VAN0 Posted August 29, 2017 Posted August 29, 2017 Hello. Is there a way get notified when any autoit/non-autoit window is minimized? Thank you
SlackerAl Posted August 30, 2017 Posted August 30, 2017 You could write something to notify you using WinList to build a list of windows and then WinGetState to see if any have changed state. Perhaps there is some more elegant way to do this with COM events, but I do not know how. Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.
LarsJ Posted September 2, 2017 Posted September 2, 2017 (edited) This can be done with UI Automation code: expandcollapse popup#include "CUIAutomation2.au3" Opt( "MustDeclareVars", 1 ) Global Const $S_OK = 0x00000000 Global Const $E_NOINTERFACE = 0x80004002 Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global $tIUIAutomationPropertyChangedEventHandler, $oIUIAutomationPropertyChangedEventHandler Global $oUIAutomation Example() Func Example() $oIUIAutomationPropertyChangedEventHandler = ObjectFromTag( "oIUIAutomationPropertyChangedEventHandler_", $dtagIUIAutomationPropertyChangedEventHandler, $tIUIAutomationPropertyChangedEventHandler, True ) If Not IsObj( $oIUIAutomationPropertyChangedEventHandler ) Then Return $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return Local $pUIElement $oUIAutomation.GetRootElement( $pUIElement ) ; Desktop If Not $pUIElement Then Return Local $tPropertyArray = DllStructCreate( "int[1]" ) DllStructSetData( $tPropertyArray, 1, $UIA_WindowWindowVisualStatePropertyId, 1 ) $oUIAutomation.AddPropertyChangedEventHandlerNativeArray( $pUIElement, $TreeScope_Descendants, 0, $oIUIAutomationPropertyChangedEventHandler, $tPropertyArray, 2 ) ; Add the PropertyChangedEventHandler $oUIAutomation.AddPropertyChangedEventHandler( $pUIElement, $TreeScope_Descendants, 0, $oIUIAutomationPropertyChangedEventHandler, Ptr($tPropertyArray)) HotKeySet( "{ESC}", "Quit" ) While Sleep(100) WEnd EndFunc Func Quit() $oIUIAutomationPropertyChangedEventHandler = 0 DeleteObjectFromTag( $tIUIAutomationPropertyChangedEventHandler ) Exit EndFunc Func _UIA_getPropertyValue( $obj, $id ) Local $vVal $obj.GetCurrentPropertyValue( $id, $vVal ) Return $vVal EndFunc Func oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent( $pSelf, $pSender, $iPropertyId, $newValue ) ; Ret: long Par: ptr;int;ptr ConsoleWrite( @CRLF & "oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = " & $iPropertyId & ", $newValue = " & $newValue & @CRLF ) Local $oSender = ObjCreateInterface( $pSender, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) $oSender.AddRef() ConsoleWrite( "Handle " & _UIA_getPropertyValue( $oSender, $UIA_NativeWindowHandlePropertyId ) & @CRLF ) ConsoleWrite( "Name " & _UIA_getPropertyValue( $oSender, $UIA_NamePropertyId ) & @CRLF ) ConsoleWrite( "Class " & _UIA_getPropertyValue( $oSender, $UIA_ClassNamePropertyId ) & @CRLF ) ConsoleWrite( "Ctrl type " & _UIA_getPropertyValue( $oSender, $UIA_ControlTypePropertyId ) & @CRLF ) ConsoleWrite( "Ctrl name " & _UIA_getPropertyValue( $oSender, $UIA_LocalizedControlTypePropertyId ) & @CRLF ) ConsoleWrite( "Value " & _UIA_getPropertyValue( $oSender, $UIA_LegacyIAccessibleValuePropertyId ) & @CRLF ) ConsoleWrite( "State " & _UIA_getPropertyValue( $oSender, $UIA_WindowWindowVisualStatePropertyId ) & @CRLF ) Return $S_OK EndFunc Func oIUIAutomationPropertyChangedEventHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long Par: ptr;ptr* Local $sIID = StringFromGUID( $pRIID ) If $sIID = $sIID_IUnknown Then ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_QueryInterface: IUnknown" & @CRLF ) DllStructSetData( DllStructCreate( "ptr", $pObj ), 1, $pSelf ) Return $S_OK ElseIf $sIID = $sIID_IUIAutomationPropertyChangedEventHandler Then ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_QueryInterface: IUIAutomationPropertyChangedEventHandler" & @CRLF ) DllStructSetData( DllStructCreate( "ptr", $pObj ), 1, $pSelf ) Return $S_OK Else ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_QueryInterface: " & $sIID & @CRLF ) Return $E_NOINTERFACE EndIf EndFunc Func oIUIAutomationPropertyChangedEventHandler_AddRef( $pSelf ) ; Ret: ulong ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_AddRef" & @CRLF ) Return 1 EndFunc Func oIUIAutomationPropertyChangedEventHandler_Release( $pSelf ) ; Ret: ulong ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_Release" & @CRLF ) Return 1 EndFunc Func StringFromGUID( $pGUID ) Local $aResult = DllCall( "ole32.dll", "int", "StringFromGUID2", "struct*", $pGUID, "wstr", "", "int", 40 ) If @error Then Return SetError( @error, @extended, "" ) Return SetExtended( $aResult[0], $aResult[2] ) EndFunc Func ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = _ "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr"), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] $sTagPart = $aSplit[1] $sMethod = $sFunctionPrefix & $sNamePart If $fPrint Then Local $iPar = StringInStr( $sTagPart, ";", 2 ), $t If $iPar Then $t = "Ret: " & StringLeft( $sTagPart, $iPar - 1 ) & " " & _ "Par: " & StringRight( $sTagPart, StringLen( $sTagPart ) - $iPar ) Else $t = "Ret: " & $sTagPart EndIf Local $s = "Func " & $sMethod & _ "( $pSelf ) ; " & $t & @CRLF & _ "EndFunc" & @CRLF ConsoleWrite( $s ) EndIf $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) ConsoleWrite(@error & @CRLF & @CRLF) DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc Func DeleteObjectFromTag(ByRef $tInterface) For $i = 1 To DllStructGetData($tInterface, "Size") DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i)) Next $tInterface = 0 EndFunc Run the code in SciTE. Press Esc to exit. Window state values: ;enum WindowVisualState Global Const $WindowVisualState_Normal=0 Global Const $WindowVisualState_Maximized=1 Global Const $WindowVisualState_Minimized=2 See also this post. CUIAutomation2.7z Edited September 2, 2017 by LarsJ mLipok 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Deye Posted September 2, 2017 Posted September 2, 2017 look @ the example for _WinAPI_SetWinEventHook() and begin skinning the cat using this : _WinAPI_SetWinEventHook($EVENT_SYSTEM_FOREGROUND, $EVENT_SYSTEM_MINIMIZESTART, DllCallbackGetPtr($hEventProc), $WINEVENT_OUTOFCONTEXT)
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