Hello,
could anyone give me some hints on how to position a popup window next to a control. The control itself is on a child form of the main form.
Any answer is greatly appreciated.
Regards,
Marc
Example:
Create a project with two Forms (FORM1, FORM2). Form1 is the main form and Form2 is the popup (modal).
On Form1, create a CommandButton that when pressed will show Form2 immediately to the right edge of it.
Code for the Button BN_CLICKED event:
Function FORM1_COMMAND1_BN_CLICKED ( _
ControlIndex As Long, _ ' index in Control Array
hWndForm As Dword, _ ' handle of Form
hWndControl As Dword, _ ' handle of Control
idButtonControl As Long _ ' identifier of button
) As Long
Form2_Show hWndForm, %TRUE ' show the popup form modal
End Function
In the WM_CREATE of Form2 (the modal popup form), you will position the form. The trick is to get the screen coordinates of the CommandButton rather than the client coordinates.
Function FORM2_WM_CREATE ( _
hWndForm As Dword, _ ' handle of Form
ByVal UserData As Long _ 'optional user defined Long value
) As Long
Local rc As Rect
' Get the screen coordinates of the Command Button
GetWindowRect HWND_FORM1_COMMAND1, rc
' Position the popup form immediately to the right of the Command Button
SetWindowPos hWndForm, 0, rc.nRight, rc.nTop, 0, 0, %SWP_NOSIZE Or %SWP_SHOWWINDOW
End Function
Thank you Paul,
So easy.
Could you have done it with FF_Control_GetLoc and FF_Control_SetLoc. I know you SDK people like this but why invent FF then :)
Regards,
Marc
You could have used FF_Control_GetLoc and FF_Control_SetLoc but they use Client co-ordinates.... You would have to use MapWindowPoints to convert the values from Client to Screen in order to position the popup form correctly. GetWindowRect is just easier in this case. :)
... Also, learn SetWindowPos. It is incredibly useful and I use it all the time. It allows you to do multiple settings in just one function call making it very convenient.
Thanks Marc and Paul.
The little loop to back up to the top level form on nested forms worked. I had to make one adjustment because if you back all the way back to the top level form it returns the position relative to the desktop and then the popup form will be in the wrong place unless the top level form is positioned at 0,0.
'Calculate Offset of control from top level window
hWnd = hWndControl :'Control handle passed in to my popup function
WHILE ISTRUE (GETWINDOWLONG(hWnd, %GWL_STYLE) AND %WS_CHILD)
IF ISTRUE (GETWINDOWLONG(hWnd, %GWL_EXSTYLE) AND %WS_EX_MDICHILD) THEN EXIT LOOP
hWnd = GETPARENT(hWnd)
FF_CONTROL_GETLOC (hWnd,X,Y)
TopOff = TopOff + Y
LeftOff = LeftOff + X
WEND
'Remove last location since it is window to desktop relative position and adjustment values for exact position
'Also add some margins to make it "just right"
LeftOff = LeftOff - X + 3 :'Plus three pixels right
TopOff = TopOff - Y - 5 :'Minus five pixels up
Thanks for the help.
Maybe something like this.....
'Calculate Offset of control from top level window
hWnd = hWndControl :'Control handle passed in to my popup function
While IsTrue (GetWindowLong(hWnd, %GWL_STYLE) And %WS_CHILD)
If IsTrue (GetWindowLong(hWnd, %GWL_EXSTYLE) And %WS_EX_MDICHILD) Then Exit Loop
hWnd = GetParent(hWnd)
Wend
' Now we know that hWnd now stores the top window handle.
Local rc As Rect
' Get the screen coordinates of the control
GetWindowRect hWndControl, rc
' Get the position of the control relative to the
' top window handle.
MapWindowPoints %HWND_DESKTOP, hWnd, rc, 2
' The rect variable should now hold values for the
' control relative to the top most parent window.