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! :wink:

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 :D

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

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. :shock:
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