Jump to content

window restored position without actually restoring


Recommended Posts

How can I get a window's "restored" coordinates (X, Y , width & height) without actually restoring it from a minimized or maximized state? I have a situation where a window is maximized (or minimized) and I need to know where the OS is going to put the window in the restored state before it actually happens.

Link to comment
Share on other sites

How can I get a window's "restored" coordinates (X, Y , width & height) without actually restoring it from a minimized or maximized state? I have a situation where a window is maximized (or minimized) and I need to know where the OS is going to put the window in the restored state before it actually happens.

Restore it hidden, get the pos, then put it back minimized and unhidden.

:)

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
Link to comment
Share on other sites

OK, you can't leave me hang'n! How do you make that work? I create a DLL struct and make the DLL call, and it almost works, but I don't understand how you get a struct out of a struct.

The GetWindowPlacement call uses a WINDOWPLACEMENT struct, which I don't know how to create because I don't know how to put "POINT" and "RECT" types in it (though they are available as $tag_ variables in WinAPI.au3).

This works...

#include <WinAPI.au3>

Run("notepad.exe", @TempDir, @SW_MINIMIZE)
WinWait("Untitled - Notepad")
$hWindow = WinGetHandle("Untitled - Notepad")
_WinAPI_GetWindowPlacement($hWindow)

Func _WinAPI_GetWindowPlacement($hWND)
    Local $strPointMinPosition = DllStructCreate($tagPOINT); "int X;int Y"
    Local $ptrPointMinPosition = DllStructGetPtr($strPointMinPosition)
    
    Local $strPointMaxPosition = DllStructCreate($tagPOINT); "int X;int Y"
    Local $ptrPointMaxPosition = DllStructGetPtr($strPointMaxPosition)
    
    Local $strRECT = DllStructCreate($tagRECT); "int Left;int Top;int Right;int Bottom"
    Local $ptrRECT = DllStructGetPtr($strRECT)
    
    Local $strWindowPlacement = DllStructCreate("UINT length; UINT flags; UINT showCmd; " & _
        "PTR ptMinPosition; PTR ptMaxPosition; PTR rcNormalPosition")
    Local $ptrWindowPlacement = DllStructGetPtr($strWindowPlacement)    
    
    $avRET = DllCall("user32.dll", "int", "GetWindowPlacement", "hwnd", $hWND, "ptr", $ptrWindowPlacement)
    If $avRET[0] <> 0 Then
        $sMsg = "DLL call succeded: $avRET[0] = " & $avRET[0] & @CRLF & @CRLF
        $sMsg &= "$strWindowPlacement:" & @CRLF
        $sMsg &= @TAB & "length = " & DllStructGetData($strWindowPlacement, "length") & @CRLF
        $sMsg &= @TAB & "flags = " & DllStructGetData($strWindowPlacement, "flags") & @CRLF
        $sMsg &= @TAB & "showCmd = " & DllStructGetData($strWindowPlacement, "showCmd") & @CRLF
        MsgBox(64, "Success", $sMsg)        
    Else
        MsgBox(16, "Failed", "Dll call failed: $avRET[0] = " & $avRET[0])
    EndIf
EndFunc
...but it stops short of reading out the "POINT" and "RECT" values.

How do you do that?

:)

Edit: Fixed broken link.

Edited by PsaltyDS
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
Link to comment
Share on other sites

$tagWINDOWPLACEMENT = "uint sizeof;uint flags;uint showCmd;int MinPos[2];int MaxPos[2];int NormPos[4]"

or

$tagWINDOWPLACEMENT = "uint sizeof;uint flags;uint showCmd;int MinPosX;int MinPosY;int MaxPosX;int MaxPosY;int NormPosX1;int NormPosY1;int NormPosX2;int NormPosY2"

Whichever you prefer.

"be smart, drink your wine"

Link to comment
Share on other sites

$tagWINDOWPLACEMENT = "uint sizeof;uint flags;uint showCmd;int MinPos[2];int MaxPos[2];int NormPos[4]"

or

