PsaltyDS Posted June 6, 2008 Share Posted June 6, 2008 (edited) With some help understanding the DLL struct required from Siao and SmOke_N, I coded _WinAPI_GetWindowPlacement() in this topic: window restored position without actually restoringThe primary advantage to this method is getting where the window will go, vice where it is. For example determining where the window will restore to, while it remains minimized.I am considering putting it in for consideration as an addition to WinAPI.au3 UDF, but need more people to try it first. Here's the function, with a demo: <snip>Also, I guess we need the matching _WinAPI_SetWindowPlacement() to go with it. I will take a look at that too.Comments requested... Edit: Reformatted for submission to UDF, including both _WinAPI_GetWindowPlacement() and _WinAPI_SetWindowPlacement():Here are the functions, to be included in WinAPI.au3: expandcollapse popup; #FUNCTION# ==================================================================================== ; ; Name...........: _WinAPI_GetWindowPlacement ; Description ...: Retrieves the placement of the window for Min, Max, and normal positions ; Syntax.........: _WinAPI_GetWindowPlacement($hWnd) ; Parameters ....: $hWnd - Handle of the window ; Return values .: Success - returns $tagWINDOWPLACEMENT structure with the placement coordinates ; Failure - returns 0, @error = 1, @extended = _WinAPI_GetLastError() ; Author ........: PsaltyDS, with help from Siao and SmOke_N, at www.autoitscript.com/forum ; Modified.......: ; Remarks .......: ; Related .......: _WinAPI_SetWindowPlacement, $tagWINDOWPLACEMENT ; Link ..........; @@MsdnLink@@ GetWindowPlacement ; Example .......; Yes ; ; ============================================================================================= Func _WinAPI_GetWindowPlacement($hWnd) ; Create struct to receive data Local $tWindowPlacement = DllStructCreate($tagWINDOWPLACEMENT) DllStructSetData($tWindowPlacement, "length", DllStructGetSize($tWindowPlacement)) ; Get pointer to struct Local $pWindowPlacement = DllStructGetPtr($tWindowPlacement) ; Make DLL call Local $avRET = DllCall("user32.dll", "int", "GetWindowPlacement", "hwnd", $hWnd, "ptr", $pWindowPlacement) ; Return results If $avRET[0] Then Return $tWindowPlacement Else Return SetError(1, _WinAPI_GetLastError(), 0) EndIf EndFunc ;==>_WinAPI_GetWindowPlacement ; #FUNCTION# ===================================================================================== ; ; Name...........: _WinAPI_SetWindowPlacement ; Description ...: Sets the placement of the window for Min, Max, and normal positions ; Syntax.........: _WinAPI_SetWindowPlacement($hWnd, $pWindowPlacement) ; Parameters ....: $hWnd - Handle of the window ; $pWindowPlacement - pointer to $tagWINDOWPLACEMENT structure ; Return values .: Success - Returns non-zero ; Failure - Returns 0, @error = 1, @extended = _WinAPI_GetLastError() ; Author ........: PsaltyDS at www.autoitscript.com/forum ; Modified.......: ; Remarks .......: ; Related .......: _WinAPI_GetWindowPlacement, $tagWINDOWPLACEMENT ; Link ..........; @@MsdnLink@@ SetWindowPlacement ; Example .......; Yes ; ; =============================================================================================== Func _WinAPI_SetWindowPlacement($hWnd, $pWindowPlacement) ; Make DLL call Local $avRET = DllCall("user32.dll", "int", "SetWindowPlacement", "hwnd", $hWnd, "ptr", $pWindowPlacement) ; Return results If $avRET[0] Then Return $avRET[0] Else Return SetError(1, _WinAPI_GetLastError(), 0) EndIf EndFunc ;==>_WinAPI_SetWindowPlacement...and here is the demo, which includes the required $tagWINDOWPLACEMENT definition: expandcollapse popup; _WinAPI_GetWindowPlacement.au3 and _WinAPI_SetWindowPlacement.au3 #AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 ; Placed here only until included in appropriate Constants include file: ; ------------------------------------------------------------------------------ ; $tagWINDOWPLACEMENT ; ----------------------------------- ; This structure defines the data for User32.dll functions GetWindowPlacement and SetWindowPlacement. ; Includes the X/Y coord of the window when minimized and maximized, and the rectangle coord when ; normalized. ; Parameters: ; length = size of struct ; flags = sum of WPF_ASYNCWINDOWPLACEMENT, WPF_RESTORETOMAXIMIZED, and WPF_SETMINPOSITION ; showCmd = show state, i.e. SW_Show or SW_Minimize ; ptMinPosition = X/Y coord of upper left corner when minimized ; ptMaxPosition = X/Y coord of upper left corner when maximized ; rcNormalPosition = left/top/right/bottom coord when normalized ; ------------------------------------------------------------------------------ Global Const $tagWINDOWPLACEMENT = "UINT length; UINT flags; UINT showCmd; " & _ "int ptMinPosition[2]; int ptMaxPosition[2]; int rcNormalPosition[4]" #include <WinAPI.au3> Global $hWindow, $stRET, $sMsg, $pStruct, $iRET ; Create an instance of notepad to play with Run("notepad.exe") WinWait("Untitled - Notepad") $hWindow = WinGetHandle("Untitled - Notepad") WinMove($hWindow, "", 256, 256, 400, 400) Sleep(1000) ; Minimize and then check the placement values returned by _WinAPI_GetWindowPlacement() WinSetState($hWindow, "", @SW_MINIMIZE) $stRET = _WinAPI_GetWindowPlacement($hWindow) If @error = 0 Then $sMsg = "$stWindowPlacement:" & @CRLF & @CRLF $sMsg &= @TAB & "length = " & DllStructGetData($stRET, "length") & @CRLF $sMsg &= @TAB & "flags = " & DllStructGetData($stRET, "flags") & @CRLF $sMsg &= @TAB & "showCmd = " & DllStructGetData($stRET, "showCmd") & @CRLF & @CRLF $sMsg &= "ptMinPosition:" & @CRLF $sMsg &= @TAB & "MinX = " & DllStructGetData($stRET, "ptMinPosition", 1) & @CRLF $sMsg &= @TAB & "MinY = " & DllStructGetData($stRET, "ptMinPosition", 2) & @CRLF & @CRLF $sMsg &= "ptMaxPosition:" & @CRLF $sMsg &= @TAB & "MaxX = " & DllStructGetData($stRET, "ptMaxPosition", 1) & @CRLF $sMsg &= @TAB & "MaxY = " & DllStructGetData($stRET, "ptMaxPosition", 2) & @CRLF & @CRLF $sMsg &= "rcNormalPosition:" & @CRLF $sMsg &= @TAB & "left = " & DllStructGetData($stRET, "rcNormalPosition", 1) & @CRLF $sMsg &= @TAB & "top = " & DllStructGetData($stRET, "rcNormalPosition", 2) & @CRLF $sMsg &= @TAB & "right = " & DllStructGetData($stRET, "rcNormalPosition", 3) & @CRLF $sMsg &= @TAB & "bottom = " & DllStructGetData($stRET, "rcNormalPosition", 4) MsgBox(64, "Success", $sMsg) ; Change the normalized rectangle with _WinAPI_SetWindowPlacement() and then restore DllStructSetData($stRET, "rcNormalPosition", 128, 1); left DllStructSetData($stRET, "rcNormalPosition", 128, 2); top DllStructSetData($stRET, "rcNormalPosition", @DesktopWidth - 128, 3); right DllStructSetData($stRET, "rcNormalPosition", @DesktopHeight - 128, 4); bottom $pStruct = DllStructGetPtr($stRET); Get pointer to the modified struct $iRET = _WinAPI_SetWindowPlacement($hWindow, $pStruct) If @error = 0 Then WinSetState($hWindow, "", @SW_RESTORE) ControlSetText($hWindow, "", "Edit1", "_WinAPI_SetWindowPlacement() succeeded!") Else MsgBox(16, "Error", "_WinAPI_SetWindowPlacement() failed!" & @CRLF & _ "$iRET = " & $iRET & @CRLF & _ "@error = " & @error & @CRLF & _ "@extended = " & @extended) EndIf Else MsgBox(16, "Error", "_WinAPI_GetWindowPlacement() failed!" & @CRLF & _ "$stRET = " & $stRET & @CRLF & _ "@error = " & @error & @CRLF & _ "@extended = " & @extended) EndIf Edited June 18, 2008 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 More sharing options...
Andreik Posted June 6, 2008 Share Posted June 6, 2008 (edited) Very useful function. I will add this function in WinAPI.au3 UDF. Thanks PsaltyDS. Edited June 6, 2008 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 6, 2008 Author Share Posted June 6, 2008 Very useful function. I will add this function in WinAPI.au3 UDF.Thanks PsaltyDS. You're welcome, but monitor for changes. As I look into _WinAPI_SetWindowPlacement(), I see a major change possible. That the $tagWINDOWPLACEMENT should be declared Global Const, rather than local to the function. The _WinAPI_GetWindowPlacement() function will return the structure, and the Set version will take the structure as an input parameter. So the tag should be global to be used in both cases for setting/reading data. 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 More sharing options...
PsaltyDS Posted June 6, 2008 Author Share Posted June 6, 2008 (edited) Here are _WinAPI_GetWindowPlacement() and _WinAPI_SetWindowPlacement() cleaned up per the UDF Standards, with a demo script. Note the new Global Const variable, which is declared in the demo but would presumably be included in the WinAPI.au3 UDF if these functions are accepted. I also added some error detection: expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include <WinAPI.au3> ; ------------------------------------------------------------------------------ ; Placed here until included in WinAPI.au3: ; ; $tagWINDOWPLACEMENT ; ----------------------------------- ; This structure defines the data for User32.dll functions GetWindowPlacement and SetWindowPlacement. ; Includes the X/Y coord of the window when minimized and maximized, and the rectangle coord when ; normalized. ; Parameters: ; length = size of struct ; flags = sum of WPF_ASYNCWINDOWPLACEMENT, WPF_RESTORETOMAXIMIZED, and WPF_SETMINPOSITION ; showCmd = show state, i.e. SW_Show or SW_Minimize ; ptMinPosition = X/Y coord of upper left corner when minimized ; ptMaxPosition = X/Y coord of upper left corner when maximized ; rcNormalPosition = left/top/right/bottom coord when normalized ; ------------------------------------------------------------------------------ Global Const $tagWINDOWPLACEMENT = "UINT length; UINT flags; UINT showCmd; " & _ "int ptMinPosition[2]; int ptMaxPosition[2]; int rcNormalPosition[4]" ; #Demo Script# ==================================================================================== Global $hWindow, $stRET, $sMsg, $pStruct, $iRET ; Create an instance of notepad to play with Run("notepad.exe") WinWait("Untitled - Notepad") $hWindow = WinGetHandle("Untitled - Notepad") WinMove($hWindow, "", 256, 256, 400, 400) Sleep(1000) ; Minimize and then check the placement values returned by _WinAPI_GetWindowPlacement() WinSetState($hWindow, "", @SW_MINIMIZE) $stRET = _WinAPI_GetWindowPlacement($hWindow) If @error = 0 Then $sMsg = "$stWindowPlacement:" & @CRLF & @CRLF $sMsg &= @TAB & "length = " & DllStructGetData($stRET, "length") & @CRLF $sMsg &= @TAB & "flags = " & DllStructGetData($stRET, "flags") & @CRLF $sMsg &= @TAB & "showCmd = " & DllStructGetData($stRET, "showCmd") & @CRLF & @CRLF $sMsg &= "ptMinPosition:" & @CRLF $sMsg &= @TAB & "MinX = " & DllStructGetData($stRET, "ptMinPosition", 1) & @CRLF $sMsg &= @TAB & "MinY = " & DllStructGetData($stRET, "ptMinPosition", 2) & @CRLF & @CRLF $sMsg &= "ptMaxPosition:" & @CRLF $sMsg &= @TAB & "MaxX = " & DllStructGetData($stRET, "ptMaxPosition", 1) & @CRLF $sMsg &= @TAB & "MaxY = " & DllStructGetData($stRET, "ptMaxPosition", 2) & @CRLF & @CRLF $sMsg &= "rcNormalPosition:" & @CRLF $sMsg &= @TAB & "left = " & DllStructGetData($stRET, "rcNormalPosition", 1) & @CRLF $sMsg &= @TAB & "top = " & DllStructGetData($stRET, "rcNormalPosition", 2) & @CRLF $sMsg &= @TAB & "right = " & DllStructGetData($stRET, "rcNormalPosition", 3) & @CRLF $sMsg &= @TAB & "bottom = " & DllStructGetData($stRET, "rcNormalPosition", 4) MsgBox(64, "Success", $sMsg) ; Change the normalized rectangle with _WinAPI_SetWindowPlacement() and then restore DllStructSetData($stRET, "rcNormalPosition", 128, 1); left DllStructSetData($stRET, "rcNormalPosition", 128, 2); top DllStructSetData($stRET, "rcNormalPosition", @DesktopWidth - 128, 3); right DllStructSetData($stRET, "rcNormalPosition", @DesktopHeight - 128, 4); bottom $pStruct = DllStructGetPtr($stRET); Get pointer to the modified struct $iRET = _WinAPI_SetWindowPlacement($hWindow, $pStruct) If @error = 0 Then WinSetState($hWindow, "", @SW_RESTORE) ControlSetText($hWindow, "", "Edit1", "_WinAPI_SetWindowPlacement() succeeded!") Else MsgBox(16, "Error", "_WinAPI_SetWindowPlacement() failed!" & @CRLF & _ "$iRET = " & $iRET & @CRLF & _ "@error = " & @error & @CRLF & _ "@extended = " & @extended) EndIf Else MsgBox(16, "Error", "_WinAPI_GetWindowPlacement() failed!" & @CRLF & _ "$stRET = " & $stRET & @CRLF & _ "@error = " & @error & @CRLF & _ "@extended = " & @extended) EndIf ; #End Demo Script# ================================================================================ ; #FUNCTION# ==================================================================================== ; Name...........: _WinAPI_GetWindowPlacement ; Description ...: Retrieves the placement of the window for Min, Max, and normal positions ; Syntax.........: _WinAPI_GetWindowPlacement($hWnd) ; Parameters ....: $hWnd - Handle of the window ; Return values .: Success - returns $tagWINDOWPLACEMENT structure with the placement coordinates ; Failure - returns 0, @error = 1, @extended = _WinAPI_GetLastError() ; Author ........: PsaltyDS, with help from Siao and SmOke_N, at www.autoitscript.com/forum ; Modified.......: ; Remarks .......: ; Related .......: _WinAPI_SetWindowPlacement, $tagWINDOWPLACEMENT ; Link ..........; @@MsdnLink@@ GetWindowPlacement ; Example .......; Yes ; ============================================================================================= Func _WinAPI_GetWindowPlacement($hWnd) ; Create struct to receive data Local $stWindowPlacement = DllStructCreate($tagWINDOWPLACEMENT) DllStructSetData($stWindowPlacement, "length", DllStructGetSize($stWindowPlacement)) ; Get pointer to struct Local $pWindowPlacement = DllStructGetPtr($stWindowPlacement) ; Make DLL call Local $avRET = DllCall("user32.dll", "int", "GetWindowPlacement", "hwnd", $hWnd, "ptr", $pWindowPlacement) ; Return results If $avRET[0] Then Return $stWindowPlacement Else Return SetError(1, _WinAPI_GetLastError(), 0) EndIf EndFunc;==>_WinAPI_GetWindowPlacement ; #FUNCTION# ===================================================================================== ; Name...........: _WinAPI_SetWindowPlacement ; Description ...: Sets the placement of the window for Min, Max, and normal positions ; Syntax.........: _WinAPI_SetWindowPlacement($hWnd, $pWindowPlacement) ; Parameters ....: $hWnd - Handle of the window ; $pWindowPlacement - pointer to $tagWINDOWPLACEMENT structure ; Return values .: Success - Returns non-zero ; Failure - Returns 0, @error = 1, @extended = _WinAPI_GetLastError() ; Author ........: PsaltyDS at www.autoitscript.com/forum ; Modified.......: ; Remarks .......: ; Related .......: _WinAPI_GetWindowPlacement, $tagWINDOWPLACEMENT ; Link ..........; @@MsdnLink@@ SetWindowPlacement ; Example .......; Yes ; =============================================================================================== Func _WinAPI_SetWindowPlacement($hWnd, $pWindowPlacement) ; Make DLL call Local $avRET = DllCall("user32.dll", "int", "SetWindowPlacement", "hwnd", $hWnd, "ptr", $pWindowPlacement) ; Return results If $avRET[0] Then Return $avRET[0] Else Return SetError(1, _WinAPI_GetLastError(), 0) EndIf EndFunc;==>_WinAPI_SetWindowPlacementTesting and comment requested. Edit: Minor typo, fixed line-wrap in header because SmOke_N is watching... Edited June 6, 2008 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 More sharing options...
DaRam Posted June 6, 2008 Share Posted June 6, 2008 Another Useful function, Thanks. Here is how I am using this (earlier I would restore a Min or Max 'ed window to achieve it): Presumptions, _WinAPI_GetWindowPlacement is in an include as also <WinAPI.au3>, $IniFile is defined/set, Global Const $_Comma = ",", and $GUIMain is the Main Window defined elsewhere. Func SaveSettings() Local $App_Coords[4], $WinPlacement If FileExists($IniFile) Then; The App. does not save settings if this file does NOT already exist - Comment out to Force save $WinState = WinGetState($ActiveWindowTitle, "") If NOT BitAnd($WinState, 16) AND NOT BitAnd($WinState, 32) Then; NOT Minimized or Maximized $App_Coords = WinGetPos($GUIMain); Or $App_Coords = WinGetPos("[active]", "") WinSetState($GUIMain, "", @SW_MINIMIZE) Else $WinPlacement = _WinAPI_GetWindowPlacement($GUIMain) $App_Coords[0] = DllStructGetData($WinPlacement, "rcNormalPosition", 1); Left $App_Coords[1] = DllStructGetData($WinPlacement, "rcNormalPosition", 2); Top $App_Coords[2] = DllStructGetData($WinPlacement, "rcNormalPosition", 3); Right $App_Coords[3] = DllStructGetData($WinPlacement, "rcNormalPosition", 4); Bottom $App_Coords[2] = $App_Coords[2] - $App_Coords[0]; Discount Left from Right to Get Width $App_Coords[3] = $App_Coords[3] - $App_Coords[1]; Discount Top from Bottom to Get Height EndIf If UBound($App_Coords) = 4 Then; $App_Coords[0] = Left, 1 = Top, 2 = Width, 3 = Height IniWrite($IniFile, @UserName, "WinPos", $App_Coords[0] & $_Comma & $App_Coords[1] & $_Comma & $App_Coords[2] & $_Comma & $App_Coords[3]) EndIf ; Other IniWrite Values.... EndIf; FileExists($IniFile) EndFunc;SaveSettings() Link to comment Share on other sites More sharing options...
Zedna Posted June 10, 2008 Share Posted June 10, 2008 Testing and comment requested. If this is prepared for standard UDFs then you should make example "language neutral" according to BugTrack post I have seen some days ago. Original code: Run("notepad.exe") WinWait("Untitled - Notepad") On my Czech Windows: Run("notepad.exe") WinWait("Bez názvu - Poznámkový blok") Here is result from MessageBox on my WIN98SE (Success): $stWindowPlacement: length = 44 flags = 0 showCmd = 2 ptMinPosition: MinX = 3000 MinY = 3000 ptMaxPosition: MaxX = -1 MaxY = -1 rcNormalPosition: left = 256 top = 256 right = 656 bottom = 656 Are the ptMinPosition and ptMaxPosition values right? Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 18, 2008 Author Share Posted June 18, 2008 (edited) If this is prepared for standard UDFs then you should make example "language neutral" according to BugTrack post I have seen some days ago. Original code: Run("notepad.exe") WinWait("Untitled - Notepad") On my Czech Windows: Run("notepad.exe") WinWait("Bez názvu - Poznámkový blok")I haven't seen that Bug Trac yet, and the UDF Standards don't say anything about it. What do you think would be the easiest change to the demo script for that? I only went with Notepad because it's easy and familiar, and already used in many example scripts in the help file. I am submitting them as is, but could certainly submit an update if you have a good alternative. (See update post #1.) Here is result from MessageBox on my WIN98SE (Success): Are the ptMinPosition and ptMaxPosition values right?Thanks. I get -32000 on XP for MinX and MinY. The numbers are just what the API returns from the DLL call. Edited June 18, 2008 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 More sharing options...
GaryFrost Posted June 18, 2008 Share Posted June 18, 2008 WinWaitActive("[CLASS:Notepad]") $hWnd = WinGetHandle("[CLASS:Notepad]") SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 23, 2008 Author Share Posted June 23, 2008 The WinAPI.au3 UDF includes _WinAPI_GetWindowPlacement() and _WinAPI_SetWindowPlacement() as of Beta 3.2.13.3 dated 6/22/08. 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 More sharing options...
ptrex Posted June 24, 2008 Share Posted June 24, 2008 @PsaltyDS Congratulations !! Good job Regards, ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New 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