Page 1 of 1

Конфликт горячих клавиш

Posted: 04 Sep 2023, 04:13
by beruk
Всем привет,
есть такая проблема: горячая клавиша в скрипте, с комбинацией ALT+SHIFT+X, где Х - цифра или латинская буква, иногда переключает раскладку клавиатуры, которая переключается комбинацией ALT+SHIFT в системе (Windows 10).

Code: Select all

Пример:
!+Z:: ; ALT+SHIFT+Z 
CoordMode, Mouse, Screen
Send ^a {Delete}
Return
Пробовал восстанавливать раскладку принудительно, не всегда работает:
Send {LAlt Down}{Shift}{LAlt Up}
Пробовал ставить ~ перед горячей клавишей, не помогло:
~!+Z::
Пробовал так, не помогло:

Code: Select all

#If GetKeyState("Alt") && GetKeyState("Shift")
    *z::
        Send, {Blind}{z}
        return
#If
По наблюдениям, проблема зависит от скорости исполнения и может появляться, может нет.

Re: Конфликт горячих клавиш  Topic is solved

Posted: 07 Sep 2023, 02:30
by beruk
Проблема решена.
Появилась блестящая идея - отключить переключение раскладки в системе и переключать ее средствами АНК (спасибо мне).
Очень Искусственный Интеллект вида GPT-3.5 написал мне для этого нерабочий код (спасибо ему).
Два дня я заставлял его исправлять свои ошибки, которые мы находили по очереди (спасибо нам).
В итоге, во код:

Code: Select all

;==ПЕРЕКЛЮЧЕНИЕ РАСКЛАДКИ КЛАВИАТУРЫ==============================
!LShift:: ; ALT+SHIFT. Комбинация !+:: не будет работать без третьей клавиши (например!+X::) , нужно именно !LShift::
    ; Получение текущей раскладки клавиатуры
    currentLayout := GetKeyboardLayout()
    
    ; Определение новой раскладки клавиатуры
    newLayout := (currentLayout = "RU") ? "EN" : "RU"


    ; Переключение на новую раскладку клавиатуры
    ToggleLayout(newLayout)

    return

; Функция для получения текущей раскладки клавиатуры
GetKeyboardLayout()
{
    ; Получение хэндла активного окна
    activeWindow := WinActive("A")


    ; Получение раскладки клавиатуры для активного окна
    GetKeyboardLayoutName(activeWindow, layoutName)
    

    ; Извлечение кода раскладки из имени
    StringMid, layoutCode, layoutName, 5, 2

    ; Возврат кода раскладки
    return layoutCode
}

; Функция для переключения раскладки клавиатуры
ToggleLayout(layoutCode)
{
    
; Получение хэндла активного окна
    activeWindow := WinActive("A")

    ; Определение кода сообщения для переключения раскладки
    WM_INPUTLANGCHANGEREQUEST := 0x50

    ; Определение параметров сообщения для переключения раскладки
    INPUTLANGCHANGE_FORWARD := 0x2
    INPUTLANGCHANGE_BACKWARD := 0x4

    ; Определение параметров переключения раскладки
    layoutChangeParam := (layoutCode = "EN") ? INPUTLANGCHANGE_FORWARD : INPUTLANGCHANGE_BACKWARD

    ; Отправка системного сообщения для переключения раскладки клавиатуры
    PostMessage, % WM_INPUTLANGCHANGEREQUEST, % layoutChangeParam, 0,, ahk_id %activeWindow%
    return
}

; Функция для получения имени раскладки клавиатуры
GetKeyboardLayoutName(hwnd, ByRef layoutName)
{
    layoutName := ""
    ; Определение кода сообщения для получения имени раскладки
    WM_INPUTLANGNAME := 0x50A

    ; Создание буфера для имени раскладки
    VarSetCapacity(buffer, 256 * 2, 0)

    ; Отправка системного сообщения для получения имени раскладки клавиатуры
    SendMessage, % WM_INPUTLANGNAME, 0, &buffer,, ahk_id %hwnd%

    ; Копирование имени раскладки из буфера
    DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "ptr", &buffer, "int", 256, "str", &layoutName, "int", 256, "ptr", 0, "ptr", 0)

    ; Возврат имени раскладки
    return layoutName
}
;================================================================

Re: Конфликт горячих клавиш

Posted: 12 Sep 2023, 08:34
by vmech
В вызове WideCharToMultiByte тип параметра "str", &layoutName, должен быть "ptr", а не "str"