$tagWINDOWPLACEMENT = "uint sizeof;uint flags;uint showCmd;int MinPosX;int MinPosY;int MaxPosX;int MaxPosY;int NormPosX1;int NormPosY1;int NormPosX2;int NormPosY2"

Whichever you prefer.

The first one worked! (The second caused the Dll call to fail.) This is a start:
#include <WinAPI.au3>

Run("notepad.exe", @TempDir, @SW_MINIMIZE)
WinWait("Untitled - Notepad")
$hWindow = WinGetHandle("Untitled - Notepad")
_WinAPI_GetWindowPlacement($hWindow)
WinClose($hWindow)

Func _WinAPI_GetWindowPlacement($hWND)
    Local $strWindowPlacement = DllStructCreate("UINT length; UINT flags; UINT showCmd; " & _
        "int MinPos[2]; int MaxPos[2]; int NormPos[4]")
    
    Local $ptrWindowPlacement = DllStructGetPtr($strWindowPlacement)    
    
    $avRET = DllCall("user32.dll", "int", "GetWindowPlacement", "hwnd", $hWND, "ptr", $ptrWindowPlacement)
    If $avRET[0] <> 0 Then
        $sMsg = "DLL call succeded: $avRET[0] = " & $avRET[0] & @CRLF & @CRLF
        $sMsg &= "$strWindowPlacement:" & @CRLF
        $sMsg &= @TAB & "length = " & DllStructGetData($strWindowPlacement, "length") & @CRLF
        $sMsg &= @TAB & "flags = " & DllStructGetData($strWindowPlacement, "flags") & @CRLF
        $sMsg &= @TAB & "showCmd = " & DllStructGetData($strWindowPlacement, "showCmd") & @CRLF
        $sMsg &= "PointMinPosition:" & @CRLF
        $sMsg &= @TAB & "MinX = " & DllStructGetData($strWindowPlacement, "MinPos", 1) & @CRLF
        $sMsg &= @TAB & "MinY = " & DllStructGetData($strWindowPlacement, "MinPos", 2) & @CRLF
        $sMsg &= "PointMaxPosition:" & @CRLF
        $sMsg &= @TAB & "MaxX = " & DllStructGetData($strWindowPlacement, "MaxPos", 1) & @CRLF
        $sMsg &= @TAB & "MaxY = " & DllStructGetData($strWindowPlacement, "MaxPos", 2) & @CRLF
        $sMsg &= "RectNormPosition:" & @CRLF
        $sMsg &= @TAB & "left = " & DllStructGetData($strWindowPlacement, "NormPos", 1) & @CRLF
        $sMsg &= @TAB & "top = " & DllStructGetData($strWindowPlacement, "NormPos", 2) & @CRLF
        $sMsg &= @TAB & "right = " & DllStructGetData($strWindowPlacement, "NormPos", 3) & @CRLF
        $sMsg &= @TAB & "bottom = " & DllStructGetData($strWindowPlacement, "NormPos", 4)
        MsgBox(64, "Success", $sMsg)        
    Else
        MsgBox(16, "Failed", "Dll call failed: $avRET[0] = " & $avRET[0])
    EndIf
EndFunc

I can normalize the return data from the function instead of a MsgBox(), and we have a working call! Thanks, Siao!

:)

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
Link to comment
Share on other sites

  • Moderators

Eek, guess I could have saved some time and refreshed this page... I just sent you a PM on it salty .. Siao has a great grasp on api calls (as well as many other things) :)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Here is the new function, _WinAPI_GetWindowPlacement(), built based on Siao's and SmOke_N's help:

#include <WinAPI.au3>

; Get the normal position of a minimized window
Run("notepad.exe", @TempDir, @SW_MINIMIZE)
WinWait("Untitled - Notepad")
$hWindow = WinGetHandle("Untitled - Notepad")
$strRET = _WinAPI_GetWindowPlacement($hWindow)

