Jump to content



Photo

Client Position


  • Please log in to reply
7 replies to this topic

#1 Jex

Jex

    Polymath

  • Active Members
  • PipPipPipPip
  • 206 posts

Posted 30 November 2007 - 04:24 AM

How can i find client position? That question looking easy but i can't find solution..
WinGetPos giving window position and i can't add + pixel for find client position because have menu and if im use another Windows skin that client position will be not true.
ControlGetPos giving window relative coordinate and that mean X=0 Y=0
I need WinGetClientPos :P
I'm tried AutoItSetOptions too but still can't find Window Client pos..
I need find client position for my Image Editor.

Edit : I'm found GetClientRect Function ( http://msdn2.microsoft.com/en-us/library/ms633503.aspx )

Edited by Jex, 30 November 2007 - 04:45 AM.








#2 Fossil Rock

Fossil Rock

    ASCII a stupid question,… get a stupid ANSI.

  • Active Members
  • PipPipPipPipPipPip
  • 1,084 posts

Posted 30 November 2007 - 05:05 AM

I'm not sure if this will help but look into Opt("MouseCoordMode", 2).

Sets the way coords are used in the mouse functions, either absolute coords or coords relative to the current active window:
0 = relative coords to the active window
1 = absolute screen coordinates (default)
2 = relative coords to the client area of the active window

Agreement is not necessary - thinking for one's self is!

Posted Image

Posted Image


#3 Jex

Jex

    Polymath

  • Active Members
  • PipPipPipPip
  • 206 posts

Posted 30 November 2007 - 05:06 AM

Func WinGetClientPos($Handle)     $hwnd = WinGetHandle($Handle)     $cPos = DllStructCreate("long;long;long;long")     DllCall("user32.dll", "int", "GetClientRect", "hwnd", $hwnd, "ptr", DllStructGetPtr($cPos))     Dim $cPos2[4] = [DllStructGetData($cPos, 1), DllStructGetData($cPos, 2), DllStructGetData($cPos, 3), DllStructGetData($cPos, 4)]     Return $cPos2 EndFunc


Giving client relative coordinate ;)
Buffy opts not help.

Edit : Now im see Autoit have that function ( _WinAPI_GetClientRect )
Edit2 : I'm said Buffy but your nick Fossil Rock :P ?!

Edited by Jex, 30 November 2007 - 07:42 PM.


#4 PsaltyDS

PsaltyDS

    Most Venerable Penguin

  • MVPs
  • 13,279 posts

Posted 30 November 2007 - 01:07 PM

Another way to do that UDF, just for fun:
AutoIt         
#include <array.au3> $PID = Run("Notepad.exe") WinWait("Untitled - Notepad") $hNotepad = WinGetHandle("Untitled - Notepad") $avResult = _WinGetClientPos($hNotepad) _ArrayDisplay($avResult, "Client Pos (Relative)") $avResult = _WinGetClientPos($hNotepad, 1) _ArrayDisplay($avResult, "Client Pos (Absolute)") ProcessClose($PID) ; Returns X/Y coord of client are, absolute to the desktop if $fAbsolute <> 0 Func _WinGetClientPos($hWin, $fAbsolute = 0)     If Not WinActivate($hWin) Then Return SetError(1, 0, 0)         Local $cPos = DllStructCreate("long;long;long;long")     DllCall("user32.dll", "int", "GetClientRect", "hwnd", $hWin, "ptr", DllStructGetPtr($cPos))     Local $cPos2[4] = [DllStructGetData($cPos, 1), DllStructGetData($cPos, 2), DllStructGetData($cPos, 3), DllStructGetData($cPos, 4)]         If $fAbsolute Then         WinActivate($hWin)         WinWaitActive($hWin)         Local $MousePosSav = MouseGetPos()         Local $MouseModeSav = Opt("MouseCoordMode", 2)         MouseMove(0, 0, 0)         Opt("MouseCoordMode", 1)         Local $avRET = MouseGetPos()         Opt("MouseCoordMode", $MouseModeSav)         MouseMove($MousePosSav[0], $MousePosSav[1], 0)         $cPos2[0] = $avRET[0]         $cPos2[1] = $avRET[1]         $cPos2[2] = $avRET[0] + $cPos2[2]         $cPos2[3] = $avRET[1] + $cPos2[3]     EndIf         Return $cPos2 EndFunc   ;==>_WinGetClientPos


