Тема: AHK v2: Заблокировать клавиатуру и мышь (+ AHK v1)
Составил такой вариант v2-скрипта для блокировки клавиатуры и мыши, который запускаю из v1-скрипта с правами администратора.
— блокирует по "F1 + Пробел" (можно разблокировать по этой же клавише, но закомментировано);
— после блокировки создает файл "BlockKbrdMouse.FLG", чтобы после перезапуска компьютера блокировка восстановилась;
— разблокирует по горячей строке "102" (в гуи записано словами, для защиты от неумеющих читать детей);
— разблокировка удаляет файл "BlockKbrdMouse.FLG";
— если запущен PotPlayer — остается рабочей только клавиша "Пробел", для возможности остановки/старта воспроизведения;
— добавил дополнительно почти все клавиши с return, так как "BlockInput(true)" некоторые мои клавиши преодолевали.
Есть вопрос по коду v2. Как исправить поведение, когда горячая строка не откликается на "102", если много раз перед этим набирались случайные цифры?
Код для v1:
IfExist, %MY_DATA%\_Scripts\BlockKbrdMouse.FLG
Gosub, BlockKbrdMouse
; Заблокировать клавиатуру и мышь
F1 & Space::
BlockKbrdMouse:
;Запуск программы С ПРАВАМИ Администратора
Run *RunAs "C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe" "%MY_DATA%\_Scripts\BlockKbrdMouse_(+ADMIN+AHKv2).ahk"
Return
Код для v2:
#Requires AutoHotkey v2.0
#SingleInstance Force
#UseHook
;KeyHistory 0 ; Отключает историю нажатий клавиш для оптимизации и снижения использования памяти.
; Путь к файлу флага
BlockKbrdMouseFile := A_ScriptDir "\BlockKbrdMouse.FLG"
; Создание файла флага, если он не существует
if !FileExist(BlockKbrdMouseFile) {
FileAppend("", BlockKbrdMouseFile) ; Создаёт пустой файл
}
; Инициализация переменных
isLocked := true
; Создание GUI
; Внешнее окно с красным фоном (для каймы)
myGui := Gui()
myGui.BackColor := "Red" ; Красный фон для имитации каймы
myGui.Opt("-Caption +AlwaysOnTop +ToolWindow +E0x80000") ; WS_EX_LAYERED, без +Border
; Внутреннее окно с жёлтым фоном и текстом
innerGui := Gui()
innerGui.BackColor := "Yellow" ; Жёлтый фон
innerGui.Opt("-Caption +Parent" myGui.Hwnd) ; Внутреннее окно
; Включить обнаружение скрытых окон
;!!DetectHiddenWindows(true)
;MsgBox WinExist("ahk_exe PotPlayerMini64.exe") ? "PotPlayer существует" : "PotPlayer не найден" ; Раскомментировать для отладки
; Проверка, существует ли процесс PotPlayer
if WinExist("ahk_exe PotPlayerMini64.exe") {
innerGui.SetFont("s18 cRed", "Segoe UI")
innerGui.Add("Text", "x10 y10 w120", "Сто два") ;Сто два
innerGui.SetFont("s18 cBlack", "Segoe UI")
innerGui.Add("Text", "x+20 y10 w580", " — разблокировать клавиатуру и мышь")
innerGui.Show("x10 y10 w680 h60") ; Уменьшенное окно
myGui.Show("w700 h80 y0") ; Внешнее окно по центру
myGui.Title := "BlockKbrdMouse_Win"
} else {
innerGui.SetFont("s20 cRed", "Segoe UI")
innerGui.Add("Text", "x10 y10 w120", "Сто два") ;Сто два
innerGui.SetFont("s20 cBlack", "Segoe UI")
innerGui.Add("Text", "x+20 y10 w350", " — разблокировать клавиатуру и мышь")
innerGui.SetFont("s12 cRed", "Segoe UI")
innerGui.Add("Text", "x10 y100 w120", "F1+Пробел")
innerGui.SetFont("s12 cBlack", "Segoe UI")
innerGui.Add("Text", "x+20 y100 w140", " — заблокировать")
innerGui.Show("x10 y10 w410 h140") ; Полное окно
myGui.Show("w430 h160 Center") ; Внешнее окно по центру
myGui.Title := "BlockKbrdMouse_Win"
}
; Проверка существования окна GrandGui
if WinExist("GrandGui")
{
; Установить прозрачность (100 — нечётко видимое)
DllCall("SetLayeredWindowAttributes", "Ptr", myGui.Hwnd, "UInt", 0, "UChar", 90, "UInt", 0x2)
}
else
{
; Установить прозрачность (255 — чётко видимое)
DllCall("SetLayeredWindowAttributes", "Ptr", myGui.Hwnd, "UInt", 0, "UChar", 255, "UInt", 0x2)
}
WinShow(myGui.Hwnd) ; Принудительно показать окно
WinRedraw(myGui.Hwnd) ; Перерисовать окно для гарантии отображения
; Включение блокировки при запуске скрипта
BlockInput(true)
SoundBeep(500, 200) ; Звуковой сигнал для подтверждения
; Исключения для клавиш
#InputLevel 1
; Исключение для пробела в окне PotPlayer: пробел не блокируется
$Space:: {
; Проверка, существует ли процесс PotPlayer
if WinExist("ahk_exe PotPlayerMini64.exe") {
WM_KEYDOWN := 0x0100
WM_KEYUP := 0x0101
VK_Space := 0x20
potPlayerTitle := "ahk_exe PotPlayerMini64.exe"
potPlayerID := WinGetID(potPlayerTitle)
DetectHiddenWindows(false)
BlockInput(false)
if potPlayerID {
persistentClass := getPersistentClass(potPlayerID)
hwnd := findChildByClass(potPlayerID, persistentClass)
if !hwnd {
ToolTip("❌ Класс " persistentClass " не найден, пробую заново")
persistentClass := getPersistentClass(potPlayerID)
hwnd := findChildByClass(potPlayerID, persistentClass)
}
if hwnd {
; Временно активируем PotPlayer, чтобы пробел точно сработал
WinActivate("ahk_id " potPlayerID)
Sleep(40) ;100
; Отправляем пробел
PostMessage(WM_KEYDOWN, VK_Space, 0, , hwnd)
Sleep(15) ;30
PostMessage(WM_KEYUP, VK_Space, 0, , hwnd)
ToolTip("Пробел отправлен в HWND: " hwnd)
; Снова поднимаем GUI поверх PotPlayer
WinSetAlwaysOnTop(true, "ahk_id " myGui.Hwnd)
WinSetAlwaysOnTop(true, "ahk_id " innerGui.Hwnd)
WinActivate("ahk_id " myGui.Hwnd) ; Только после отправки
} else {
ToolTip("❌ Не удалось найти нужное окно даже после повтора")
}
} else {
Send("{Space}")
ToolTip("PotPlayer не найден, пробел отправлен")
}
ToolTip()
BlockInput(true)
DetectHiddenWindows(true)
}
}
getPersistentClass(potPlayerID) {
persistentClass := ""
foundHwnd := 0
EnumChildProc(hwnd, _) {
class := WinGetClass("ahk_id " hwnd)
if class {
foundHwnd := hwnd
persistentClass := class
return false
}
return true
}
cb := CallbackCreate(EnumChildProc, "Fast")
DllCall("User32.dll\EnumChildWindows", "Ptr", potPlayerID, "Ptr", cb, "Ptr", 0)
CallbackFree(cb)
return (foundHwnd != 0) ? persistentClass : ""
}
findChildByClass(parentHwnd, className) {
foundHwnd := 0
EnumChildProc(hwnd) {
class := WinGetClass("ahk_id " hwnd)
if (class = className) {
foundHwnd := hwnd
return false
}
return true
}
cb := CallbackCreate(EnumChildProc, "Fast")
DllCall("User32.dll\EnumChildWindows", "Ptr", parentHwnd, "Ptr", cb, "Ptr", 0)
CallbackFree(cb)
return foundHwnd
}
#InputLevel 0
/*
; удерживать F1 + F5 + Пробел одновременно, чтобы разблокировать
SetTimer(CheckUnlock, 50)
CheckUnlock() {
global isLocked
if (isLocked && GetKeyState("F1", "P") && GetKeyState("F5", "P") && GetKeyState("Space", "P")) {
UnBlock()
}
}
*/
; Горячая строка для разблокировки
; --- Автозамена в любом месте ввода ---
:?*:102::
{
global isLocked
if (!GetKeyState("F1", "P") && isLocked)
{
UnBlock()
}
}
/*
; Горячая клавиша для блокировки (F1 + Пробел)
#HotIf GetKeyState("F1", "P") ; Проверяем, удерживается ли F1
Space::
{
UnBlock()
}
#HotIf
*/
; Функция разблокировки
UnBlock() {
global isLocked
BlockInput(false) ; Отключаем блокировку
isLocked := false
if FileExist(BlockKbrdMouseFile) {
FileDelete(BlockKbrdMouseFile) ; Удаляем файл флага
}
;myGui.Destroy() ; Уничтожаем GUI после разблокировки
;SoundBeep(1000, 200) ; Звуковой сигнал для подтверждения
ExitApp
}
; Перехват всех клавиш, кроме цифр, в состоянии блокировки
#HotIf isLocked
; Буквы
$a::return
$b::return
$c::return
$d::return
$e::return
$f::return
$g::return
$h::return
$i::return
$j::return
$k::return
$l::return
$m::return
$n::return
$o::return
$p::return
$q::return
$r::return
$s::return
$t::return
$u::return
$v::return
$w::return
$x::return
$y::return
$z::return
/*
; Цифровые клавиши
0::Return
1::Return
2::Return
3::Return
4::Return
5::Return
6::Return
7::Return
8::Return
9::Return
*/
; Функциональные клавиши
$F1::return
$F2::return
$F3::return
$F4::return
$F5::return
$F6::return
$F7::return
$F8::return
$F9::return
$F10::return
$F11::return
$F12::return
; Специальные клавиши
$AppsKey::Return ; Меню (context menu key)
;$Space::return
$Enter::return
$Tab::return
$Backspace::return
$Delete::return
$Insert::return
$Home::return
$End::return
$PgUp::return
$PgDn::return
$Up::return
$Down::return
$Left::return
$Right::return
$Esc::return
$CapsLock::return
$ScrollLock::return
$NumLock::return
$PrintScreen::return
$Pause::return
; Модификаторы
$LShift::return
$RShift::return
$LCtrl::return
$RCtrl::return
$LAlt::return
$RAlt::return
$LWin::return
$RWin::return
/*
; Знаки препинания и символы
$`::return
$~::return
$!::return
$@::return
$#::return
$$::return
$%::return
$^::return
$&::return
$*::return
$(::return
$)::return
$_::return
$+::return
$[::return
$]::return
${::return
$}::return
$|::return
$\::return
$;::return
$Colon::return
$'::return
$"::return
$,::return
$.::return
$<::return
$>::return
$/::return
$?::return
*/
/*
; Математические символы
Multiply::Return ; Умножение (*)
Add::Return ; Плюс (+)
Subtract::Return ; Минус (-)
Divide::Return ; Деление (/)
Decimal::Return ; Десятичная точка (.)
*/
; Клавиши цифрового блока (кроме цифр)
$NumpadDiv::return
$NumpadMult::return
$NumpadAdd::return
$NumpadSub::return
$NumpadEnter::return
$NumpadDot::return
; Мышь
$LButton::return
$RButton::return
$MButton::return
$XButton1::return
$XButton2::return
$WheelUp::return
$WheelDown::return
; Мультимедийные клавиши
Browser_Back::return
Browser_Forward::return
Browser_Refresh::return
Browser_Stop::return
Browser_Search::return
Browser_Favorites::return
Browser_Home::return
Volume_Mute::return
Volume_Down::return
Volume_Up::return
Media_Next::return
Media_Prev::return
Media_Stop::return
Media_Play_Pause::return
Launch_Mail::return
Launch_Media::return
Launch_App1::return
Launch_App2::return
#HotIf