- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to create one huge "window" or dialog box that has lots of questions (sort of like a questionnaire) where the user can answer the questions, scroll up, scroll down, go back and change answers, then hit an "ok" button when they're all done. I don't want a bunch of separate windows, I just want one huge window. When I create a dialog box, I haven't been able to dictate the size but I've been able to put vertical and horizontal scroll bars on my dialg box. When I run the application and make the dialog box very samll so you can't see all of the edit boxex, the scrolling does not work. Help. Thanks. Jill
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's not clear from your letter - which type of application you try to create - Dialog or Win32? For Win32 applications you must remember, that scrollbars are control elements only and no more... You must program the respective actions for these controls manually. From my side of view, your algorithm could be the next:
1.Create all necessary controls, using CreateWindow(Ex) function ( because, if your window is "huge", then you're not able to create them in Resource Editor).
2."Keep in mind" positions of all controls
3.Detect the visible group of controls
4.Programming the scrollbars actions/events, use MoveWindow function, to make the next group of controls visible/hidden.
Hope this helps,
Vladimir V.Vasilchenko
http://www.donpac.ru/usr/golub/fortran/
http://fortran-windows.tripod.com
1.Create all necessary controls, using CreateWindow(Ex) function ( because, if your window is "huge", then you're not able to create them in Resource Editor).
2."Keep in mind" positions of all controls
3.Detect the visible group of controls
4.Programming the scrollbars actions/events, use MoveWindow function, to make the next group of controls visible/hidden.
Hope this helps,
Vladimir V.Vasilchenko
http://www.donpac.ru/usr/golub/fortran/
http://fortran-windows.tripod.com
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd just add that you could consider using a tabbed dialog instead, since it should be simpler to program (and, IMHO, simpler to use). As you can see from Vladimir's post, using a huge window with scrollbar is far from trivial.
Jugoslav
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm afraid I don't have the knowlege to program scroll bars in WIN32 yet. I'll probably have to take a class. So, is there a way to create a dialog box that is 2 to 4 screens long? and that automatically handles the scroll bars? Jill
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A simpler idea than Vladimir's just struck my mind -- an approach similar to tabbed dialog boxes. I'll try to explain it in short notes.
First, create two dialogs: one "master" (
In "main" routine initialize
Then, in OnDlgInit, do DlgModeless for the child dialog:
and in OnScroll, just move the Child using MoveWindow:
As you can see, only APIs needed are GetWindowRect and MoveWindow (see docs, they're rather simple). A variation of the theme (as in your second post) is possible -- create, say, four child dialogs, do a DlgModeless for each, set scrollbar range to 1-4 and in OnScroll do a ShowWindow(SW_SHOW) for the corresponding child.
HTH
Jugoslav
First, create two dialogs: one "master" (
Dlg), containing only a scrollbar, and one huge "child" (Child) containing everything else. Child should have style "child", no caption, no border. Also, variable Child should be global somehow: MODULE Mod1 USE DFLOGM TYPE(Dialog):: Child CONTAINS...
In "main" routine initialize
Dlg. Create an initialization callback for Dlg. Also, you can initialize and fill in controls in Child there: SUBROUTINE MainDialog iSt = DlgInit(IDD_MASTER, Dlg) iSt = DlgInit(IDD_CHILD, Dlg) iSt = DlgSetSub(Dlg, IDD_MASTER, OnDlgInit) iSt = DlgSetSub(Dlg, IDD_SCROLLBAR, OnScroll) !Fill in child's contents here
Then, in OnDlgInit, do DlgModeless for the child dialog:
SUBROUTINE OnDlgInit(Dlg, ID, iEvent) USE DFWIN TYPE (T_RECT):: Rect iSt = DlgModeless(Child, SW_SHOW, Dlg%hWnd) !Find height of child and adjust scrollbar's paramters iSt = GetWindowRect(Child%hWnd, Rect) iSt = DlgSet(Dlg, IDC_SCROLLBAR, Rect%Bottom-Rect%Top, DLG_RANGEMAX) END SUBROUTINE OnDlgInit
and in OnScroll, just move the Child using MoveWindow:
SUBROUTINE OnScroll(Dlg, ID, iEvent) iSt = DlgGet(Dlg, IDC_SCROLLBAR, nPos, DLG_POSITION) iSt = GetWindowRect(Child%hWnd, Rect) iSt = MoveWindow(Child%hWnd, 0, -nPos, Rect%Right-Rect%Left, Rect%Bottom-Rect%Top)
As you can see, only APIs needed are GetWindowRect and MoveWindow (see docs, they're rather simple). A variation of the theme (as in your second post) is possible -- create, say, four child dialogs, do a DlgModeless for each, set scrollbar range to 1-4 and in OnScroll do a ShowWindow(SW_SHOW) for the corresponding child.
HTH
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Small addendum:
- Of course,
- Er, I forgot that Dlg has to be closed somehow and it has to have some "OK" and/or "Cancel" button. For the start, you could place them on the right side of Dlg. If you want them at the bottom, you'd have to carefully calculate arguments to MoveWindow(Child...) to clip the child accordingly. You could also take a look at GetClientRect()
- Of course,
DlgModal has to be in MainDialog- Er, I forgot that Dlg has to be closed somehow and it has to have some "OK" and/or "Cancel" button. For the start, you could place them on the right side of Dlg. If you want them at the bottom, you'd have to carefully calculate arguments to MoveWindow(Child...) to clip the child accordingly. You could also take a look at GetClientRect()
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav,
it seems to me, that "simpler" approach consists in using trivial scheme of any installations wizards. In practice it means - N dialog panels + using "Back","Next","Cancel" buttons + trivial external loop/block for the analysis of return code from each dialog panel... N-th panel will have "Back", "Finish", "Cancel" buttons...
Vladimir V.Vasilchenko
Fortran Programmers Club
http://www.donpac.ru/usr/golub/fortran/
http://fortran-windows.tripod.com
it seems to me, that "simpler" approach consists in using trivial scheme of any installations wizards. In practice it means - N dialog panels + using "Back","Next","Cancel" buttons + trivial external loop/block for the analysis of return code from each dialog panel... N-th panel will have "Back", "Finish", "Cancel" buttons...
Vladimir V.Vasilchenko
Fortran Programmers Club
http://www.donpac.ru/usr/golub/fortran/
http://fortran-windows.tripod.com
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sure it could; variations on the theme are indefinite. Personally, as a user, I dislike scrolling approach, since I get lost in a huge window. I'd prefer having information organized in groups somehow (tab control; a list control on the left or similar). Wizard-style you propose is also OK, but I prefer to keep it for tree-like data structures, where next screen depends on the choice in previous. I dislike wizards where info collected on each panel is totally unrelated with adjacent panels, since navigation with wizards is harder than with, say, tabs. But these are just my user's preferences.
Btw, I'd suggest a very funny but educating site related with GUI design -- Interface Hall of Shame
Btw, I'd suggest a very funny but educating site related with GUI design -- Interface Hall of Shame
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks guys for your responses. I think I'll try the tab approach and see how that works. Jill.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, i have the same problem as jschomaker. I have modified my program, but it works still not. What can I do? Thanks
integer*4 function WinMain( hInstance, hPrevInstance,
& lpszCmdLine, nCmdShow )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
!DEC$ ENDIF
!DEC$ ATTRIBUTES DLLEXPORT :: /X/
!COMMON /X/
use dfwin
use dflogm
use Mod1
implicit none
integer*4 hInstance
integer*4 hPrevInstance
integer*4 lpszCmdLine
integer*4 nCmdShow
include 'resource.fd'
external OnDialog
external OnScroll
type (T_MSG) mesg
type (T_RECT) :: Rect
type (dialog) modaldlg
type (dialog) dlg
integer*4 ret
integer*4 let
logical*4 llet
logical*4 lret
logical retlog
ghInstance = hInstance
ghModule = GetModuleHandle(NULL)
ghwndMain = NULL
llet = DlgInit (IDD_DIALOG1, modaldlg)
lret = DlgInit(IDC_MyDlg, dlg)
lret = DlgSetSub(dlg, IDC_MyDlg, OnDialog)
llet = DlgSetSub(modaldlg, IDD_DIALOG1, OnScroll)
if (lret == .FALSE.) goto 99999
do while( GetMessage (mesg, NULL, 0, 0) )
if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
lret = TranslateMessage( mesg )
ret = DispatchMessage( mesg )
end if
end do
call DlgUninit(dlg)
WinMain = mesg.wParam
return
99999 ret = MessageBox(ghwndMain, "Error initializing application
+Eingabebutton"C,"Error"C, MB_OK)
WinMain = 0
end
SUBROUTINE OnDialog(dlg, id, callbacktype)
use dfwin
use dflogm
use Mod1
implicit none
include 'resource.fd'
type (T_RECT) :: Rect
type (dialog) dlg
integer id, callbacktype
logical lret
lret = DlgModeless (Child, SW_SHOW, Dlg%hWnd)
lret = GetWindowRect (Child%hWnd, Rect)
lret = DlgSet(Dlg, IDD_DIALOG1, Rect%Bottom-Rect%Top, DLG_RANGEMAX)
if (callbacktype == dlg_destroy) then
call PostQuitMessage(0)
endif
END SUBROUTINE OnDialog
SUBROUTINE OnScroll(Dlg, ID, iEvent)
use dfwin
use dflogm
use Mod1
type (dialog) modaldlg
type (T_RECT) :: Rect
logical llet
let = DlgModal(modaldlg, hwndParent = 0)
llet = DlgSet(modaldlg, IDD_SCROLLBAR, 212, DLG_RANGE)
llet = DlgGet(modaldlg, IDD_SCROLLBAR, nPos, DLG_POSITION)
llet = GetWindowRect(Child%hWnd, Rect)
llet = MoveWindow(Child%hWnd, 0, 0, -nPos, Rect%Right-Rect%Left,
+Rect%Bottom-Rect%Top)
call DlgUninit(modaldlg)
END SUBROUTINE OnScroll
integer*4 function WinMain( hInstance, hPrevInstance,
& lpszCmdLine, nCmdShow )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
!DEC$ ENDIF
!DEC$ ATTRIBUTES DLLEXPORT :: /X/
!COMMON /X/
use dfwin
use dflogm
use Mod1
implicit none
integer*4 hInstance
integer*4 hPrevInstance
integer*4 lpszCmdLine
integer*4 nCmdShow
include 'resource.fd'
external OnDialog
external OnScroll
type (T_MSG) mesg
type (T_RECT) :: Rect
type (dialog) modaldlg
type (dialog) dlg
integer*4 ret
integer*4 let
logical*4 llet
logical*4 lret
logical retlog
ghInstance = hInstance
ghModule = GetModuleHandle(NULL)
ghwndMain = NULL
llet = DlgInit (IDD_DIALOG1, modaldlg)
lret = DlgInit(IDC_MyDlg, dlg)
lret = DlgSetSub(dlg, IDC_MyDlg, OnDialog)
llet = DlgSetSub(modaldlg, IDD_DIALOG1, OnScroll)
if (lret == .FALSE.) goto 99999
do while( GetMessage (mesg, NULL, 0, 0) )
if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
lret = TranslateMessage( mesg )
ret = DispatchMessage( mesg )
end if
end do
call DlgUninit(dlg)
WinMain = mesg.wParam
return
99999 ret = MessageBox(ghwndMain, "Error initializing application
+Eingabebutton"C,"Error"C, MB_OK)
WinMain = 0
end
SUBROUTINE OnDialog(dlg, id, callbacktype)
use dfwin
use dflogm
use Mod1
implicit none
include 'resource.fd'
type (T_RECT) :: Rect
type (dialog) dlg
integer id, callbacktype
logical lret
lret = DlgModeless (Child, SW_SHOW, Dlg%hWnd)
lret = GetWindowRect (Child%hWnd, Rect)
lret = DlgSet(Dlg, IDD_DIALOG1, Rect%Bottom-Rect%Top, DLG_RANGEMAX)
if (callbacktype == dlg_destroy) then
call PostQuitMessage(0)
endif
END SUBROUTINE OnDialog
SUBROUTINE OnScroll(Dlg, ID, iEvent)
use dfwin
use dflogm
use Mod1
type (dialog) modaldlg
type (T_RECT) :: Rect
logical llet
let = DlgModal(modaldlg, hwndParent = 0)
llet = DlgSet(modaldlg, IDD_SCROLLBAR, 212, DLG_RANGE)
llet = DlgGet(modaldlg, IDD_SCROLLBAR, nPos, DLG_POSITION)
llet = GetWindowRect(Child%hWnd, Rect)
llet = MoveWindow(Child%hWnd, 0, 0, -nPos, Rect%Right-Rect%Left,
+Rect%Bottom-Rect%Top)
call DlgUninit(modaldlg)
END SUBROUTINE OnScroll
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Uh, your code is in quite a disorder. (Both display disorder and statements disorder). You need:
I'm not sure whether it would work now (I used scissors extensively) but it's pretty close to it.
Few tips:
- In a Dialog-based application, when the main window is a modal dialog, you don't need message loop regardless of whether there are modeless children. You need message loop only when you have "standalone" modeless dialogs. In other words, having only DlgModal in WinMain is perfectly OK.
- For child dialog use "Child" and "Control" styles.
- Variable type(Dialog):: Child in the code above has to be global (say, defined in Mod1).
HTH
Jugoslav
integer*4 function WinMain( hInstance, hPrevInstance,
& lpszCmdLine, nCmdShow )
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
use dfwin
use dflogm
use Mod1
implicit none
integer*4 hInstance, hPrevInstance, lpszCmdLine, nCmdShow
include 'resource.fd'
external OnDialog
type (T_RECT) :: Rect
type (dialog) modaldlg
!type (dialog) dlg This one goes to OnDialog
integer*4 ret, let
logical*4 llet, lret, retlog
ghInstance = hInstance
ghModule = hInstance
ghwndMain = NULL
llet = DlgInit (IDD_DIALOG1, modaldlg)
lret = DlgSetSub(modaldlg, IDD_DIALOG1, OnDialog)
lret = DlgSetSub(modaldlg, IDC_SCROLLBAR1, OnScroll)
lret = DlgInit(IDC_MyDlg, dlg)
if (lret == .FALSE.) goto 99999
!You don't need this
!do while( GetMessage (mesg, NULL, 0, 0) )
! if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
! lret = TranslateMessage( mesg )
! ret = DispatchMessage( mesg )
! end if
! end do
WinMain = DlgModal(dlgModal)
return
99999 ret = MessageBox(ghwndMain, "Error initializing application
+Eingabebutton"C,"Error"C, MB_OK)
WinMain = 0
end function WinMain
!================================
SUBROUTINE OnDialog(modaldlg, id, callbacktype)
use dfwin
use dflogm
use Mod1
implicit none
include 'resource.fd'
type (T_RECT) :: Rect
type (dialog) modaldlg
integer id, callbacktype
logical lret
lret = DlgModeless (Child, SW_SHOW, ModalDlg%hWnd)
lret = GetWindowRect (Child%hWnd, Rect)
lret = DlgSet(ModalDlg, IDC_SCROLLBAR1, Rect%Bottom-Rect%Top, DLG_RANGEMAX)
END SUBROUTINE OnDialog
!================================
SUBROUTINE OnScroll(ModalDlg, ID, iEvent)
use dfwin
use dflogm
use Mod1
type (dialog) modaldlg
type (T_RECT) :: Rect
logical llet
llet = DlgGet(modaldlg, IDD_SCROLLBAR, nPos, DLG_POSITION)
llet = GetWindowRect(Child%hWnd, Rect)
llet = MoveWindow(Child%hWnd, 0, 0, -nPos, Rect%Right-Rect%Left,
+Rect%Bottom-Rect%Top)
END SUBROUTINE OnScroll I'm not sure whether it would work now (I used scissors extensively) but it's pretty close to it.
Few tips:
- In a Dialog-based application, when the main window is a modal dialog, you don't need message loop regardless of whether there are modeless children. You need message loop only when you have "standalone" modeless dialogs. In other words, having only DlgModal in WinMain is perfectly OK.
- For child dialog use "Child" and "Control" styles.
- Variable type(Dialog):: Child in the code above has to be global (say, defined in Mod1).
HTH
Jugoslav
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page