1 (изменено: jerrimix, 2021-11-04 22:40:32)

Тема: AHK: Бинд и перехват кнопок клавиатуры в Windows 7

Добрый день.
Помогите разобраться. Ниже скрипт, который прекрасно работает и ловит нажатие заложенных в алгоритме сочетаний клавиш на клавиатуре, но категорически отказывается делать это на Windows 7. Ошибок при этом не выдает. По какой причине такое может быть?


#NoEnv; 
#Warn; 
#Persistent

SendMode Input
SetWorkingDir %A_ScriptDir%

global adminControl:= 0
PID:= startApp()

Loop
 {
       if WinExist("Касса МойСклад") 
         {
                if !WinActive("Касса МойСклад") && !adminControl
                  {
		      WinActivate, Касса МойСклад
                  }
                if WinActive("Касса МойСклад") && !adminControl
                  {
                      WinSet, Style, -0xC40000, Касса МойСклад
                      WinMaximize, Касса МойСклад  
                      WinSet, AlwaysOnTop, On, Касса МойСклад
                  }
                if adminControl
                  {
                      WinSet, Style, +0xC40000, Касса МойСклад
                      WinSet, AlwaysOnTop, Off, Касса МойСклад
                  }
                if !adminControl 
                  {
                      DetectHiddenWindows On
                      WinGet, pidTaskMgr, PID, Диспетчер задач                                 
                      WinGet, processTaskMgr, ProcessName, Диспетчер задач                                 
                      if pidTaskMgr
                        Process, Close, %pidTaskMgr%
                      DetectHiddenWindows Off
                  }


          }

       if isProcessSuspended(PID)
         {
                MsgBox Кассовая система зависла и будет перезапущена автоматически...
                closeApp("Касса МойСклад", PID)
                PID := startApp()
         }
 }

; --------------------------------------------
$!F4::
       if WinActive("Касса МойСклад") && !adminControl
         return
       else if WinActive("Касса МойСклад") && adminControl
         Send !+{F4}
       else
         Send !+{F4}
       return    
$!TAB::
       if WinActive("Касса МойСклад") && !adminControl
         return
       else if WinActive("Касса МойСклад") && adminControl
         Send !+{TAB}
       else
         Send !+{TAB}
       return    
$!Escape::
       if WinActive("Касса МойСклад") && !adminControl
         return
       else if WinActive("Касса МойСклад") && adminControl
         Send !+{Escape}
       else
         Send !+{Escape}
       return    
$^Escape::
       if WinActive("Касса МойСклад") && !adminControl
         return
       else if WinActive("Касса МойСклад") && adminControl
         Send ^+{Escape}
       else
         Send ^+{Escape}
       return     
$LWin:: 
       if WinActive("Касса МойСклад") && !adminControl
         return
       else if WinActive("Касса МойСклад") && adminControl
         Send {LWin}
       else
         Send {LWin}
       return      
$RWin:: 
       if WinActive("Касса МойСклад") && !adminControl
         return
       else if WinActive("Касса МойСклад") && adminControl
         Send {RWin}
       else
         Send {RWin}
       return      

$^!t:: 
       if (adminControl)   
         { 
               if WinExist("Касса МойСклад") && WinActive("Касса МойСклад")
                 {
                     WinSet, Style, +0xC40000, Касса МойСклад
                     WinSet, AlwaysOnTop, Off, Касса МойСклад
                 }

               Run, taskmgr.exe, , max, _taskmgrpid

               if WinExist("Диспетчер задач") 
                 {
                     WinActivate, Диспетчер задач
                 }
         }
       return      

$^!a:: 
       if (!adminControl) 
         adminControl = 1
       else adminControl = 0
       return

$^!q:: 
       closeApp("Касса МойСклад", PID)
       ExitApp
       return
; ----------------------------------------