$sMsg = "$strWindowPlacement:" & @CRLF & @CRLF
$sMsg &= @TAB & "length = " & DllStructGetData($strRET, "length") & @CRLF
$sMsg &= @TAB & "flags = " & DllStructGetData($strRET, "flags") & @CRLF
$sMsg &= @TAB & "showCmd = " & DllStructGetData($strRET, "showCmd") & @CRLF & @CRLF
$sMsg &= "ptMinPosition:" & @CRLF
$sMsg &= @TAB & "MinX = " & DllStructGetData($strRET, "ptMinPosition", 1) & @CRLF
$sMsg &= @TAB & "MinY = " & DllStructGetData($strRET, "ptMinPosition", 2) & @CRLF & @CRLF
$sMsg &= "ptMaxPosition:" & @CRLF
$sMsg &= @TAB & "MaxX = " & DllStructGetData($strRET, "ptMaxPosition", 1) & @CRLF
$sMsg &= @TAB & "MaxY = " & DllStructGetData($strRET, "ptMaxPosition", 2) & @CRLF & @CRLF
$sMsg &= "rcNormalPosition:" & @CRLF
$sMsg &= @TAB & "left = " & DllStructGetData($strRET, "rcNormalPosition", 1) & @CRLF
$sMsg &= @TAB & "top = " & DllStructGetData($strRET, "rcNormalPosition", 2) & @CRLF
$sMsg &= @TAB & "right = " & DllStructGetData($strRET, "rcNormalPosition", 3) & @CRLF
$sMsg &= @TAB & "bottom = " & DllStructGetData($strRET, "rcNormalPosition", 4)
MsgBox(64, "Success", $sMsg)

WinClose($hWindow)

; #FUNCTION# =============================================================
; Name...........: _WinAPI_GetWindowPlacement
; Description ...: Retrieves the placement of the window, which includes Min, Max, and normal (even if minimized) positions
; Syntax.........: _WinAPI_GetWindowPlacement($hWnd)
; Parameters ....: $hWnd        - Handle of the window
; Return values .: Success    - $tagWindowPlacement structure that receives the placement coordinates:
; Author ........: PsaltyDS, with help from Siao and SmOke_N, at www.autoitscript.com/forum
; Modified.......:
; Remarks .......: See MSDN for WINDOWPLACEMENT, POINT, and RECT structures combined into $tagWindowPlacement in this function.
;           $tagWindowPlacement = "
;               UINT length;  size of struct
;               UINT flags;  sum of WPF_ASYNCWINDOWPLACEMENT, WPF_RESTORETOMAXIMIZED, and WPF_SETMINPOSITION
;               UINT showCmd;  show state, i.e. SW_Show or SW_Minimize
;               int ptMinPosition[2];  X/Y of upper left corner when minimized
;               int ptMaxPosition[2];  X/Y coord of upper left corner when maximized
;               int rcNormalPosition[4]"  left/top/right/bottom coord when normalized
; Related .......: $tagWindowPlacement
; Link ..........; @@MsdnLink@@ GetWindowPlacement
; Example .......;
; =======================================================================
Func _WinAPI_GetWindowPlacement($hWnd)
    Local $tagWindowPlacement = "UINT length; UINT flags; UINT showCmd; " & _
            "int ptMinPosition[2]; int ptMaxPosition[2]; int rcNormalPosition[4]"
    Local $strWindowPlacement = DllStructCreate($tagWindowPlacement)
    DllStructSetData($strWindowPlacement, "length", DllStructGetSize($strWindowPlacement))
    Local $ptrWindowPlacement = DllStructGetPtr($strWindowPlacement)
    
    $avRET = DllCall("user32.dll", "int", "GetWindowPlacement", "hwnd", $hWnd, "ptr", $ptrWindowPlacement)
    Return $strWindowPlacement
EndFunc;==>_WinAPI_GetWindowPlacement

I feel like I learned something today!

:)

Edit: Fixed line-wrapped header on function for SmOke_N. Picky, picky, picky...

P.S. Posted _WinAPI_GetWindowPlacement() to the example forum. If it needs any more changes, they will be posted there. Hopefully it will soon be joined there by _WinAPI_SetWindowPlacement().

:)

Edited by PsaltyDS
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
Link to comment
Share on other sites

  • Moderators

Yeah, I learned a few things myself... you might want to watch that word wrap on your function headers.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...