Jump to content

[SOLVED] Resizing Active Window Problem


 Share

Recommended Posts

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

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

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

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

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

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

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:

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

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 by leomoon
improved code
Link to comment
Share on other sites

  • 10 months later...

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

error.png

Link to comment
Share on other sites

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 by Dan_555

Some of my script sourcecode

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