- Сообщения
- 8,673
- Репутация
- 2,486
Alexey [?]
Хм, странно, а теперь? :whistle:теперь ничего не работает
Хм, странно, а теперь? :whistle:теперь ничего не работает
Это из за сложности(?) индикации текущего окна. Ведь когда пользователь (я, вы) перключает окна вручную, то сбивается последовательность окон, тогда следующее может стать предыдущим. Решение есть, но оно подразумивает установку хука на окна, ну или циклический мониторинг активных окон... позже попробую сделать.что касается комбинации ctrl+win+3, то она ведёт себя странно - должна всегда переключать с текущего на следующее (и затем наоборот), а она переключает по-разному. иногда - правильно, иной раз - на предыдущее окно
Ничего подобного, назначить можно их без проблем:Ctrl + Win + 1/2 я привёл вот почему: запускать каждую из двух команд всё равно буду исключительно одной кнопкой (это максимально удобно, ради этого, по сути, всё и затевается). у меня это будут num 7 (previous window) и num 1 (next window). но если именно их прописать в скрипте, то будут конфликты с другими клавишами, поскольку num 7 - это также и home (а num 1 - end)
Global $sSwitchBack_HT = "{NUMPAD7}"
Global $sSwitchNext_HT = "{NUMPAD1}"
Ок:в нём не должно быть:
;<TaskBar Windows Switcher> program by G.Sandler, v1.1
;http://autoit-script.ru/index.php/topic,203.0.html
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <GUIToolbar.au3>
#include <WinAPI.au3>
#include <Array.au3>
#include <Misc.au3>
#include <HotKey.au3>
_Singleton("TaskBar_Windows_Switcher")
#Region Variables & Options
Opt("WinWaitDelay", 1)
Global $sLast_NextBack_Window = ""
Global $sLast_BackNext_Window = ""
Global $sExit_HT = 0x0352 ;ctrl + shift + R
Global $sSwitchBack_HT = 0x0A31 ;ctrl + win + 1
Global $sSwitchNext_HT = 0x0A32 ;ctrl + win + 2
Global $sSwitchDblBack_HT = 0x0A38 ;ctrl + win + 8
Global $sSwitchDblNext_HT = 0x0A39 ;ctrl + win + 9
Global $sSwitchNextBack_HT = 0x0A33 ;ctrl + win + 3
Global $sSwitchBackNext_HT = 0x0A37 ;ctrl + win + 7
Global $sSwitchFirst_HT = 0x0A30 ;ctrl + win + 0
Global $sSwitchLast_HT = 0x0A35 ;ctrl + win + 5
Global $sSwitchAsAltTab_HT = 0x0409 ;alt + tab
$aHK_Vars = StringSplit("Exit|Back|Next|DblBack|DblNext|NextBack|BackNext|First|Last|AsAltTab", "|")
For $i = 1 To $aHK_Vars[0]
If $aHK_Vars[$i] = "Exit" Then
_HotKeyAssign($sExit_HT, "_Exit")
Else
_HotKeyAssign(Eval("sSwitch" & $aHK_Vars[$i] & "_HT"), "_SwitchTaskBarWindow_Proc", _
BitOR($HK_FLAG_DEFAULT, $HK_FLAG_EXTENDEDCALL))
EndIf
Next
#EndRegion Variables & Options
While 1
Sleep(1000)
WEnd
Func _SwitchTaskBarWindow_Proc($iKey)
Local $HotKeyPressed = "0x" & Hex($iKey, 4)
_HotKeyAssign($HotKeyPressed)
Local $sActivate_Window = "", $hParent_Active_Wnd = _WinAPI_GetAncestor(WinGetHandle(""), $GA_ROOTOWNER)
Local $aTaskBarWindows = _WinListTaskBarWindowsEx(Number($HotKeyPressed <> $sSwitchAsAltTab_HT))
If @error Then Return _HotKeyAssign($HotKeyPressed, "_SwitchTaskBarWindow_Proc", BitOR($HK_FLAG_DEFAULT, $HK_FLAG_EXTENDEDCALL))
For $i = 1 To $aTaskBarWindows[0][0]
If WinActive($aTaskBarWindows[$i][0]) Or $aTaskBarWindows[$i][0] = $hParent_Active_Wnd Then
Switch $HotKeyPressed
Case $sSwitchBack_HT, $sSwitchAsAltTab_HT ;Предыдущее окно (1-ое по счёту)
If $i = 1 Then $i = $aTaskBarWindows[0][0] + 1
$sActivate_Window = $aTaskBarWindows[$i - 1][0]
Case $sSwitchNext_HT, $sSwitchAsAltTab_HT ;Следующее окно (1-ое по счёту)
If $i = $aTaskBarWindows[0][0] Then $i = 0
$sActivate_Window = $aTaskBarWindows[$i + 1][0]
Case $sSwitchDblBack_HT ;Предыдущее окно (2-ое по счёту)
If $i = 1 Then $i = $aTaskBarWindows[0][0] + 1
If $i = 2 Then $i = $aTaskBarWindows[0][0] + 2
$sActivate_Window = $aTaskBarWindows[$i - 2][0]
Case $sSwitchDblNext_HT ;Следующее окно (2-ое по счёту)
If $i = $aTaskBarWindows[0][0] Then $i = 0
If $i + 2 <= $aTaskBarWindows[0][0] Then $sActivate_Window = $aTaskBarWindows[$i + 2][0]
Case $sSwitchNextBack_HT ;Следующее <> Предыдущее окно
If $sLast_NextBack_Window <> $aTaskBarWindows[$i][0] Then $sLast_NextBack_Window = ""
If $sLast_NextBack_Window = "" Then
If $i = $aTaskBarWindows[0][0] Then $i = 0
$sActivate_Window = $aTaskBarWindows[$i + 1][0]
$sLast_NextBack_Window = $sActivate_Window
Else
If $i = 1 Then $i = $aTaskBarWindows[0][0] + 1
$sActivate_Window = $aTaskBarWindows[$i - 1][0]
$sLast_NextBack_Window = ""
EndIf
Case $sSwitchBackNext_HT ;Предыдущее <> Следующее окно
If $sLast_BackNext_Window <> $aTaskBarWindows[$i][0] Then $sLast_BackNext_Window = ""
If $sLast_BackNext_Window = "" Then
If $i = 1 Then $i = $aTaskBarWindows[0][0] + 1
$sActivate_Window = $aTaskBarWindows[$i - 1][0]
$sLast_BackNext_Window = $sActivate_Window
Else
If $i = $aTaskBarWindows[0][0] Then $i = 0
$sActivate_Window = $aTaskBarWindows[$i + 1][0]
$sLast_BackNext_Window = ""
EndIf
Case $sSwitchFirst_HT, $sSwitchLast_HT
$sActivate_Window = ""
EndSwitch
ExitLoop
EndIf
Next
;Не найдены активные окна...
If $sActivate_Window = "" Then
Switch $HotKeyPressed
Case $sSwitchBack_HT, $sSwitchLast_HT
;Активируем последнее окно
$sActivate_Window = $aTaskBarWindows[$aTaskBarWindows[0][0]][0]
Case Else
;Активируем первое окно
$sActivate_Window = $aTaskBarWindows[1][0]
EndSwitch
EndIf
WinActivate($sActivate_Window)
_HotKeyAssign($HotKeyPressed, "_SwitchTaskBarWindow_Proc", BitOR($HK_FLAG_DEFAULT, $HK_FLAG_EXTENDEDCALL))
EndFunc
Func _WinListTaskBarWindowsEx($iListSort=1)
Local $hToolbar = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", "ToolbarWindow323")
If @error Then $hToolbar = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", "ToolbarWindow322")
If @error Then Return SetError(1, 0, 0)
Local $aWinList = WinList()
Local $aRet_List[$aWinList[0][0] + 1][2], $iToolbarButtonIndex
For $i = 1 To $aWinList[0][0] Step 1
If Not BitAND(WinGetState($aWinList[$i][1]), 2) Then ContinueLoop
$iToolbarButtonIndex = _WinAPI_FindToolbarButton($aWinList[$i][1], $hToolbar)
If $iToolbarButtonIndex > 0 Then
$aRet_List[0][0] += 1
$aRet_List[$aRet_List[0][0]][0] = $aWinList[$i][1]
$aRet_List[$aRet_List[0][0]][1] = $iToolbarButtonIndex
EndIf
Next
If $aRet_List[0][0] = 0 Then Return SetError(2, 0, 0)
ReDim $aRet_List[$aRet_List[0][0] + 1][2]
If $iListSort Then _ArraySort($aRet_List, 0, 1, $aRet_List[0][0], 1)
Return $aRet_List
EndFunc
Func _WinAPI_FindWindowEx($hParent, $hChild, $sClass, $sWindow)
; must create structs and use ptrs to account for passing a true NULL as classname or window title
; simply using "wstr" and "" does NOT work
Local $sStruct1, $sStruct2
If $sClass = "" Then
$sClass = 0
Else
$sStruct1 = DllStructCreate("wchar[256]")
DllStructSetData($sStruct1, 1, $sClass)
$sClass = DllStructGetPtr($sStruct1)
EndIf
If $sWindow = "" Then
$sWindow = 0
Else
$sStruct2 = DllStructCreate("wchar[256]")
DllStructSetData($sStruct2, 1, $sWindow)
$sWindow = DllStructGetPtr($sStruct2)
EndIf
Local $aRet = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hChild, "ptr", $sClass, "ptr", $sWindow)
$sStruct1 = 0
$sStruct2 = 0
Return $aRet[0]
EndFunc
Func _WinAPI_FindToolbarButton($hWnd, $hTB)
Local $iReturn = -1, $iPID, $hProcess, $sStruct = DllStructCreate("ptr")
; open process owning toolbar control
_WinAPI_GetWindowThreadProcessId($hTB, $iPID)
$hProcess = _WinAPI_OpenProcess(0x410, False, $iPID)
If $hProcess Then
Local $iCount = _GUICtrlToolbar_ButtonCount($hTB)
For $i = 0 To $iCount - 1
Local $iID = _GUICtrlToolbar_IndexToCommand($hTB, $i)
; button param is ptr to owner's window handle, stored in target process's memory space
Local $dwData = _GUICtrlToolbar_GetButtonParam($hTB, $iID)
; read the window handle from the explorer process
Local $aRet = DllCall("kernel32.dll", "int", "ReadProcessMemory", "ptr", _
$hProcess, "ptr", $dwData, "ptr", DllStructGetPtr($sStruct), "uint", 4, "uint*", 0)
If $aRet[5] Then
If $hWnd = DllStructGetData($sStruct, 1) Then
$iReturn = $i
ExitLoop
EndIf
EndIf
Next
_WinAPI_CloseHandle($hProcess)
EndIf
Return $iReturn
EndFunc
Func _Exit()
Exit
EndFunc
Многие скажут что да, я лично папку includ'ов стараюсь не трогать.правильно ли я сделал, что закинул эти 3 файла в папку Include и при этом имевшийся HotKey.au3 был заменён новым из этого архива ?
CreatoR сказал(а):Задачка интересная, но как бы удивительно это не звучало, мне вот одно неясно - почему именно «Ctrl + Win + 1/2»? это же неудобно. Вообщем вот сделал через «Win + Left/Right»:
Код:#NoTrayIcon #include <GUIToolbar.au3> #include <Array.au3> ; Opt("WinWaitDelay", 1) $sExit_HT = "^+e" ;Выход по <Ctrl + Shift + E> $sSwitchBack_HT = "#{Left}" $sSwitchNext_HT = "#{Right}" HotKeySet($sExit_HT, "_Exit") HotKeySet($sSwitchBack_HT, "_SwitchTaskBarWindow_Proc") HotKeySet($sSwitchNext_HT, "_SwitchTaskBarWindow_Proc") While 1 Sleep(1000) WEnd Func _SwitchTaskBarWindow_Proc() HotKeySet(@HotKeyPressed) Local $sActivate_Window = "" Local $aTaskBarWindows = _WinListTaskBarWindowsEx() If @error Then Return HotKeySet(@HotKeyPressed, "_SwitchTaskBarWindow_Proc") For $i = 1 To $aTaskBarWindows[0][0] If WinActive($aTaskBarWindows[$i][0]) Then Switch @HotKeyPressed Case $sSwitchBack_HT ;Предыдущее окно If $i = 1 Then $i = $aTaskBarWindows[0][0] + 1 $sActivate_Window = $aTaskBarWindows[$i - 1][0] Case $sSwitchNext_HT ;Следующее окно If $i = $aTaskBarWindows[0][0] Then $i = 0 $sActivate_Window = $aTaskBarWindows[$i + 1][0] EndSwitch ExitLoop EndIf Next ;Не найдены активные окна... If $sActivate_Window = "" Then Switch @HotKeyPressed Case $sSwitchBack_HT ;Активируем последнее окно $sActivate_Window = $aTaskBarWindows[$aTaskBarWindows[0][0]][0] Case $sSwitchNext_HT ;Активируем первое окно $sActivate_Window = $aTaskBarWindows[1][0] EndSwitch EndIf WinActivate($sActivate_Window) HotKeySet(@HotKeyPressed, "_SwitchTaskBarWindow_Proc") EndFunc Func _WinListTaskBarWindowsEx() Local $hToolbar For $i = 2 To 4 $hToolbar = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", "ToolbarWindow32" & $i) If Not @error Then ExitLoop Next Local $aWinList = WinList() Local $aRet_List[$aWinList[0][0] + 1][2], $iToolbarButtonIndex For $i = $aWinList[0][0] To 1 Step -1 If Not BitAND(WinGetState($aWinList[$i][1]), 2) Then ContinueLoop $iToolbarButtonIndex = _WinAPI_FindToolbarButton($aWinList[$i][1], $hToolbar) If $iToolbarButtonIndex > 0 Then $aRet_List[0][0] += 1 $aRet_List[$aRet_List[0][0]][0] = $aWinList[$i][1] $aRet_List[$aRet_List[0][0]][1] = $iToolbarButtonIndex EndIf Next If $aRet_List[0][0] = 0 Then Return SetError(1, 0, 0) ReDim $aRet_List[$aRet_List[0][0] + 1][2] _ArraySort($aRet_List, 0, 1, $aRet_List[0][0], 1) Return $aRet_List EndFunc Func _WinAPI_FindWindowEx($hParent, $hChild, $sClass, $sWindow) ; must create structs and use ptrs to account for passing a true NULL as classname or window title ; simply using "wstr" and "" does NOT work Local $sStruct1, $sStruct2 If $sClass = "" Then $sClass = 0 Else $sStruct1 = DllStructCreate("wchar[256]") DllStructSetData($sStruct1, 1, $sClass) $sClass = DllStructGetPtr($sStruct1) EndIf If $sWindow = "" Then $sWindow = 0 Else $sStruct2 = DllStructCreate("wchar[256]") DllStructSetData($sStruct2, 1, $sWindow) $sWindow = DllStructGetPtr($sStruct2) EndIf Local $aRet = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hChild, "ptr", $sClass, "ptr", $sWindow) $sStruct1 = 0 $sStruct2 = 0 Return $aRet[0] EndFunc Func _WinAPI_FindToolbarButton($hWnd, $hTB) Local $iReturn = -1, $iPID, $hProcess, $sStruct = DllStructCreate("ptr") ; open process owning toolbar control _WinAPI_GetWindowThreadProcessId($hTB, $iPID) $hProcess = _WinAPI_OpenProcess(0x410, False, $iPID) If $hProcess Then Local $iCount = _GUICtrlToolbar_ButtonCount($hTB) For $i = 0 To $iCount - 1 Local $iID = _GUICtrlToolbar_IndexToCommand($hTB, $i) ; button param is ptr to owner's window handle, stored in target process's memory space Local $dwData = _GUICtrlToolbar_GetButtonParam($hTB, $iID) ; read the window handle from the explorer process Local $aRet = DllCall("kernel32.dll", "int", "ReadProcessMemory", "ptr", _ $hProcess, "ptr", $dwData, "ptr", DllStructGetPtr($sStruct), "uint", 4, "uint*", 0) If $aRet[5] Then If $hWnd = DllStructGetData($sStruct, 1) Then $iReturn = $i ExitLoop EndIf EndIf Next _WinAPI_CloseHandle($hProcess) EndIf Return $iReturn EndFunc Func _Exit() Exit EndFunc
Я уже написал код. Тебе просто нужно его адаптировать (вместо HotKeySet).можешь написать код