Page 1 of 1
how to get client position of a dialog control ?
Posted: Wed Nov 05, 2008 10:00 am
by eddy
Is there any differences between window controls and dialogbox controls ?
I want to code that :
hwnd_button = GetDlgItem_(...)
x=Function_GetPosX( hwnd_button )
y=Function_GetPosY( hwnd_button )
I tried to use : GetWindowRect_() & WindowToClient_() API functions.
Posted: Wed Nov 05, 2008 10:43 am
by srod
Well, dialog units only apply when defining the dialog template or using one of the 'indirect' dialog creation functions etc. Once these units have been mapped to device units and the dialog shown then we are simply dealing with good old device units.
In short, using GetClientRect_() in combination with GetDlgItem_() should work fine - providing you can execute these commands outside of the dialog's messaging loop in the case of a modal dialog. Is the dialog in question a modal one? If so where have you placed the GetDlgItem_() code?
Posted: Wed Nov 05, 2008 12:00 pm
by eddy
srod wrote:Is the dialog in question a modal one? If so where have you placed the GetDlgItem_() code?
I will customize the OpenFileRequester :
1) start a HOOK procedure
2) catch WM_INITDIALOG message
3) get control handle by using GetDlgItem_()
4) get control position by using GetWindowRect_()
5) ... customization part ...
Posted: Wed Nov 05, 2008 12:30 pm
by srod
Are you using #WH_CALLWNDPROC or #WH_CALLWNDPROCRET ?
Posted: Wed Nov 05, 2008 12:54 pm
by srod
Eddy, works fine here! I just used some code of yours with a quick test on the font requester. I even moved one of the buttons around etc.
Code: Select all
;{ SetRequesterPosition Functions
Procedure RequesterPositionCB(Window, Message, wParam, lParam)
Shared RequesterPositionX.l
Shared RequesterPositionY.l
Shared RequesterPositionCB.l
Shared RequesterPositionHook.l
Shared RequesterPositionWindow.l
Select Message
Case #WM_DESTROY
;close fake window if necessary
If RequesterPositionWindow
CloseWindow(RequesterPositionWindow)
RequesterPositionWindow=0
EndIf
;restore Requester CALLBACK
SetWindowLong_(Window, #GWL_WNDPROC, RequesterPositionCB)
Case #WM_CREATE
;update requester position ;(special case for InputRequester)
SetWindowPos_(Window, 0, RequesterPositionX, RequesterPositionY, 0, 0, #SWP_NOSIZE | #SWP_NOACTIVATE)
Case #WM_INITDIALOG
;update requester position
SetWindowPos_(Window, 0, RequesterPositionX, RequesterPositionY, 0, 0, #SWP_NOSIZE | #SWP_NOACTIVATE)
hWnd = GetDlgItem_(window, 1)
GetClientRect_(hWnd, rc.RECT)
Debug "CtrlID 1 has client coords --> (" + Str(rc\left) + ", " + Str(rc\top) + ", " + Str(rc\right) + ", " + Str(rc\bottom) + ")"
;result=CallWindowProc_(RequesterPositionCB, Window, Message, wParam, lParam)
;SetWindowPos_(Window, 0, RequesterPositionX, RequesterPositionY, 0, 0, #SWP_NOSIZE | #SWP_NOACTIVATE)
;ProcedureReturn result
EndSelect
ProcedureReturn CallWindowProc_(RequesterPositionCB, Window, Message, wParam, lParam)
EndProcedure
Procedure RequesterPositionHook(idHook, wParam, lParam)
Shared RequesterPositionX.l
Shared RequesterPositionY.l
Shared RequesterPositionCB.l
Shared RequesterPositionHook.l
Shared RequesterPositionWindow.l
Protected *RequesterPositionCWP.CWPSTRUCT=lParam
Protected Message=*RequesterPositionCWP\Message
Protected Window=*RequesterPositionCWP\hwnd
Protected Result
;(special case for InputRequester)
Protected WindowClass.s=Space(255)
GetClassName_(Window, WindowClass, 255)
If LCase(WindowClass)="inputrequester" : Message=#WM_INITDIALOG : EndIf
Select Message
Case #WM_INITDIALOG
;modify Requester callback
RequesterPositionCB=SetWindowLong_(Window, #GWL_WNDPROC, @RequesterPositionCB())
;restore parent HOOK
Result=CallNextHookEx_(RequesterPositionHook, idHook, wParam, lParam)
UnhookWindowsHookEx_(RequesterPositionHook)
RequesterPositionHook=0
Default
Result=CallNextHookEx_(RequesterPositionHook, idHook, wParam, lParam)
EndSelect
ProcedureReturn Result
EndProcedure
ProcedureDLL SetRequesterPosition(x=#PB_Ignore, y=#PB_Ignore) ; set requester position (x,y OR mouse position)
Shared RequesterPositionX.l
Shared RequesterPositionY.l
Shared RequesterPositionCB.l
Shared RequesterPositionHook.l
Shared RequesterPositionWindow.l
;use mouse position if x,y are undefined
If x=#PB_Ignore Or y=#PB_Ignore
Protected MouseCursor.POINT
GetCursorPos_(@MouseCursor)
RequesterPositionX=MouseCursor\x
RequesterPositionY=MouseCursor\y
Else
RequesterPositionX=x
RequesterPositionY=y
EndIf
;fake window if there's no parent window
Protected WindowID
If Not IsWindow(GetActiveWindow())
RequesterPositionWindow=OpenWindow(#PB_Any, x, y, 0, 0, "", #PB_Window_Invisible)
WindowID=WindowID(RequesterPositionWindow)
Else
WindowID=WindowID(GetActiveWindow())
EndIf
;modify parent HOOK
RequesterPositionHook=SetWindowsHookEx_(#WH_CALLWNDPROC, @RequesterPositionHook(), GetModuleHandle_(0), GetWindowThreadProcessId_(WindowID, 0))
EndProcedure
;}
; =========================
; EXAMPLE
; =========================
OpenWindow(1, 500, 10, 320, 20, "Ultimate Requester Position", #PB_Window_SystemMenu)
SetRequesterPosition(10, 130)
FontRequester("", 0, 0)
Delay(1000)
Note that I first used EnumChildWindows_() and GeDlgCtrlID_() to check the ctrlID's of the controls within the dialog etc. This is a good idea because the common dialogs do use some strange ID's!

Posted: Wed Nov 05, 2008 1:25 pm
by Denis
I use
Code: Select all
Parent_hdlg.l = GetParent_(hdlg)
GetDlgItem_(Parent_hdlg, #lst1)
and
Code: Select all
GetDlgItem_(Parent_hdlg, #IDCANCEL)
to get the handle of the List box that displays the contents of the current drive or folder (#lst1) and the Cancel command button (push button --> #IDCANCEL).
To get position
Code: Select all
GetWindowRect_(GetDlgItem_(Parent_hdlg, #IDCANCEL), wr1.RECT)
and i use ScreenToClient_() after that.
You will find the different contants for buttons, list etc here (at the end of the page)
http://msdn.microsoft.com/en-us/library ... S.85).aspx
Posted: Wed Nov 05, 2008 1:28 pm
by srod
Why not use GetClientRect_() ?
Posted: Wed Nov 05, 2008 1:33 pm
by Denis
I don't know

Posted: Wed Nov 05, 2008 1:34 pm
by srod
Denis wrote:I don't know


Posted: Wed Nov 05, 2008 1:36 pm
by Denis
In fact, i have written this some months ago, so i don't remember if i 've done some tests with GetClientRect_().
I take me some time to write this correctly. :roll:
Posted: Wed Nov 05, 2008 9:23 pm
by eddy
Ah... I forgot to catch resizing events.
That's why all my calculations are messed up.
Posted: Wed Nov 05, 2008 9:49 pm
by eddy
Alter #WM_WINDOWPOSCHANGING, the dialog control size is not updated! It's weird
Code: Select all
GetClientRect_(GetDlgItem_(window, #lst1), @rc.RECT)
h=rc\bottom
Debug h