Hallo Freunde der automatisierten Schritte,
Raupi hat in Post 17
Wechsel zwischen geöffneten Fenstern
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compile_Both=y
#AutoIt3Wrapper_UseX64=y
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <Process.au3>
_Singleton("switch", 0)
Opt("GUICoordMode", 0)
Opt("TrayIconHide", 1)
Global Const $GCL_CBCLSEXTRA = -20
Global Const $GCL_CBWNDEXTRA = -18
Global Const $GCL_HBRBACKGROUND = -10
Global Const $GCL_HCURSOR = -12
Global Const $GCL_HICON = -14
Global Const $GCL_HICONSM = -34
Global Const $GCL_HMODULE = -16
Global Const $GCL_MENUNAME = -8
Global Const $GCL_STYLE = -26
Global Const $GCL_WNDPROC = -24
$allwindows = WinList()
$count = $allwindows[0][0]
Global $relatedwindows[$count][$count]
$rows = 1
$colums = 0
$cnt = 1
$j = 1
$mouseX = MouseGetPos(0)
Global $thirdW = @DesktopWidth / 3
$third2 = (2 * $thirdW)
$third3 = @DesktopWidth
$x1 = ($thirdW / 2 - 332)
$x2 = ($thirdW + $x1)
$x3 = ($thirdW + $x2)
Global $winH = @DesktopHeight
Global $2thirdW = 2 * @DesktopWidth / 3
Global $maxW = @DesktopWidth
Global $m1X = 0
Global $m2X = @DesktopWidth / 3
Global $m3X = 2 * @DesktopWidth / 3
;;
Global $guiW, $guiH; auf jeden Fall deklarieren, sonst mault AutoIt
;---> Positionsbestimmung
If $mouseX <= $thirdW Then
$guiX = $x1
ElseIf $mouseX <= $third2 Then
$guiX = $x2
ElseIf $mouseX <= $third3 Then
$guiX = $x3
EndIf
;---> Fenster sammeln & Filtern. Anzahl von Zeilen & Spalten bestimmen.
For $i = 1 To $count
If (BitAND(WinGetState($allwindows[$i][1]), 16) Or WinGetState($allwindows[$i][1]) = 7) And $allwindows[$i][0] <> "Start" And $allwindows[$i][0] <> "Program Manager" And $allwindows[$i][0] <> "DWM Notification Window" And $allwindows[$i][0] <> "AMD:CCC-AEMCapturingWindow" And $allwindows[$i][0] <> "2. Client Starten" And $allwindows[$i][0] <> "SBSDKInstance" And $allwindows[$i][0] <> "" Then
$relatedwindows[$j][0] = $allwindows[$i][0]
$relatedwindows[$j][1] = $allwindows[$i][1]
$colums = $colums + 1
$j = $j + 1
If $colums > 4 Then
$colums = 1
$rows = $rows + 1
EndIf
EndIf
Next
;---> Maße der GUI gemäß Zeilen & Spalten
If $j == 1 Then
$guiW = 260
ElseIf $j <= 4 Then
$guiW = $j * 115
Else
$guiW = 550
EndIf
$guiH = ($rows * 90)
$ygap = 80
;---> semitransparenter Hintergrund
$background = GUICreate("", $guiW, $guiH, $guiX, -1, $WS_POPUP, $WS_EX_TOPMOST)
GUISetBkColor(0x01)
_Gui_RoundCorners($background, 0, 0, 50, 50)
WinSetTrans($background, "", 100)
GUISetState()
;---> transparente GUI mit "Kacheln" für die Fenster
$winswitch = GUICreate("Switch", $guiW, $guiH, $guiX, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST), $background)
GUISetBkColor(0x01)
$hDC_Window = _WinAPI_GetDC($winswitch) ;---> DC für Icon extract...
;---> Meldung, falls keine Fenster geunden wurden...
If $j == 1 Then
GUICtrlCreateLabel("", 20, 40, 215, 35)
GUICtrlSetBkColor(-1, 0x757273)
GUICtrlCreateLabel("sorry, there are no windows...", 5, 5, 230, 25)
GUICtrlSetFont(-1, 12, 500, 0, "Segoe UI")
GUICtrlSetColor(-1, 0xffffff)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
Else
For $i = 1 To $j - 1
If $i = 1 Then ; Erster Button
$relatedwindows[1][2] = GUICtrlCreateButton($relatedwindows[1][0], 25, 25, 110, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE))
ElseIf $cnt = 4 Then; 4. Button in der Zeile
$relatedwindows[$i][2] = GUICtrlCreateButton("", -388, -1 + $ygap, 110, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE))
$cnt = 1
Else
$relatedwindows[$i][2] = GUICtrlCreateButton("", -1 + 130, -1, 110, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE))
$cnt = $cnt + 1
EndIf
;Hier ist die Deklaration zu Ende, der übrige Code bleibt gleich
$hIcon = _SendMessage($relatedwindows[$i][1], $WM_GETICON, 2, 0, 0, Default, Default, "HANDLE")
If Not $hIcon Then $hIcon = GetIconfromExe($relatedwindows[$i][0])
If Not $hIcon Then $hIcon = _SendMessage($relatedwindows[$i][1], $WM_GETICON, 0, 0, 0, Default, Default, "HANDLE")
If Not $hIcon Then $hIcon = _WinAPI_GetClassLongEx($relatedwindows[$i][1], $GCL_HICON)
If Not $hIcon Then $hIcon = _WinAPI_GetClassLongEx($relatedwindows[$i][1], $GCL_HICONSM)
GUICtrlSetData($relatedwindows[$i][2], StringLeft($relatedwindows[$i][0], 10));Buttontext einfügen, egal ob es ein Icon gibt !!!!
GUICtrlSetFont($relatedwindows[$i][2], 10, 400, 0, "Segoe UI")
If $hIcon Then
Local $hOldImage = _SendMessage(GUICtrlGetHandle($relatedwindows[$i][2]), $BM_SETIMAGE, 1, $hIcon)
_SendMessage($winswitch, $WM_ERASEBKGND, $hDC_Window)
_WinAPI_DestroyIcon($hOldImage);Altes ButtonIcon zerstören
_WinAPI_DestroyIcon($hIcon)
EndIf
Next
EndIf
GUISetState()
_WinAPI_SetLayeredWindowAttributes($winswitch, 0x01, 255)
;---> Falls keine Fester gefunden: Meldung für 3sec zeigen und dann beenden.
If $j == 1 Then
Sleep(3000)
Exit
EndIf
While 1
$msg = GUIGetMsg()
WinSetOnTop($winswitch, "", 1)
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case Else
;---> Auf Buttons lauschen
For $i = 1 To $j - 1
If $msg = ($relatedwindows[$i][2]) Then
__PopUp($relatedwindows[$i][0])
Exit
EndIf
Next
EndSwitch
WEnd
;---> PoUp mit Aktionen für gewähltes Fenster
Func __PopUp($window)
$position = GUICreate("", 338, 280, $guiX, -1, $WS_POPUP, $WS_EX_TOPMOST, $background);Wenn diese Gui als vorderste liegen soll und die HauptGui nicht mehr anklickbar sein soll, Parent als letzten Parameter setzen.
GUISetBkColor(0x01)
;==> Positions
GUICtrlCreateGroup("", 25, 25, 290, 160)
GUICtrlSetColor(-1, 0xffffff)
GUICtrlCreateLabel(" Action ", 15, -8, 63, 25)
GUICtrlSetFont(-1, 12, 500, 0, "Segoe UI")
GUICtrlSetColor(-1, 0xffffff)
$m1 = GUICtrlCreateButton("", -1, 30, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\m1-gui.ico")
$m2 = GUICtrlCreateButton("", 70, 0, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\m2-gui.ico")
$m3 = GUICtrlCreateButton("", 70, 0, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\m3-gui.ico")
$m12 = GUICtrlCreateButton("", 70, 0, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\m12-gui.ico")
$m23 = GUICtrlCreateButton("", -210, 70, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\m23-gui.ico")
$max = GUICtrlCreateButton("", 70, 0, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\maximize-gui.ico")
$min = GUICtrlCreateButton("", 70, 0, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\minimize-gui.ico")
$close = GUICtrlCreateButton("", 70, 0, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetImage(-1, @ScriptDir & "\GUI\close-gui.ico")
$esc = GUICtrlCreateButton("cancel", -105, 90, 50, 50, BitOR($BS_MULTILINE, $BS_PUSHLIKE, $BS_ICON))
GUICtrlSetFont(-1, 12, 400, 0, "Segoe UI")
_Gui_RoundCorners($position, 0, 0, 50, 50)
GUISetState(@SW_SHOW)
While 1
$button = GUIGetMsg()
Switch $button
Case $GUI_EVENT_CLOSE
Exit
Case $m1
WinActivate($window, "")
$positionX = $m1X
$positionW = $thirdW
WinMove($window, "", $positionX, 0, $positionW, $winH, 3)
Exit
Case $m2
WinActivate($window, "")
$positionX = $m2X
$positionW = $thirdW
WinMove($window, "", $positionX, 0, $positionW, $winH, 3)
Exit
Case $m3
WinActivate($window, "")
$positionX = $m3X
$positionW = $thirdW
WinMove($window, "", $positionX, 0, $positionW, $winH, 3)
Exit
Case $m12
WinActivate($window, "")
$positionX = $m1X
$positionW = $2thirdW
WinMove($window, "", $positionX, 0, $positionW, $winH, 3)
Exit
Case $m23
WinActivate($window, "")
$positionX = $m1X
$positionW = $2thirdW
WinMove($window, "", $positionX, 0, $positionW, $winH, 3)
Exit
Case $max
WinActivate($window, "")
$positionX = $m1X
$positionW = $maxW
WinMove($window, "", $positionX, 0, $positionW, $winH, 3)
Exit
Case $min
WinSetState($window, "", @SW_MINIMIZE)
Exit
Case $close
WinClose($window, "")
Exit
Case $esc
Return
EndSwitch
WEnd
EndFunc ;==>__PopUp
Func _Gui_RoundCorners($h_win, $i_x1, $i_y1, $i_x3, $i_y3)
Local $XS_pos, $XS_ret, $XS_ret2
$XS_pos = WinGetPos($h_win)
$XS_ret = DllCall("gdi32.dll", "long", "CreateRoundRectRgn", "long", $i_x1, "long", $i_y1, "long", $XS_pos[2], "long", $XS_pos[3], "long", $i_x3, "long", $i_y3)
If $XS_ret[0] Then
$XS_ret2 = DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $XS_ret[0], "int", 1)
EndIf
EndFunc ;==>_Gui_RoundCorners
Func _WinAPI_GetClassLongEx($hWnd, $iIndex)
Local $Ret
If @AutoItX64 Then
$Ret = DllCall('user32.dll', 'ulong_ptr', 'GetClassLongPtrW', 'hwnd', $hWnd, 'int', $iIndex)
Else
$Ret = DllCall('user32.dll', 'ulong', 'GetClassLongW', 'hwnd', $hWnd, 'int', $iIndex)
EndIf
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc ;==>_WinAPI_GetClassLongEx
Func GetIconfromExe($Title)
Local $iIcons = 1; 1
Local $t_ahIcons = DllStructCreate("HWND[" & $iIcons & "]") ;HWND Array um die Icons zu erhalten
Local $p_ahIcons = DllStructGetPtr($t_ahIcons)
Local $PID = WinGetProcess($Title)
Local $Prozessname = _ProcessGetName($PID)
Local $AndwendungsPfad = _GetPathByPid($PID)
If $Prozessname <> "explorer.exe" Then
_WinAPI_ExtractIconEx($AndwendungsPfad, 0, 0, $p_ahIcons, $iIcons)
If Not @error Then Return DllStructGetData($t_ahIcons, 1, 1)
Return 0
Else; Fenster gehört zu Explorer.exe geladen wird dabei das 202. ICon aus der imageres.dll. ggF. kann auch ein anderes verwendet werde.
_WinAPI_ExtractIconEx(@SystemDir & "\imageres.dll", 202, 0, $p_ahIcons, $iIcons)
If Not @error Then Return DllStructGetData($t_ahIcons, 1, 1)
Return 0
EndIf
EndFunc ;==>GetIconfromExe
Func _GetPathByPid($iPID); gefunden im Englischen Forum , verfasser nicht bekannt.
Local $aProc = DllCall('kernel32.dll', 'hwnd', 'OpenProcess', 'int', 0x0410, 'int', 0, 'int', $iPID)
If $aProc[0] = 0 Then Return SetError(1, 0, '')
Local $vStruct = DllStructCreate('int[1024]')
DllCall('psapi.dll', 'int', 'EnumProcessModules', 'hwnd', $aProc[0], 'ptr', DllStructGetPtr($vStruct), 'int', DllStructGetSize($vStruct), 'int_ptr', 0)
Local $aReturn = DllCall('psapi.dll', 'int', 'GetModuleFileNameExW', 'hwnd', $aProc[0], 'int', DllStructGetData($vStruct, 1), 'wstr', '', 'int', 2048)
If $aReturn[0] = 0 Then Return SetError(2, 0, '')
Return $aReturn[3]
EndFunc ;==>_GetPathByPid
Alles anzeigen
ein recht interessantes Script als Alt Tab Ersatz gepostet.
Wer mag das Script mit updaten?
1. Das Grundfenster soll 2x so hoch und 3x so breit werden.
In welchen Zeilen muss dass geändert werden?
2. Die Button sollen 3x so breit werden.
In welchen Zeilen muss dass geändert werden?
3. Die Programme sollen von A-Z sortiert werden, bevor sie als Button angezeigt werden.
Ich habe das mit
_ArraySort($relatedwindows, 0)
probiert. Anzeige und Sortierung dauern ewig ... weil ...
... auf meinem System im Array rund 1300 Zeilen und 249 Spalten verwendet werden, obwohl nur 21 sichtbare Fenster vorhanden sind.
Die anderen Zeilen und Spalten erscheinen leer.
Und warum 249 Spalten mit Array Display angezeigt werden, erschließt sich mir nicht - weiß jemand, warum?
Und ob diese eine Funktion im Script haben?
Das Array wurde damals als
$allwindows = WinList()
$count = $allwindows[0][0]
Global $relatedwindows[$count][$count]
definiert.
Wie kann man das optimieren, dass das Array nur die Größe der sichtbaren Fenster hat? Dann müsste auch die Sortierung schneller funktionieren.
Wer das Script testet, wird sehen, dass im Aktions-Fenster nur 8 leere Button + Cancel zu sehen ist.
Dass auf den 8 Button des Aktionsfensters nichts zu sehen ist, liegt daran, dass die Icons im ursprünglichen Thread nicht beigefügt wurden - oder täusche ich mich?
4. Es wird hier von meinen Programmen auf den Button nur vom einem Programmfenster (PotPlayer) kein Icon angezeigt. Das ist zwar auf der Startleiste vom Windows 8 / 64 zu sehen, aber nicht auf dem Button im obigen Script. Weiß jemand, wie man das am besten beheben kann?
5. Ich würde das Programm gerne um einen Button "Liste aktualisieren" ergänzen.
Falls Ihr noch weitere empfehlenswerte Alt Tab Listen kennt, die mit Autoit erstellt wurden, würde ich mich über einen Link freuen.
Nach 4 Stunden Tests - Schlafenszeit - 4:50 Uhr ... 2 freie Tage und es geht zurück ins Arbeitsleben.
Viele Grüße und vielen Dank
AutoMit
PS: Übrigens - noch eine Frage am Rande zur Fensteraktivierung:
laut Hilfe:
Fenster-Titel und -Text (erweitert)
Fenster-Handles funktionieren immer, egal welcher WinTitleMatchMode gerade in Benutzung ist.
Wie muss WinActivate(handle) geschrieben werden?
So funktioniert es nicht, Rückgabewert 0.
$ergebnis = WinActivate(0x00510C34) ; Handle per Script ausgelesen
$ergebnis = WinActivate(0x0000000000510C34) ; Handle mit dem Autoit v3 Info Tool ausgelesen
Falls man WinActivate nicht mit dem Handle als Parameter nutzen kann, wie kann man dann ein Fenster aktivieren, von dem man "nur" das Handle hat?