Что нового

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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,484
Известно что при использований 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
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

CreatoR,
В библиотеке WinAPIEx.au3 есть функция с таким же названием. ИМХО, имеет смысл переименовать Вашу очень полезную функцию.
 
Автор
CreatoR

CreatoR

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

madmasles [?]
имеет смысл переименовать Вашу очень полезную функцию
Спасибо, переименовал.
 

agikon

Знающий
Сообщения
789
Репутация
17
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

а что если два скрипта одновременно работают вот с этой функцией то проблем не будет? или что-то изменять надо?

а то ж получается что эти строчки в двух скриптах одинаковые.
Код:
Local  $aRet = DllCall("user32.dll", "long", "LoadKeyboardLayoutW", "wstr", Hex($sLayoutID, 8), "int", 0)

DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", $WM_INPUTLANGCHANGEREQUEST, "int", 1, "int", $aRet[0])


или не надо ничего изменять?
 
Автор
CreatoR

CreatoR

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

agikon [?]
а что если два скрипта одновременно работают вот с этой функцией то проблем не будет?
Не должно быть.
 

agikon

Знающий
Сообщения
789
Репутация
17
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

понятно.

а скажите, эта функция меняет раскладку только для скрипта, или и в виндовсе меняется раскладка. ну смотрите, если у меня стоит русский по-умрлчанию, то если скрипт загружается вместе с виндовсем то что тогда при полной загрузке виндовса английская будет выставлена возле часов в трее, и мне прийдётся каждый раз менять на русскую?

обьясните пожалуйста.
 

Ganibal95

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

Помоему только для скрипта английская... :smile:
 
Автор
CreatoR

CreatoR

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

agikon
Меняется раскладка только для текущего скрипта, в этом и вся идея (и это кстати написано в первом сообщений темы).

Лучше 100 раз проверить, глядишь и вопросы отпадут ;)
 

agikon

Знающий
Сообщения
789
Репутация
17
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

спасибо!
 

madcrow

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

а для обратного перехода с английской на русскую раскладку клавиатуры, использовать ту же команду?(бывает что и такое надобоно)) :stars:
 
Автор
CreatoR

CreatoR

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

madcrow [?]
а для обратного перехода с английской на русскую раскладку клавиатуры, использовать ту же команду?
Да:
Код:
_WinAPI_LoadKeyboardLayoutEx(0x0419)
 

Dima1337

Осваивающий
Сообщения
186
Репутация
24
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

Доброго времени суток.
Опишу проблему: У меня две раскладки, русская и французская.
При запуске в языковое меню добавляется английская раскладка. И после завершения работы скрипта не исчезает (Только при перезагрузке). Как сделать что бы она исчезала после завершения скрипта?
 
Автор
CreatoR

CreatoR

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

Dima1337 [?]
При запуске в языковое меню добавляется английская раскладка. И после завершения работы скрипта не исчезает (Только при перезагрузке). Как сделать что бы она исчезала после завершения скрипта?
Хороший вопрос... ещё интереснее, так это почему она там появляется...
 

Dima1337

Осваивающий
Сообщения
186
Репутация
24
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

CreatoR сказал(а):
ещё интереснее, так это почему она там появляется...

Ну вопрос не ко мне, я запустил скрипт из шапки темы ничего не меняя...
 
Автор
CreatoR

CreatoR

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

Как вариант:

Код:
#include <WinAPISys.au3>

_WinAPI_ActivateKeyboardLayout(0x0409)


Но если в системе не установлена английская раскладка, то ввод будет тот же что установлен по умолчанию в системе.
Соответственно г.клавиши не сработают.
 
Автор
CreatoR

CreatoR

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

Вот так можно обойти эту проблему:

Код:
#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 $aKbrdLayouts[0]
			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
 

Dima1337

Осваивающий
Сообщения
186
Репутация
24
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

CreatoR,
Большое спасибо :smile:
 

Skif_off

Знающий
Сообщения
173
Репутация
12
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

CreatoR
AutoIt 3.3.8.1: если завершать скрипт с помощью Exit, то вылезает сообщение об ошибке в строке
Код:
For $i = 1 To $aKbrdLayouts[0]

что $aKbrdLayouts[0] - не массив. Как можно пофиксить?


Добавлено:
Сообщение автоматически объединено:

Если возможно, заодно сделать универсальной, заменив
Код:
$iKbrdLayout = 0x0409

на полученный с помощью _WinAPI_GetKeyboardLayout()?
 
Автор
CreatoR

CreatoR

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

Skif_off [?]
Как можно пофиксить?
Заменить
Код:
Static $iKbrdLayout, $aKbrdLayouts

на
Код:
Global $iKbrdLayout, $aKbrdLayouts


[?]
Если возможно, заодно сделать универсальной, заменив
Идея в том, чтобы загружать английскую раскладку, а не ту что установлена в системе.
 

Skif_off

Знающий
Сообщения
173
Репутация
12
Re: Обход проблемы с HotKeySet/Accelerators при разных раскладках клавиатуры

CreatoR
Спасибо, так заработало.

CreatoR сказал(а):
Идея в том, чтобы загружать английскую раскладку, а не ту что установлена в системе.
Но в конце функции возвращается русская, если была включена
Код:
$iKbrdLayout = 0x0409
$aKbrdLayouts = _WinAPI_GetKeyboardLayoutList()
_WinAPI_LoadKeyboardLayout($iKbrdLayout, $KLF_ACTIVATE)

А если в ОС нет русского 0x0409, а есть, например, греческий 0x0408? В этом смысле универсальная. Либо я просто не понял, как работает функция :smile:


Добавлено:
Сообщение автоматически объединено:

Прошу прощения, дошло: 0x0409 - это и есть английский, переклинило с 0x0419.
 
Верх