Software Archive
Read-only legacy content
Announcements
Important Update: Community Platform Migration​. Learn more​>
17060 Discussions

dialog location

myron_r
Beginner
2,376 Views
I would like to know how to determine the location of a dialog box. I have tried using GetWindowRect but I haven't been able to get it to work. My project has an opengl window as well and the GetWindowRect works for that window. Why doesn't it work for the dialog window? The following is a couple lines of code that I tried using.

type(t_RECT) rect
retint = DlgModal( dlg )
ignor = GetWindowRect(dlg%hwnd,rect)

What I would like to do is get the position of the dialog box and then pass that to iposition and jposition of SetWindowPos.

retlog = SetWindowPos( dlg % hwnd, HWND_TOP, &
iposition, jposition, 130,450, ior(SWP_NOZORDER, SWP_NOACTIVATE))

Thanks
Myron McKenzie
0 Kudos
6 Replies
Jugoslav_Dujic
Valued Contributor II
2,376 Views
There's the following rule of thumb:

Any Windows API function related with handle of dialog or a control will work only in a callback function (registered via DlgSetSub)

The reason for that is simple: dialog window exists only during call to DlgModal; before it it's not made yet; after that it's destroyed. Thus, the dlg%hwnd is a valid handle only while the dialog is displayed.

To make GetWindowRect work, you must call it in a callback function. A common trick is to define a callback function for the dialog itself; this one will be called immediately on dialog start, i.e. right after DlgModal:

 
EXTERNAL OnDlgInit 
 
iSt = DlgSetSub (Dlg, IDD_DIALOG1, OnDlgInit) 
... 
SUBROUTINE OnDlgInit(Dlg, ID, iEvent) 
!TODO call your initialization APIs here (GetWindowRect, SetWindowPos, 
SetWindowText, SendMessage etc.) 
END SUBROUTINE OnDlgInit 


HTH

Jugoslav
0 Kudos
myron_r
Beginner
2,376 Views
Thanks Jugoslav for the help. I tried what you suggested and when I used GetWindowRect I got the dimensions of the dialog box (x,y coordinates of the lower right corner of dialog box) but the location of the upper left corner was always (0,0). Any ideas why I don't get an updated location. Here is the code I used.

recursive subroutine DoDialog( dlg, id, callbacktype ) !called from main program
use dflogm
use dfwin
implicit none
type (dialog) dlg
integer id
integer callbacktype
include 'whizzy.fd'
integer*4 ret,iSt
logical*4 lret
logical retlog,retlog2
integer retint,ignor
external PositionDlg
if ( .not. DlgInit( idd_whizzy, dlg ) ) then
write (*,*) "error: resource not found"
else
retlog=DlgSetSub(dlg,IDD_WHIZZY,PositionDlg)
retint = DlgModal( dlg )
call DlgUninit( dlg )
end if
end subroutine DoDialog

subroutine PositionDlg( dlg, id, callbacktype )
use dflogm
use user32
use VarGlob
use dfopngl
implicit none
type (dialog) dlg
type(t_RECT) rect
integer id
integer callbacktype
include 'whizzy.fd'
logical retlog
retlog = GetWindowRect(dlg%hwnd,rect)
iposition=rect%left
jposition=rect%top
write(155,*)rect
retlog = SetWindowPos( dlg % hwnd, HWND_TOP, &
iposition, jposition, 130,450, ior(SWP_NOZORDER, SWP_NOACTIVATE))
end subroutine

Thanks for your help
Myron
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,376 Views
GetWindowRect (appears to) work. Your code is mostly correct. Now, you didn't state type of your project (QuickWin or Win32). That's the behaviour I'd expect for Win32 application with X and Y in dialog's property sheet set to 0. Uh, I guess I'll have to add couple of remarks:

1) There's a thing called dialog's owner window; the coordinates you enter in resource editor are relative to owner window's origin (but are expressed in some odd units). DlgModal calls GetHWNDQQ(QWIN$FRAMEWINDOW) to pass the owner to Win32 DialogBox function; with Win32, GetHWNDQQ fails and returns 0, meaning that the owner window is desktop, so your dialog is displayed at the screen origin, which gives you expected Rect=(0,0,Width,Height).

You may take a look at my "touched" version of DFLOGM which allows you to specify owner window as an optional argument to DlgModal.


2) Are you aware of DS_CENTER dialog style? That's the one I almost always use (it's "Center" checkbox on "More styles" dialog's tab). This style always centers the dialog on the screen.


3) You need not call GetWindowPos. Just add flag SWP_NOMOVE to SetWindowPos to adjust only size of the window. You can set iposition and jposition to 0 then, since they're ignored.


Regards

Jugoslav
0 Kudos
myron_r
Beginner
2,376 Views
Jugoslav

This is a Win32 project. In my application I use the dialog box to control action that occurs on an opengl window. For my application opening the dialog in the center would not be good. But thanks for the suggestion. I don't know enough about dialogs to understand your suggestion about specifying the owner window as an optional argument to DlgModal. I have included DFLOGM.lib and XFLOGM.f90 to my project. The compiler didn't like <> so I changed them to .NE. Can you explain how I should proceed?

Myron
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,376 Views
Well, where you want your dialog exactly to be? You don't necessarily have to use XFLOGM for that. Let's assume that in resource editor X and
Y for the dialog are set to 0, "Center" is off, and hgWindow is (global) handle of your OpenGL window. With XFLOGM, you can use:

 
iRet=DlgModal(Dlg, hgWindow) 


and then, the dialog will show up in upper left corner of hgWindow.
With DFLOGM, you have to move the dialog manually:

 
iSt=DlgSetSub(...OnDlgInit) 
iRet=DlgModal(Dlg) 


and in callback function:

 
SUBROUTINE OnDlgInit(Dlg, ID, iEvent) 
... 
iSt=GetWindowRect(hgWindow, Rect) 
iSt=SetWindowPos(Dlg%hWnd, 0, Rect%Left, Rect%Top, 0, 0, & 
      SWP_NOZORDER.OR.SWP_NOSIZE) 


Now, you can play with dialog's position. For example, the following snippet
would place dialog "on top" of hgWindow, simultaneously widening it so that it's width is identical with width of hgWindow:

 
SUBROUTINE OnDlgInit(Dlg, ID, iEvent) 
... 
iSt=GetWindowRect(hgWindow, Rect) 
iSt=GetWindowRect(Dlg%hWnd, Rect2) 
 
iSt=SetWindowPos(Dlg%hWnd, 0,                   & 
              Rect%Left,                 & 
              Rect%Top-(Rect2%Bottom-Rect2%Top),  & 
              Rect%Right-Rect%Left,    & 
              Rect2%Bottom-Rect2%Top, & 
              SWP_NOZORDER) 


AFAIK owner window affects only initial position of the dialog (and that position can be overriden as above).

As for <>s, it's not my fault :-). That's a nonstandard extension that survived up to CVF 6.5 days and then deleted (standard gives /=). but it's used in parts of XFLOGM written by Microsoft and Compaq people. Thanks, I'll fix it.

Regards

Jugoslav
0 Kudos
Steven_L_Intel1
Employee
2,376 Views
<> is not Fortran syntax. Use /= instead. Earlier versions of the compiler accepted it by mistake - we fixed that in 6.5.

Steve
0 Kudos
Reply