Показать полную графическую версию : [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?
Добрый день! Вариант send("!+") не подойдет, потому что нужно определить, какая раскладка у клавиатуры в данный момент, а потом высылать "!+" 1 или 0 раз.
Лучше же всего вообще обойтись без send.
Как взаимодействовать с языковой панелью у меня нет даже идеи)
Вообще задача такая:
... ; запомнить, какой была ракладка до начала "махинаций"
$str1=inputbox("1","2", "") ; при вводе в этот инпутбокс сделать раскладку английской
$str2=inputbox("1","2", "") ; при вводе в этот инпутбокс сделать раскладку русской
... ; вернуть ракладку в первоначальное состояние
Global $Rus = '00000419'; Раскладка русского языка
Global $Eng = '00000409'; Раскладка английского языка
Global $hWnd = WinGetHandle('AutoIt Help'); Находишь хендл своего окна
$def_lang = _WinAPI_GetKeyboardLayout($hWnd); Запоминаешь раскладку до "махинаций"
_WinAPI_SetKeyboardLayout($Rus, $hWnd); Ставишь язык на русским и делаешь что-то
_WinAPI_SetKeyboardLayout($Eng, $hWnd); Ставишь язык на английский и делаешь что-то
_WinAPI_SetKeyboardLayout($def_lang, $hWnd); Ставишь язык на начальный
Func _WinAPI_GetKeyboardLayout($hWnd)
Local $Ret = DllCall('user32.dll', 'long', 'GetWindowThreadProcessId', 'hwnd', $hWnd, 'ptr', 0)
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
$Ret = DllCall('user32.dll', 'long', 'GetKeyboardLayout', 'long', $Ret[0])
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
Return '0000' & Hex($Ret[0], 4)
EndFunc ;==>_WinAPI_GetKeyboardLayout
Func _WinAPI_SetKeyboardLayout($sLayout, $hWnd)
If Not WinExists($hWnd) Then
Return SetError(1, 0, 0)
EndIf
Local $Ret = DllCall('user32.dll', 'long', 'LoadKeyboardLayout', 'str', StringFormat('%08s', StringStripWS($sLayout, 8)), 'int', 0)
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
DllCall('user32.dll', 'ptr', 'SendMessage', 'hwnd', $hWnd, 'int', 0x0050, 'int', 1, 'int', $Ret[0])
Return SetError(0, 0, 1)
EndFunc ;==>_WinAPI_SetKeyboardLayout
@kaster
В последней версии WinAPIEx.au3 (http://autoit-script.ru/index.php/topic,47.0.html) уже используются не строковые значения для указания языка, а целочисленные - LCID константы.
:)
Yashied, да, это я уде опосля понял нашел в твое либе эти функции. а то что привел выше это из оффорума. наглец даже не указал откуда взял :teeth:
А как быть, если я создаю inputbox, в нем по умолчанию язык станет русским. Как поменять на английский?
Если так:
_WinAPI_SetKeyboardLayout($hWnd, $Eng)
inputbox(1,1)
то невозможно правильно указать $hWnd. Если так:
inputbox(1,1)
_WinAPI_SetKeyboardLayout($hWnd, $Eng)
то сначала исчезнет инпутбокс...
Попробовал поменять так:
#include <File.au3>
; Декларируем константы
Global $Rus = 0x0419
Global $Eng = 0x0409
Global $Chn = 0x0804
Global $InputBoxTitle = "InputBox"
; код файла, который запустим
$Code='#Include <WinAPIEx.au3>' & @CRLF & _
'Global $Rus = 0x0419' & @CRLF & _
'Global $Eng = 0x0409' & @CRLF & _
'Global $Chn = 0x0804 '& @CRLF & _
'Global $InputBoxTitle = "InputBox"'& @CRLF & _
'WinWait ($InputBoxTitle)'& @CRLF & _
'Global $hWnd = WinGetHandle($InputBoxTitle, "")'& @CRLF & _
'$def_lang = _WinAPI_GetKeyboardLayout($hWnd)'& @CRLF & _
'_WinAPI_SetKeyboardLayout($hWnd, $Eng)'
'WinSetTitle($hWnd,"","123321")' ; это чтобы знать, что $hWnd найден верно
$FilePath=@DesktopDir & "\ChangeLang.au3"
_FileCreate( $FilePath) ; создаем файл
FileWrite( $FilePath,$Code) ; пишем туда $code
ShellExecute($FilePath) ; запускаем его, по идее он должен дождаться окна с заголовком "InputBox" и поменять там язык на английский
inputbox($InputBoxTitle,1)
FileDelete ($FilePath) ; удаляем файл
но что-то не меняется, а ошибки не вижу.
Раньше я делал переключение расскладки клавиатуры, и заметил одно, что в таких окнах (если это окно на данный момент активно), как inputbox, или в окне Запуск программы (если нажать Пуск --> Выполнить), в Диспетчере задач windows и еще в некоторых, переключение расскладки с помощью такого способа (имеется ввиду способ описанный в примере kasterа или с помощью этого же способа, но использования библиотеки WinAPIEx.au3) не работает (Windows наверно думает что она умнее и поэтому расскладка клавиатуры в таких окнах не изменяется :( ), жалко что расскладку таким образом можно менять только в отдельном окне, хенд которого узнается, а не вобще, ибо если бы было что то наподобие как в windows меняется расскладка (shift+alt у меня), то было бы гораздо проще. А так поменял расскладку в каком то окне, запустил inputbox, а windows бах, и поставила какая до этого была установлена раскладка с помощью тех таки клавиш (shift+alt)... а другого способа наверное нет?.......
Т.к. в AutoIt нет многопоточности, могу посоветовать перед запуском InputBox запустить еще один скрипт, которые будет ждать окна с нужным заголовком, а после того, как дождется, поменяет там раскладку.
Примерно так.
Готовишь вспомогательный скрипт следующего содержания
Global $Rus = '00000419'; Раскладка русского языка
Global $Eng = '00000409'; Раскладка английского языка
While 1
If WinExists('InputBoxTitle', '') Then
$hWnd = WinGetHandle('InputBoxTitle', '')
;MsgBox(0, '', 'Got it')
_WinAPI_SetKeyboardLayout($Rus, $hWnd)
ExitLoop
EndIf
Sleep(100)
WEnd
Func _WinAPI_GetKeyboardLayout($hWnd)
Local $Ret = DllCall('user32.dll', 'long', 'GetWindowThreadProcessId', 'hwnd', $hWnd, 'ptr', 0)
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
$Ret = DllCall('user32.dll', 'long', 'GetKeyboardLayout', 'long', $Ret[0])
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
Return '0000' & Hex($Ret[0], 4)
EndFunc ;==>_WinAPI_GetKeyboardLayout
Func _WinAPI_SetKeyboardLayout($sLayout, $hWnd)
If Not WinExists($hWnd) Then
Return SetError(1, 0, 0)
EndIf
Local $Ret = DllCall('user32.dll', 'long', 'LoadKeyboardLayout', 'str', StringFormat('%08s', StringStripWS($sLayout, 8)), 'int', 0)
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
DllCall('user32.dll', 'ptr', 'SendMessage', 'hwnd', $hWnd, 'int', 0x0050, 'int', 1, 'int', $Ret[0])
Return SetError(0, 0, 1)
EndFunc ;==>_WinAPI_SetKeyboardLayout
Он будет непрерывно мониторить нужное тебе окно. Как только оно появится, немедленно поменяет в нем раскладку на нужную. Вот к примеру нужное
InputBox('InputBoxTitle', 'Russian text')
Аналогично можешь ставить какую угодно раскладку, и совершенствовать скрипт для мониторинга под свои нужны. Это первое что пришло в голову
Все намного проще. Для изменения раскладки для любого окна созданного в AutoIt (в том числе и InputBox()), нужно изменить раскладку для скрытого окна AutoIt.
AutoItWinSetTitle('MyAutoItTitle')
_WinAPI_SetKeyboardLayout(WinGetHandle(AutoItWinGetTitle()), 0x0419)
InputBox(...)
все гениальное просто :yes:
На самом деле это не есть хорошо. При смене раскладки клавиатуры системой посылаются сообщения WM_INPUTLANGCHANGE..., так вот, AutoIt окна, те что созданы с помощью GUICreate(), эти сообщения не обрабатывают. Только скрытое окно. В этом можно убедиться, применив _WinAPI_SetKeyboardLayout() к любому AutoIt-овскому окну, ничего не произойдет.
Странно, но в случае, описанном мною пару постов выше (#7 (http://forum.oszone.net/post-1265172-7.html)), там где два скрипта запущены, то есть один мониторит, другое окно - цель, так вот там все норм меняется. или чего то недопонял :)
Забавно что даже такой скрипт не работает:
Run(@AutoItExe & ' /AutoIt3ExecuteLine "InputBox(''My InputBox'', ''Prompt'')"')
WinWait("My InputBox")
_WinAPI_SetKeyboardLayout(0x0419, WinGetHandle("My InputBox"))
_WinAPI_SetKeyboardLayout(0x0419, WinGetHandle("My InputBox"))
Он и не должен работать.
_WinAPI_SetKeyboardLayout(WinGetHandle("My InputBox"), 0x0419)
Оказывается действительно надо было просто поменять раскладку скрытого AutoIt окна :)
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC