Aleksks
  Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору в начале предыдущего сообщения по ссылке имеется чуть более старая версия autoit-скрипта   размещаю здесь самую последнюю версию, в которой просто убран мелкий неактуальный фрагмент, а также существенно изменены сочетания клавиш   (в сторону упрощения и увеличения удобства при сохранении функционала)      много часов на это вчера-сегодня было потрачено, вроде бы в итоге скрипт работает так же хорошо   но при этом 8 возможностей скрипта теперь напрямую прописаны как одинарные комбинации (а не тройные как раньше)      почти все проблемы заключались в том, что вообще есть две клавиши home, две клавиши end и две клавиши insert   и, например, на клавишу num7 (она же num-home) нужно было назначить собственную комбинацию (переключение на предыдущее окно панели задач), но заодно не потерять функционал простой клавиши home      также добавлены немногочисленные, но подробнейшие комментарии (примерно в строках 20-25), призванные существенно облегчить понимание сути как предыдущего сообщения, так и задумки в целом       Код: #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("My Windows-Switcher")      #Region Variables & Options   Opt("WinWaitDelay", 1)      Global $sLast_NextBack_Window       = ""   Global $sLast_BackNext_Window       = ""              ; COMMENT:  desired state of num-lock is 'always off'     to achieve it, this constantly running ahk-script is necessary:     NumLock::  {    setnumlockstate, alwaysoff     $numlock::YOUR-HOTKEY-TO-TOGGLE-'ALWAYS-ON-TOP'-STATE   }   return   ;   Global $sSwitchBack_HT              = 0x67 ; button num7      COMMENT:  (67: num7) (24: home)       24: works but also affects button 'home'         67: works only if 'num-lock' is on  so this constantly running ahk-script is necessary:        *VK24::send {VK67} return   ;   Global $sSwitchNext_HT              = 0x61 ; button num1      COMMENT:  (61: num1) (23: end)       23: works but also affects button 'end'         61: works only if 'num-lock' is on  so this constantly running ahk-script is necessary:        *VK23::send {VK61} return   ;   Global $sSwitchDblBack_HT           = 0x2C ; button 'prt scr'   Global $sSwitchDblNext_HT           = 0x2D ; button insert       COMMENT:  (2D: insert) (60: num0)        this constantly running ahk-script is necesssary:        *VK60::send {VK2D} return   Global $sSwitchNextBack_HT          = 0xB0 ; button 'next track'   Global $sSwitchBackNext_HT          = 0xB1 ; button 'previous track'   Global $sSwitchFirst_HT             = 0x6F ; button num/   Global $sSwitchLast_HT              = 0x6A ; button num*   Global $sSwitchAsAltTab_HT          = ""      $aHK_Vars = StringSplit("Back|Next|DblBack|DblNext|NextBack|BackNext|First|Last|AsAltTab", "|")      For $i = 1 To $aHK_Vars[0]       _HotKeyAssign(Eval("sSwitch" & $aHK_Vars[$i] & "_HT"), "_SwitchTaskBarWindow_Proc", _           BitOR($HK_FLAG_DEFAULT, $HK_FLAG_EXTENDEDCALL))   Next   #EndRegion Variables & Options      While 1       Sleep(100)   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]", "", "ToolbarWindow322")       If @error Then $hToolbar = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", "ToolbarWindow323")       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  |  
  |   Всего записей: 137 | Зарегистр. 25-04-2008 | Отправлено:  19:53 21-01-2019  | Исправлено: Aleksks,   20:31 21-01-2019    |  
  |