:P

Edited by PsaltyDS, 30 November 2007 - 01:10 PM.

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

#5 Jex

Jex

    Polymath

  • Active Members
  • PipPipPipPip
  • 206 posts

Posted 01 December 2007 - 02:47 AM

PsaltyDS very thanks that method working but have problems.

            $Timer = TimerInit()             $Position = _WinGetClientPos(WinGetHandle($GUI), 1)             MsgBox("", "", Round(TimerDiff($Timer), 0) & "ms")


+1000ms
and i can't loop that function because moving mouse every loop.
I need find better way for get client position :)

Edited by Jex, 01 December 2007 - 04:34 AM.


#6 PsaltyDS

PsaltyDS

    Most Venerable Penguin

  • MVPs
  • 13,279 posts

Posted 01 December 2007 - 04:25 PM

[quote name='Jex' post='441306' date='Nov 30 2007, 09:47 PM']PsaltyDS very thanks that method working but have problems.

AutoIt         
            $Timer = TimerInit()             $Position = _WinGetClientPos(WinGetHandle($GUI), 1)             MsgBox("", "", Round(TimerDiff($Timer), 0) & "ms")ƒo݊÷ ÛítÓI¬jwbq©÷öÙh¢›aj×îËb¢vÞq«¬zj/Šx&¢ëz÷«ÊZ(¤‰Þy×âÖ޶׫Á¬Ÿ¢¸µÉbz{i¢È­Š‰ÿªê-x‹b™çl¢g¨~Ø^¥ªí±©Ý~‹§v+pjËaz·ªº*ޙéí¶‡§²êÞ¶«z«¢­çpŠwhìiËb½ëajÛh¢F¥–Ø^)žN¬½ê슉åy«Þ²ØZ¶êm¢Ø^^™©"ž ayÆ¥•©Ý­êe‰ë"Ÿi¢–X¬yÊ+•ë,jëhŠ×6#include <array.au3> $PID = Run("Notepad.exe") WinWait("Untitled - Notepad") $hNotepad = WinGetHandle("Untitled - Notepad") WinActivate($hNotepad) WinWaitActive($hNotepad) $iTimer = TimerInit() $avResult = _WinGetClientPos() ; Relative _ArrayDisplay($avResult, "Client Pos (Relative) in " & Round(TimerDiff($iTimer) / 1000, 3) & "secs") Sleep(2000) $iTimer = TimerInit() $avResult = _WinGetClientPos(1) ; Absolute (to desktop) _ArrayDisplay($avResult, "Client Pos (Absolute) in " & Round(TimerDiff($iTimer) / 1000, 3) & "secs") ProcessClose($PID) ; Returns X/Y coord of client area of the active window; absolute to the desktop if $fAbsolute <> 0 Func _WinGetClientPos($fAbsolute = 0)     Local $cPos = DllStructCreate("long;long;long;long"), $hWin = WinGetHandle("")     DllCall("user32.dll", "int", "GetClientRect", "hwnd", $hWin, "ptr", DllStructGetPtr($cPos))     Local $cPos2[4] = [DllStructGetData($cPos, 1), DllStructGetData($cPos, 2), DllStructGetData($cPos, 3), DllStructGetData($cPos, 4)]         If $fAbsolute Then         Local $MousePosSav = MouseGetPos()         Local $MouseModeSav = Opt("MouseCoordMode", 2)         MouseMove(0, 0, 0)         Opt("MouseCoordMode", 1)         Local $avRET = MouseGetPos()         Opt("MouseCoordMode", $MouseModeSav)         MouseMove($MousePosSav[0], $MousePosSav[1], 0)         $cPos2[0] = $avRET[0]         $cPos2[1] = $avRET[1]         $cPos2[2] = $avRET[0] + $cPos2[2]         $cPos2[3] = $avRET[1] + $cPos2[3]     EndIf     Return $cPos2 EndFunc   ;==>_WinGetClientPos

I can't help you with the mouse movement. The fuction moves the mouse exactly twice, at speed = 0 (instantaneous), and puts the both the mouse mode and mouse pos where they were before it started. This all happens too fast to see on my computer.

:)
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