startApp()
  { 
       path1 = C:\Program Files
       path2 = C:\Program Files (x86)

       If FileExist(path1 "\moysklad-kassa\Касса МойСклад.exe")
         {
             Run, %path1%\moysklad-kassa\Касса МойСклад.exe, , max, _pid
             Return _pid
         }
       Else If FileExist(path2 "\moysklad-kassa\Касса МойСклад.exe")
         {
             Run, %path2%\moysklad-kassa\Касса МойСклад.exe, , max, _pid
             Return _pid
         }   
       Else 
         {
             MsgBox Не найден модуль запуска кассовой программы
         } 
   }

closeApp(_name, _pid)
   {
       if WinExist(_name) && WinActive(_name) 
       WinClose, %_name%, , 3000

       Process, Exist, %_pid%
       if ErrorLevel > 0
         {
             Process, Close, %_pid%
             if !ErrorLevel
             MsgBox 'Система не смогла завершить процесс, свяжитесь с системным администратором'
         }

       Sleep, 1000
   }

isProcessSuspended(_pid)	
   {	
        ; 0 = Unknown, 1 = Other, 2 = Ready, 3 = Running, 4 = Blocked, 5 = Suspended Blocked, 6 = Suspended Ready

	For thread In ComObjGet("winmgmts:").ExecQuery("SELECT * FROM Win32_Thread WHERE ProcessHandle = " _pid)
 	   If (thread.ThreadWaitReason != 5)
	     Return 0	; Not suspended.
	     Return 1	; Suspended.
   }

Спасибо.

2 (изменено: __Михаил__, 2021-11-05 00:23:32)

Re: AHK: Бинд и перехват кнопок клавиатуры в Windows 7

А простые способы перехвата клавиш работают?
И что мешало добавить программу в группу и установить перехват клавиш чисто в ней? Зачем делать такие проверки: "if WinActive("Касса МойСклад") && !adminControl"

Win10x64, AHK v1.1.33.09 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

3

Re: AHK: Бинд и перехват кнопок клавиатуры в Windows 7

__Михаил__ пишет:

А простые способы перехвата клавиш работают?
И что мешало добавить программу в группу и установить перехват клавиш чисто в ней? Зачем делать такие проверки: "if WinActive("Касса МойСклад") && !adminControl"

Не совсем понимаю, каким образом в самой программе? Проверки делал, чтобы знать, что программа открыта и включался по нажатию кнопок CTRL-ALT-A режим админа, то есть позволяло сложить окно и работать в Windows. В противном случае окно кассы не дает себя закрыть и сложить и в верху нет заголовка с крестиком.

Выяснил методом проб, что проблема на Windows 7 возникает именно в этих блоках:

           if WinActive("Касса МойСклад") && !adminControl
                  {
                      WinSet, Style, -0xC40000, Касса МойСклад
                      WinMaximize, Касса МойСклад 
                      WinSet, AlwaysOnTop, On, Касса МойСклад
                  }
                if adminControl
                  {
                      WinSet, Style, +0xC40000, Касса МойСклад
                      WinSet, AlwaysOnTop, Off, Касса МойСклад
                  }

Функция WinSet в таком виде работает нормально и корректно только в Windows 10, почему-то AlwaysOnTop в Windows 7 отрабатывается иначе, то есть окно постоянно становится в режиме поверх всех остальных окон и не может из него выйти с параметром Off.

4

Re: AHK: Бинд и перехват кнопок клавиатуры в Windows 7

При изменении стиля у окон можно словить разные баги. Например окно нельзя свернуть / развернуть. Ещё какие-то были у меня, уже не помню.
А так как в коде не подписано какие именно стили применяются (+код не очень дружелюбно написан) то лень разбираться.

Win10x64, AHK v1.1.33.09 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

5

Re: AHK: Бинд и перехват кнопок клавиатуры в Windows 7

jerrimix, напоминаю о правилах оформления кода. Освежите в памяти также правила цитирования.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder