Jump to content

GetWindowRect - wrong values on Vista/WIN7


Zedna
 Share

Recommended Posts

According to MSDN remark from here:

http://msdn.microsoft.com/en-us/library/ms633519%28VS.85%29.aspx

GetWindowRect Function

Doesn't return exactly what you'd expect on Vista with Aero Glass

Per this MSDN thread:

http://social.msdn.microsoft.com/Forums/...ad/6c1c67a9-5548-4e9b-989f-c7dbac0b1375/

Apps under Vista that are not linked with WINVER=6 will receive a misleading set of values here, that do not account for the extra padding of "glass" pixels Vista Aero applies to the window. This appears to happen even in Aero Basic (without Glass) to retain sizing consistency. The workaround (if you don't want to set WINVER=6) seems to be to dynamically bind to dwmapi.dll and use GetProcAddress() to obtain the DwmGetWindowAttribute() function, and call it with the DWMWA_EXTENDED_FRAME_BOUNDS argument to request the genuine window frame dimensions.

This article:

http://shellrevealed.com/blogs/shellblog...s-about-the-Aero-Basic-window-frame.aspx

explains the anatomy of the window frame dimensions under Vista (though it only diagrams the Aero Basic anatomy, not the full Aero Glass layout).

I don't have Vista/WIN7 anywhere to test it but if it's true I think there will be more similar API functions affected.

I think this kind of possible issues/problems/bugs could be mentioned in remarks in Autoit's helpfile for Vista/WIN7 support.

Edited by Zedna
Link to comment
Share on other sites

  • 3 weeks later...

Fighting Aero I found this article. Thanks for the Research Zedna! I dug a little deeper into it. With Aero enabled WinGetPos() returns wrong results. Correct results can be obtained with a dllcall to the dwmapi.dll function DwmGetWindowAttribute. Heavly commented (and dirty) example code below ;)...

$hGui = GUICreate("My GUI")
GUISetState(@SW_SHOW)

$aPos = WinGetPos($hGui)
$sPos = $aPos[0] & "," & $aPos[1] & @TAB & $aPos[2] & "x" & $aPos[3]
ConsoleWrite("Aero On" & @crlf)
ConsoleWrite("WinGetPos(): " & $sPos & @CRLF)

Toggle_AERO_Style_On(True)

Sleep(1000)

$aPos = WinGetPos($hGui)
$sPos = $aPos[0] & "," & $aPos[1] & @TAB & $aPos[2] & "x" & $aPos[3]
ConsoleWrite("Aero On" & @crlf)
ConsoleWrite("WinGetPos(): " & $sPos & @CRLF)

Toggle_AERO_Style_On(False)

Sleep(1000)

; DwmGetWindowAttribute Function
; http://msdn.microsoft.com/en-us/library/aa969515%28VS.85%29.aspx
; Referring to the reference for the DWMWINDOWATTRIBUTE enum:
; http://msdn.microsoft.com/en-us/library/aa969530(VS.85).aspx

#cs
    HRESULT DwmGetWindowAttribute(
    HWND hwnd,
    DWORD dwAttribute,
    PVOID pvAttribute,
    DWORD cbAttribute
    );

    public const uint DWMWA_NCRENDERING_ENABLED = 1;           // [get] Is non-client rendering enabled/disabled
    public const uint DWMWA_NCRENDERING_POLICY = 2;            // [set] Non-client rendering policy
    public const uint DWMWA_TRANSITIONS_FORCEDISABLED = 3;     // [set] Potentially enable/forcibly disable transitions
    public const uint DWMWA_ALLOW_NCPAINT = 4;                 // [set] Allow contents rendered in the non-client area to be visible on the DWM-drawn frame.
    public const uint DWMWA_CAPTION_BUTTON_BOUNDS = 5;         // [get] Bounds of the caption button area in window-relative space.
    public const uint DWMWA_NONCLIENT_RTL_LAYOUT = 6;          // [set] Is non-client content RTL mirrored
    public const uint DWMWA_FORCE_ICONIC_REPRESENTATION = 7;   // [set] Force this window to display iconic thumbnails.
    public const uint DWMWA_FLIP3D_POLICY = 8;                 // [set] Designates how Flip3D will treat the window.
    public const uint DWMWA_EXTENDED_FRAME_BOUNDS = 9;         // [get] Gets the extended frame bounds rectangle in screen space
    public const uint DWMWA_LAST = 10;

    public const uint DWMNCRP_USEWINDOWSTYLE = 0;
    public const uint DWMNCRP_DISABLED = 1;
    public const uint DWMNCRP_ENABLED = 2;
    public const uint DWMNCRP_LAST = 3;