#7 Jex

Jex

    Polymath

  • Active Members
  • PipPipPipPip
  • 206 posts

Posted 02 December 2007 - 12:22 AM

Very thanks now working instantly :)

I'm changed code and now find client coordinate and size in 0ms ( _WinGetClientPos find in 1 or 2 ms ^_^ ) and not need move mouse.
Just in startup use that "Global $Client = _WinGetClientPos(1)" ( I mean after created GUI ) and later use "GetClientPos("Title")"
I think that method can find coordinates 100% true, if Windows Skin not changed but i'm not sure.

AutoIt         
#include <Array.au3> $tNotepad = "Untitled - Notepad" $PID = Run("Notepad.exe") WinWait($tNotepad) $hNotepad = WinGetHandle($tNotepad) WinActivate($hNotepad) WinWaitActive($hNotepad) Global $Client = _WinGetClientPos(1) $iTimer = TimerInit() $ClientPos = GetClientPos($tNotepad) _ArrayDisplay($ClientPos, "Client position and size found in " & Round(TimerDiff($iTimer), 0) & "ms") ProcessClose($PID) Func GetClientPos($wTitle = "")     Local $cPos[6]     $wPos = WinGetPos($wTitle)     $cPos[0] = $wPos[0] + $Client[0]     $cPos[1] = $wPos[1] + $Client[1]     $cPos[2] = ($wPos[0] + $wPos[2]) - $Client[2]     $cPos[3] = ($wPos[1] + $wPos[3]) - $Client[3]     $cPos[4] = $cPos[2] - $cPos[0]     $cPos[5] = $cPos[3] - $cPos[1]     Return $cPos EndFunc   ;==>GetClientPos Func _WinGetClientPos($fAbsolute = 0)     Local $cPos = DllStructCreate("long;long;long;long"), $hWin = WinGetHandle("")     DllCall("user32.dll", "int", "GetClientRect", "hwnd", $hWin, "ptr", DllStructGetPtr($cPos))     Local $cPos2[4] = [DllStructGetData($cPos, 1), DllStructGetData($cPos, 2), DllStructGetData($cPos, 3), DllStructGetData($cPos, 4)]     If $fAbsolute Then         Local $MousePosSav = MouseGetPos()         Local $MouseModeSav = Opt("MouseCoordMode", 2)         MouseMove(0, 0, 0)         Opt("MouseCoordMode", 1)         Local $avRET = MouseGetPos()         Opt("MouseCoordMode", $MouseModeSav)         MouseMove($MousePosSav[0], $MousePosSav[1], 0)         $wPos = WinGetPos("")         $cPos2[0] = $avRET[0] - $wPos[0]         $cPos2[1] = $avRET[1] - $wPos[1]         $cPos2[2] = ($wPos[0] + $wPos[2]) - ($avRET[0] + $cPos2[2])         $cPos2[3] = ($wPos[1] + $wPos[3]) - ($avRET[1] + $cPos2[3])     EndIf     Return $cPos2 EndFunc   ;==>_WinGetClientPos

Edited by Jex, 02 December 2007 - 02:58 AM.


#8 elloco

elloco

    Seeker

  • New Members
  • 1 posts

Posted 23 July 2009 - 08:57 AM

Use the _WinAPI_ClientToScreen($hWnd, ByRef $tPoint)
and _WinAPI_ScreenToClient($hWnd, ByRef $tPoint) functions to get the position of the client area.

Have a look at the help file to use the functions.

Easy and no hacks required via positioning of the mouse...

Edited by elloco, 23 July 2009 - 08:58 AM.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users