Opened 11 years ago
Closed 11 years ago
#2368 closed Bug (No Bug)
Inconsistent GUICreate results
Reported by: | vlad@… | Owned by: | |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | 3.3.8.1 | Severity: | None |
Keywords: | Cc: |
Description
GUICreate produces a window with sizes dependent on the style used.
I am attaching two files: a demo script and the script's output. While I'm sure there are reasons behind this (maybe even Win API "philosophy"), I think a user not well versed in GUI tweaking might expect a consistent behavior (as WinMove offers - see the example).
Attachments (2)
Change History (10)
Changed 11 years ago by vlad@…
comment:1 follow-up: ↓ 2 Changed 11 years ago by FireFox
No, it's not a bug. Depending on the window' style, you will have to add the borders.
See below:
I changed the window' style of the Test2 because it's simpler (otherwise other metrics are needed that I don't bother to search).
#include <WindowsConstants.au3> #include <WinAPI.au3> #include <Constants.au3> Local $iBorderSize = _WinAPI_GetSystemMetrics($SM_CXDLGFRAME) Local $iCaptionSize = _WinAPI_GetSystemMetrics($SM_CYCAPTION) Local $hGUI = 0, $aClientSize = 0, $aPos = 0, $sDebugNotes = "" $sDebugNotes = "Window with DEFAULT (-1) Style:" & @CRLF #region Test1 $hGUI = GUICreate("Demo Window", 640, 480) $aClientSize = WinGetClientSize($hGUI) $sDebugNotes &= " GUICreate [640x480]: WinGetClientSize returns " & $aClientSize[0] & "x" & $aClientSize[1] & "," $sDebugNotes &= " width borders: " & $aClientSize[0] + ($iBorderSize * 2) & "x" & $aClientSize[1] + ($iCaptionSize + $iBorderSize * 2) & "," $aPos = WinGetPos($hGUI) $sDebugNotes &= " WinGetPos returns " & $aPos[2] & "x" & $aPos[3] & @CRLF ;the winmove function will resize the window's client area, you need to add the borders WinMove($hGUI, "", Default, Default, 640 + ($iBorderSize * 2), 480 + ($iCaptionSize + $iBorderSize * 2)) $aClientSize = WinGetClientSize($hGUI) $sDebugNotes &= " WinMove [640x480]: WinGetClientSize returns " & $aClientSize[0] & "x" & $aClientSize[1] & "," $sDebugNotes &= " width borders: " & $aClientSize[0] + ($iBorderSize * 2) & "x" & $aClientSize[1] + ($iCaptionSize + $iBorderSize * 2) & "," $aPos = WinGetPos($hGUI) $sDebugNotes &= " WinGetPos returns " & $aPos[2] & "x" & $aPos[3] & @CRLF GUIDelete($hGUI) #endregion #region Test2 $sDebugNotes &= @CRLF & "Window with DEFAULT+$WS_SIZEBOX Style:" & @CRLF Global Const $SM_CXSIZEFRAME = 32 $iBorderSize = _WinAPI_GetSystemMetrics($SM_CXSIZEFRAME) ;~ $hGUI = GUICreate("Demo Window", 640, 480, -1, -1, BitOR($WS_SIZEBOX, $WS_SYSMENU)) $hGUI = GUICreate("Demo Window", 640, 480, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX)) $aClientSize = WinGetClientSize($hGUI) $sDebugNotes &= " GUICreate [640x480]: WinGetClientSize returns " & $aClientSize[0] & "x" & $aClientSize[1] & "," $sDebugNotes &= " width borders: " & $aClientSize[0] + ($iBorderSize * 2) & "x" & $aClientSize[1] + ($iCaptionSize + $iBorderSize * 2) & "," $aPos = WinGetPos($hGUI) $sDebugNotes &= " WinGetPos returns " & $aPos[2] & "x" & $aPos[3] & @CRLF WinMove($hGUI, "", Default, Default, 640, 480) $aClientSize = WinGetClientSize($hGUI) $sDebugNotes &= " WinMove [640x480]: WinGetClientSize returns " & $aClientSize[0] & "x" & $aClientSize[1] & "," $sDebugNotes &= " width borders: " & $aClientSize[0] + ($iBorderSize * 2) & "x" & $aClientSize[1] + ($iCaptionSize + $iBorderSize * 2) & "," $aPos = WinGetPos($hGUI) $sDebugNotes &= " WinGetPos returns " & $aPos[2] & "x" & $aPos[3] & @CRLF ConsoleWrite($sDebugNotes) #endregion
comment:2 in reply to: ↑ 1 Changed 11 years ago by vlad@…
I have done something quite similar in my project, but this wasn't quite my point...
WinMove behaves consistently: you tell it to do a 640x480, 640x480 it is, no matter what style the window is (of course, the size of the "client area" will be affected by the thickness of the borders).
GUICreate, on the other hand, creates a window with a mostly random size: you tell it 640x480 and in most cases you get a window that has neither the "outer box" nor the "client area" of 640x480 ... it just happens that for the "default style" the outer box is 640x480.
I believe the implementation of GUICreate should offer some "certitude", in the sense that either the outer or the inner dimensions of the created window should be the ones specified by the calling arguments. It's just a matter of consistency ... Of course, this wouldn't change the fact that most programs will have to figure out the other dimensions so the GUI arrangement matches the intended design.
Anyhow, in my view this issue would fall somewhere between annoyance and minor bug. But as most of the AutoIT features are quite neat and clean, I thought it made sense letting you guys know about it.
comment:3 follow-up: ↓ 4 Changed 11 years ago by FireFox
huh, it's the same with Visual Express Form builder.
If you change the FormBorderStyle, it resizes the Form in order to keep the same client area which is IMO quite logic.
And so does autoit.
comment:4 in reply to: ↑ 3 Changed 11 years ago by vlad@…
Keeping the client area constant would be OK as well, but it just doesn't happen in AutoIT (see the BugDemo1.txt file that I've attached originally) - everything changes ...
Replying to FireFox:
huh, it's the same with Visual Express Form builder.
If you change the FormBorderStyle, it resizes the Form in order to keep the same client area which is IMO quite logic.
And so does autoit.
comment:5 Changed 11 years ago by FireFox
I don't see why the internal function of GUICreate would contain superfluous code to create a wrong window size.
I tried with the CreateWindowEx function, it gives different results with some styles but the client area does not correspond either to the size initially set.
comment:6 Changed 11 years ago by Mat
The correct solution is using the AdjustWindowRectEx function. This wrapper around GUICreate should always create a window with the correct client size.
Func _GUICreate($sTitle, $w, $h, $x = -1, $y = -1, $iStyle = -1, $iExStyle = -1, $hParent = 0) Local Const $iDefStyle = BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU) Local Const $iDefExStyle = $WS_EX_WINDOWEDGE If $iStyle = -1 Then $iStyle = $iDefStyle If $iExStyle = -1 Then $iExStyle = $iDefExStyle Local $rect = DllStructCreate($tagRECT) DllStructSetData($rect, "left", $x) DllStructSetData($rect, "right", $x + $w) DllStructSetData($rect, "top", $y) DllStructSetData($rect, "bottom", $y + $h) _WinAPI_AdjustWindowRectEx($rect, $iStyle, $iExStyle, False) $w = DllStructGetData($rect, "right") - DllStructGetData($rect, "left") $h = DllStructGetData($rect, "bottom") - DllStructGetData($rect, "top") If $x = -1 Then $x = (@DesktopWidth - $w) / 2 Else $x = DllStructGetData($rect, "left") EndIf If $y = -1 Then $y = (@DesktopHeight - $h) / 2 Else $y = DllStructGetData($rect, "top") EndIf Local $hRet = GUICreate($sTitle, $w, $h, $x, $y, $iStyle, $iExStyle, $hParent) WinMove($hRet, "", $x, $y, $w, $h) Return $hRet EndFunc ;==>_GUICreate
AdjustWindowRectEx has a note about not being able to specify the WS_OVERLAPPED style. I'll have to test what that actually means.
comment:7 Changed 11 years ago by Mat
Full code that works for all the styles I've tested can be found here: http://www.autoitscript.com/forum/topic/154224-winsetclientpos/
Don't think this will be changed in the AutoIt core as a lot of existing scripts probably rely on their windows being the same size.
comment:8 Changed 11 years ago by Jpm
- Resolution set to No Bug
- Status changed from new to closed
In fact there is no bug as GUICreate defined the Windows Size not the Client Size
@Mat suggestion is a good suggestion if you want to manage with Client size
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Demo Script