amin84 Posted August 29, 2019 Share Posted August 29, 2019 (edited) Hello, I'm trying to write a simple program that will resize the active window to 800x600 for example but when I measure the dimensions of the resized window, it's slightly off (14px on X and 7px on Y in Windows 10). Also position of 0 on X is 7 pixels off. So to move a window to top left and resize it to 800x600 in Windows 10, I have to do this instead: $hWnd = WinGetTitle ('') WinMove($hWnd, '', -7, 0, 800+14, 600+7) Is there any way to set window size to exactly 800x600 dimensions? Thanks. Edited September 12, 2019 by leomoon Link to comment Share on other sites More sharing options...
Bilgus Posted August 29, 2019 Share Posted August 29, 2019 does this show somewhere close to 14? #include <MsgBoxConstants.au3> Example() Func Example() ; Run Notepad Run("notepad.exe") ; Wait 10 seconds for the Notepad window to appear. Local $hWnd = WinWaitActive("[CLASS:Notepad]", "", 10) ; Retrieve the client area of the Notepad window using the handle returned by WinWait. Local $aClientSize = WinGetClientSize($hWnd) Local $aPos = WinGetPos($hWnd) ; Display the height and width of the client area. MsgBox($MB_SYSTEMMODAL, "", "Width: " & $aPos[2] - $aClientSize[0] & @CRLF & "Height: " & $aPos[3] - $aClientSize[1]) ; Close the Notepad window using the handle returned by WinWait. WinClose($hWnd) EndFunc ;==>Example Link to comment Share on other sites More sharing options...
Bilgus Posted August 29, 2019 Share Posted August 29, 2019 Ah here we go.. Link to comment Share on other sites More sharing options...
amin84 Posted August 29, 2019 Author Share Posted August 29, 2019 Thanks for the replies. None of them worked properly. The first one shows 16 for X and 59 for Y. The second is way off. Just to be clear, what I mean by resizing is to set the whole window to what ever dimension. This includes the title bar thickness (which can change with themes or DPI) and the small thickness around the windows. So far I haven't been able to find a good solution. Link to comment Share on other sites More sharing options...
Bilgus Posted August 29, 2019 Share Posted August 29, 2019 (edited) hmm sorry I figured you were seeing the client area being less than 800x600 i'm sure the underlying function for winmove is the same windows api function but have you tried .. #include <WinAPI.au3> _WinAPI_MoveWindow ( $hWnd, $iX, $iY, $iWidth, $iHeight [, $bRepaint = True] ) or maybe its dpi scaling causing an issue #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_HiDpi=Y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** If @OsType="WIN_10" Then DllCall("Shcore.dll","long","PROCESS_DPI_AWARENESS",1) Else DllCall("User32.dll","bool","SetProcessDPIAware") EndIf ;hResult is 32bit Edited August 29, 2019 by Bilgus Link to comment Share on other sites More sharing options...
amin84 Posted September 2, 2019 Author Share Posted September 2, 2019 (edited) Here is a very simple test app. Run this, then open an Explorer window and press Ctrl + Alt + T. This will resize the window to 800x600 and take a screen shot of that window and save it on your desktop as "resize.jpg". The dimensions of that JPG should be 800x600 but it is 786x593 for some reason (ESC will exit the script)! I tried so many things but nothing worked! #include <WinAPISysWin.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <ScreenCapture.au3> HotKeySet("{ESC}", "_exit") HotKeySet("^!t", "_resize") Global $hWnd While 1 Sleep(100) WEnd Func _resize() $hWnd = WinGetHandle("[active]") $pos = WinGetPos($hWnd) WinMove($hWnd, '', $pos[0], $pos[1], 800, 600) ;~ _WinSetClientPos($hWnd, "", 800, 600, $pos[0], $pos[1]) ;~ _WinAPI_MoveWindow($hWnd, $pos[0], $pos[1], 800, 600) ;~ _WinAPI_SetWindowPos($hWnd, $HWND_NOTOPMOST, $pos[0], $pos[1], 800, 600, $SWP_NOMOVE) Sleep(500) _ScreenCapture_CaptureWnd(@DesktopDir&'\resize.jpg', $hWnd) EndFunc Func _exit() Exit EndFunc Even DllCall does not resize it properly!!! DllCall("User32.dll", "int", "MoveWindow", "hwnd", $hWnd, "int", $pos[0], "int", $pos[1], "int", 800, "int", 600, "bool", False) Edited September 2, 2019 by leomoon Link to comment Share on other sites More sharing options...
Bilgus Posted September 2, 2019 Share Posted September 2, 2019 if you do $pos = WinGetPos($hWnd) ConsoleWrite($pos[0] & @crlf & $pos[1] & @crlf &$pos[2] & @crlf &$pos[3] & @crlf) Does it show 800 x 600 there? Maybe its actually the capture function? #include <WinAPISysWin.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <ScreenCapture.au3> HotKeySet("{ESC}", "_exit") HotKeySet("^!t", "_resize") Global $hWnd While 1 Sleep(100) WEnd Func _resize() $hWnd = WinGetHandle("[active]") $pos = WinGetPos($hWnd) WinMove($hWnd, '', Default, Default, 800, 600) ;~ _WinSetClientPos($hWnd, "", 800, 600, $pos[0], $pos[1]) ;~ _WinAPI_MoveWindow($hWnd, $pos[0], $pos[1], 800, 600) ;~ _WinAPI_SetWindowPos($hWnd, $HWND_NOTOPMOST, $pos[0], $pos[1], 800, 600, $SWP_NOMOVE) Sleep(500) _ScreenCapture_CaptureWnd(@DesktopDir&'\resize.jpg', $hWnd, Default, Default, 800, 600) EndFunc Func _exit() Exit EndFunc What about explicitly setting the size for the capture does it leave blank space? Link to comment Share on other sites More sharing options...
amin84 Posted September 3, 2019 Author Share Posted September 3, 2019 (edited) I don't know what to do anymore! It resizes properly on only a few applications. The rest are 14 pixels short on x and 7 pixels short on y. Applications that resize properly are: VSCode, Telegram, Photoshop, Applications that do not resize properly are: Windows Explorer, AutoIt SciTE, FileZilla, Audacity, QT Designer, Notepad++, Chrome, Blender, Python IDLE Here is a video demo:https://www.youtube.com/watch?v=0p2qcD_RlrQ And here is the script: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_Res_Language=1033 #AutoIt3Wrapper_Add_Constants=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;~ #NoTrayIcon #RequireAdmin #pragma compile(Icon, resources\main.ico) #pragma compile(UPX, False) #pragma compile(x64, False) #pragma compile(Compression, 9) #pragma compile(FileVersion, 1.0.0.0) #pragma compile(ProductVersion, 1.0.0.0) #include <FileConstants.au3> #include <GUIConstantsEx.au3> #include <Constants.au3> #include <StaticConstants.au3> #include <Misc.au3> #include <resources\ExtMsgBox.au3> #include <ScreenCapture.au3> $title = 'Demo App' $ver = '1.0' AutoItWinSetTitle($title) Opt('TrayMenuMode',3) Opt('TrayAutoPause',0) Opt("GUICloseOnESC", 0) Global Const $WM_USER = 0x0400 Global Const $MY_WM_NOTIFYICON = $WM_USER + 1 Global Const $WM_LBUTTONDOWN = 0x0201 Global $hWnd $resizeTray = TrayCreateItem("Active window: Resize to 800x600") TrayCreateItem("") $exitTray = TrayCreateItem('Exit') TraySetState() HotKeySet("^!t", "ShowTrayMenu") While 1 $Msg = TrayGetMsg() Switch $Msg Case $exitTray Exit Case $TRAY_EVENT_PRIMARYDOWN, $TRAY_EVENT_PRIMARYUP, $TRAY_EVENT_SECONDARYDOWN, $TRAY_EVENT_SECONDARYUP _dMenu() Case $resizeTray _resize($hWnd, 800, 600) EndSwitch WEnd Exit Func _dMenu() TrayItemSetState($resizeTray,$TRAY_DISABLE) EndFunc Func _eMenu() TrayItemSetState($resizeTray,$TRAY_ENABLE) EndFunc Func ShowTrayMenu() $hWnd = WinGetHandle("") ;get handle for active window _eMenu() DllCall("user32.dll", "int", "SendMessage", "hwnd", WinGetHandle($title), "int", $MY_WM_NOTIFYICON, "int", 0, "int", $WM_LBUTTONDOWN) ;show menu with hotkey EndFunc Func _resize($hWnd, $w, $h) WinMove($hWnd, '', Default, Default, $w, $h) $pos = WinGetPos($hWnd) ConsoleWrite('resized '&$hWnd&', x='&$pos[0]&', y='&$pos[1]&', width='&$pos[2]&', height='&$pos[3]&@LF) WinActivate($hWnd) EndFunc I have also tested this in a Windows 10 VM and the results are the same! UPDATE: This works properly on all applications in Windows 7! Anybody knows how we can fix this in Windows 10? Edited September 3, 2019 by leomoon Link to comment Share on other sites More sharing options...
amin84 Posted September 4, 2019 Author Share Posted September 4, 2019 (edited) I wrote this using Python 3 and the results were the same in Windows 10. import win32gui hwnd = win32gui.FindWindow(None, 'Untitled - Notepad') x0, y0, x1, y1 = win32gui.GetWindowRect(hwnd) win32gui.MoveWindow(hwnd, x0, y0, 800, 600, True) In Windows 7, WinGetPos and WinGetClientSize return same height and width and this problem doesn't exist in Windows 7. But in Windows 10, WinGetClientSize height is 14 pixels shorter than WinGetPos height and WinGetClinetSize width is 7 pixels shorter than WinGetPos width. This script below will fix this problem in Windows 10 while still working fine in Windows 7 and 8. Func _resize($x, $y) $hWnd = WinGetHandle("[ACTIVE]") ;get handle of active window WinSetState($hWnd, '', @SW_RESTORE) ;some windows will retrun wrong width and height if maximized $wpos = WinGetPos($hWnd) $csiz = WinGetClientSize($hWnd) If @OSVersion == 'WIN_10' Then If $csiz[0] <> $wpos[2] And @OSVersion == 'WIN_10' Then $xf = 14 $yf = 7 Else $xf = 0 $yf = 0 EndIf Else $xf = 0 $yf = 0 EndIf WinMove($hWnd, '', Default, Default, $w+$xf, $h+$yf) EndFunc And this is how to use it. _resize(800,600) I also tested this in Windows 10 with different DPI and it works. @Bilgus, thanks for helping me with this. Edited September 12, 2019 by leomoon improved code Bilgus 1 Link to comment Share on other sites More sharing options...
sgwilliams Posted July 25, 2020 Share Posted July 25, 2020 @amin84, This is a nice piece of code but when I run the, following script I get an error(see the attached screenshot). Func _resize($x, $y) $hWnd = WinGetHandle("[ACTIVE]") ;get handle of active window WinSetState($hWnd, '', @SW_RESTORE) ;some windows will retrun wrong width and height if maximized $wpos = WinGetPos($hWnd) $csiz = WinGetClientSize($hWnd) If @OSVersion == 'WIN_10' Then If $csiz[0] <> $wpos[2] And @OSVersion == 'WIN_10' Then $xf = 14 $yf = 7 Else $xf = 0 $yf = 0 EndIf Else $xf = 0 $yf = 0 EndIf WinMove($hWnd, '', Default, Default, $w+$xf, $h+$yf,10) EndFunc ; Run Filemaker Startup script. Local $fm $fm = "C:\AutoIT\Files\AdminStart.fmp12" ShellExecute($fm) Sleep(5000) WinClose("Quotation (FMSERVER15)") While WinExists("ProductPlanner (FMSERVER15)") _resize(800,600) WinMove("ProductPlanner (FMSERVER15)","", 0,-2160,10) WinSetState("ProductPlanner (FMSERVER15)","",@SW_MAXIMIZE) WEnd The following variables in your code are not declared anywhere that I can find: $xf, $xy, $w, $h. Link to comment Share on other sites More sharing options...
Dan_555 Posted July 25, 2020 Share Posted July 25, 2020 (edited) Hmm, @sgwilliams if you look at the post # 8, the resize function shows: Quote Func _resize($hWnd, $w, $h) while your post displays Quote Func _resize($x, $y) looking on the line 18, i see $w and $h, which are, now, not being used: Quote WinMove($hWnd, '', Default, Default, $w+$xf, $h+$yf,10) Try replacing $w with $x, and $h with $y. or change the function to Func _resize($w, $h) Edited July 25, 2020 by Dan_555 Some of my script sourcecode Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now