#ce

Const $DWMWA_EXTENDED_FRAME_BOUNDS = 9

$tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
DllCall("dwmapi.dll", "hwnd", "DwmGetWindowAttribute", "hwnd", WinGetHandle($hGui), "dword", $DWMWA_EXTENDED_FRAME_BOUNDS, "ptr", DllStructGetPtr($tRect),"dword",DllStructGetSize($tRect))

$sPos = DllStructGetData($tRect,"Left") & "," & DllStructGetData($tRect,"Top") & @TAB & DllStructGetData($tRect,"Right") - DllStructGetData($tRect,"Left") & "x" & DllStructGetData($tRect,"Bottom") - DllStructGetData($tRect,"Top")
ConsoleWrite("Aero On" & @crlf)
ConsoleWrite("DwmGetWindowAttribute: " & $sPos & @CRLF)

Toggle_AERO_Style_On(True)

$tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
DllCall("dwmapi.dll", "hwnd", "DwmGetWindowAttribute", "hwnd", WinGetHandle($hGui), "dword", $DWMWA_EXTENDED_FRAME_BOUNDS, "ptr", DllStructGetPtr($tRect),"dword",DllStructGetSize($tRect))

$sPos = DllStructGetData($tRect,"Left") & "," & DllStructGetData($tRect,"Top") & @TAB & DllStructGetData($tRect,"Right") - DllStructGetData($tRect,"Left") & "x" & DllStructGetData($tRect,"Bottom") - DllStructGetData($tRect,"Top")
ConsoleWrite("Aero Off" & @crlf)
ConsoleWrite("DwmGetWindowAttribute: " & $sPos & @CRLF)

GUIDelete()
ConsoleWrite(@CRLF)
Exit


Func Toggle_AERO_Style_On($toggle = True)
    ; Disable AERO effect on Vista and Win7 => MPlayer requires this
    ; http://msdn.microsoft.com/en-us/library/aa969510%28VS.85%29.aspx
    Local Const $DWM_EC_DISABLECOMPOSITION = 0
    Local Const $DWM_EC_ENABLECOMPOSITION = 1
    If $toggle = True Then
        DllCall("dwmapi.dll", "hwnd", "DwmEnableComposition", "uint", $DWM_EC_DISABLECOMPOSITION)
    Else
        DllCall("dwmapi.dll", "hwnd", "DwmEnableComposition", "uint", $DWM_EC_ENABLECOMPOSITION)
    EndIf
EndFunc   ;==>Toggle_AERO_Style_On
Edited by KaFu
Link to comment
Share on other sites

Hmmm, looking at this, what do you think of the function WinGetPosEx()? Will this lead to problems on XP?

Edit #1: At least in my VM XP it runs fine...

Edit #2: Pimped the example a little more...

Edit #3: Moved posting to examples ;)...

Edited by KaFu
Link to comment
Share on other sites

Fighting Aero I found this article. Thanks for the Research Zedna! I dug a little deeper into it. With Aero enabled WinGetPos() returns wrong results. Correct results can be obtained with a dllcall to the dwmapi.dll function DwmGetWindowAttribute. Heavly commented (and dirty) example code below ;)...

If you can confirm/invoke this on WIN7 then please make BUG report/ticket on TRAC.

I have no access to WIN Vista/WIN7.

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