Что нового

Обход проблемы с Send/HotKeySet/Accelerators при разных раскладках клавиатуры

sterro_sasha

Новичок
Сообщения
45
Репутация
1
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

Функция хорошая. Нельзя ли как-то сделать поддержку не только.. HotKeySet, но и Send?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

sterro_sasha [?]
Нельзя ли как-то сделать поддержку не только.. HotKeySet, но и Send?
Так уже работает.

Код:
_FixAccelHotKeyLayout()
Send('^v')
 

sterro_sasha

Новичок
Сообщения
45
Репутация
1
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

CreatoR сказал(а):
sterro_sasha [?]Так уже работает.

Код:
_FixAccelHotKeyLayout()
Send('^v')

К сожалению не работает. Или _FixAccelHotKeyLayout нужно вызывать непосредственно перед Send? С HotKey - работает. А при использовании Send - при русской раскладке пишется буква v.. а не вставка из буфера((
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
sterro_sasha [?]
Или _FixAccelHotKeyLayout нужно вызывать непосредственно перед Send?
Я кажется именно так и показал, а вы как то иначе пробовали? Тогда вам никто помочь не может.
 

Vivious

Новичок
Сообщения
1
Репутация
0
Почему-то некорректно отрабатывалось решение CreatoR: язык менялся, но вместо Ctrl+V отправлялось 'v'.
Предлагаю довольно примитивное решение, отлично работающее в моих условиях (запускаю скрипт вручную). Проверяет раскладку и, если она не английская, меняет её и перезагружается. Работает только с EXE, но, думаю, можно и поддержку au3 прикрутить.
Код:
Func _FixAccelHotKeyLayout()
    If @KBLayout <> 409 Then
        _WinAPI_SetKeyboardLayout(WinGetHandle('[ACTIVE]'), 0x0409)
        Run(@ScriptFullPath)
        Exit
    EndIf
EndFunc

При необходимости можно обратно включать предыдущую раскладку (не тестировалось)
Код:
Func _FixAccelHotKeyLayout()
    If @KBLayout <> 409 Then
        Local $iPrevLayout = @KBLayout
        _WinAPI_SetKeyboardLayout(WinGetHandle('[ACTIVE]'), 0x0409)
        Run(@ScriptFullPath)
        Sleep(500)
        _WinAPI_SetKeyboardLayout(WinGetHandle('[ACTIVE]'), '0x' & $iPrevLayout)
        Exit
    EndIf
EndFunc
 

Oki

Продвинутый
Сообщения
452
Репутация
63
Известно что при использований HotKeySet или GUISetAccelerators, нужно полагаться на текущую раскладку клавиатуры, т.е если мы к примеру задаём HotKeySet("^!s", "_Func"), то работать оно будет только если перед запуском скрипта раскладка клавиатуры по умолчанию была английская.
Как случилось, что об этом "известно", да ещё и с таких незапамятных времён, а в справке по этим функциям до сих пор это никак не упоминается?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
в справке по этим функциям до сих пор это никак не упоминается?
Потому что разработчики не считают это проблемой, для них это поведение системы и соответственно "не их проблема".
 

Oki

Продвинутый
Сообщения
452
Репутация
63
Потому что разработчики не считают это проблемой, для них это поведение системы и соответственно "не их проблема".
Мне такое зарывание головы в песок кажется странным. Во-первых, обычно программы корректно взаимодействуют с системой и сваливать всё на другую сторону несколько неправильно, как мне кажется. Во-вторых, даже если некий формализм позволяет вот так прикрываться, всё же справка обычно существует для информирования её пользователей, а не просто для формальной отписки в стиле "мы тут формально правы, а вы плавайте, как хотите". На родном языке создателей языка AutoIt это, как мне кажется, описывается идиомой с дословным переводом "маленькая голова". Как мне показалось при чтении других страниц справки, её авторы всё же стремятся донести до читателей требуемую информацию, а в этом случае подобные ожидания нарушаются. Если что, не хотелось никого обидеть, не прошу меня понять неправильно.
 

absolut27

Новичок
Сообщения
1
Репутация
0
Известно что при использований HotKeySet или GUISetAccelerators, нужно полагаться на текущую раскладку клавиатуры, т.е если мы к примеру задаём HotKeySet("^!s", "_Func"), то работать оно будет только если перед запуском скрипта раскладка клавиатуры по умолчанию была английская.
Следующий пример показывает как это можно обойти. Идея в том, чтобы на этапе запуска скрипта, раскладка клавиатуры для нашего приложения поменялась на английскую, тогда у нас не будет проблем, даже если мы переключили раскладку на русскую (или любую другую раскладку), заданные клавиши будут работать в любом случае.

Код:
#include <GUIConstantsEx.au3>
#include <GUIEdit.au3>
#include <WinAPIEx.au3>

_FixAccelHotKeyLayout()

HotKeySet("^+e", "_Quit")

$hGUI = GUICreate("Fix for hotkey/Accelerators assign problem", 300, 200)
$nEdit = GUICtrlCreateEdit("", 20, 40, 260, 120)

$nDummy = GUICtrlCreateDummy()
Dim $aAccelKeys[1][2] = [["^a", $nDummy]]
GUISetAccelerators($aAccelKeys)

GUISetState(@SW_SHOW, $hGUI)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $nDummy
            _GUICtrlEdit_SetSel($nEdit, 0, -1)
    EndSwitch
WEnd

Func _Quit()
    Exit
EndFunc

Func _FixAccelHotKeyLayout()
    Static $iKbrdLayout, $aKbrdLayouts
  
    If Execute('@exitMethod') <> '' Then
        Local $iUnLoad = 1
      
        For $i = 1 To Ubound($aKbrdLayouts) - 1
            If Hex($iKbrdLayout) = Hex('0x' & StringRight($aKbrdLayouts[$i], 4)) Then
                $iUnLoad = 0
                ExitLoop
            EndIf
        Next
      
        If $iUnLoad Then
            _WinAPI_UnloadKeyboardLayout($iKbrdLayout)
        EndIf
      
        Return
    EndIf
  
    $iKbrdLayout = 0x0409
    $aKbrdLayouts = _WinAPI_GetKeyboardLayoutList()
    _WinAPI_LoadKeyboardLayout($iKbrdLayout, $KLF_ACTIVATE)
  
    OnAutoItExitRegister('_FixAccelHotKeyLayout')
EndFunc
Доброго времени суток!
Правильно ли я понимаю что этот код нужно вставить в начало скрипта? Потому что у меня вместо выполнения кода появляется такое окно:
Fix for hotkey / Accelerators assign problem, которое не имеет отношения к моему дальнейшему коду. Язык операционной системы - Чехия. Прошу сильно не пинать, только сегодня начал изучать AutoIT. Спасибо.
Screenshot 2024-07-15 145657.png


Слава ChatGPT
Код:
; Получение текущего языка ввода
$currentLang = DllCall("user32.dll", "int", "GetKeyboardLayout", "int", 0)

; Проверка текущей раскладки
If $currentLang[0] <> 0x04090409 Then
    ; Если текущая раскладка отличается от английской (США), установить английскую (США) раскладку
    DllCall("user32.dll", "int", "LoadKeyboardLayout", "str", "00000409", "int", 1)
    Send("{LALT down}{SHIFT down}{SHIFT up}{LALT up}") ; Переключение на следующую раскладку
EndIf
 
Последнее редактирование:
Верх