[решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Аватара пользователя
evg64

[решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение evg64 »

Добрый день! Вариант send("!+") не подойдет, потому что нужно определить, какая раскладка у клавиатуры в данный момент, а потом высылать "!+" 1 или 0 раз.

Лучше же всего вообще обойтись без send.

Как взаимодействовать с языковой панелью у меня нет даже идеи)



Вообще задача такая:





Код:

Код: Выделить всё

... ; запомнить, какой была ракладка до начала "махинаций"
$str1=inputbox("1","2", "") ; при вводе в этот инпутбокс сделать раскладку английской
$str2=inputbox("1","2", "") ; при вводе в этот инпутбокс сделать раскладку русской
... ; вернуть ракладку в первоначальное состояние
Аватара пользователя
kaster

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение kaster »

Код:

Код: Выделить всё

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
Аватара пользователя
Yashied

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение Yashied »

@kaster



В последней версии
WinAPIEx.au3
уже используются не строковые значения для указания языка, а целочисленные - LCID константы.



Изображение
Аватара пользователя
kaster

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение kaster »

Yashied, да, это я уде опосля понял нашел в твое либе эти функции. а то что привел выше это из оффорума. наглец даже не указал откуда взял Изображение
Аватара пользователя
evg64

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение evg64 »

А как быть, если я создаю inputbox, в нем по умолчанию язык станет русским. Как поменять на английский?

Если так:





Код:

Код: Выделить всё

_WinAPI_SetKeyboardLayout($hWnd, $Eng) 
inputbox(1,1)

то невозможно правильно указать $hWnd. Если так:



Код:

Код: Выделить всё

inputbox(1,1)
_WinAPI_SetKeyboardLayout($hWnd, $Eng)

то сначала исчезнет инпутбокс...



Попробовал поменять так:




читать дальше »




Код:

Код: Выделить всё

#include 
; Декларируем константы
Global $Rus = 0x0419 
Global $Eng = 0x0409 
Global $Chn = 0x0804
Global $InputBoxTitle = "InputBox"
; код файла, который запустим
$Code='#Include ' & @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) ; удаляем файл





но что-то не меняется, а ошибки не вижу.
Аватара пользователя
beve

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение beve »

Раньше я делал переключение расскладки клавиатуры, и заметил одно, что в таких окнах (если это окно на данный момент активно), как inputbox, или в окне Запуск программы (если нажать Пуск --> Выполнить), в Диспетчере задач windows и еще в некоторых, переключение расскладки с помощью такого способа (имеется ввиду способ описанный в примере kasterа или с помощью этого же способа, но использования библиотеки WinAPIEx.au3) не работает (Windows наверно думает что она умнее и поэтому расскладка клавиатуры в таких окнах не изменяется Изображение ), жалко что расскладку таким образом можно менять только в отдельном окне, хенд которого узнается, а не вобще, ибо если бы было что то наподобие как в windows меняется расскладка (shift+alt у меня), то было бы гораздо проще. А так поменял расскладку в каком то окне, запустил inputbox, а windows бах, и поставила какая до этого была установлена раскладка с помощью тех таки клавиш (shift+alt)... а другого способа наверное нет?.......
Аватара пользователя
kaster

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение kaster »

Т.к. в 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')

Аналогично можешь ставить какую угодно раскладку, и совершенствовать скрипт для мониторинга под свои нужны. Это первое что пришло в голову
Аватара пользователя
Yashied

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение Yashied »

Все намного проще. Для изменения раскладки для любого окна созданного в AutoIt (в том числе и InputBox()), нужно изменить раскладку для скрытого окна AutoIt.





Код:

Код: Выделить всё

AutoItWinSetTitle('MyAutoItTitle')
_WinAPI_SetKeyboardLayout(WinGetHandle(AutoItWinGetTitle()), 0x0419)
InputBox(...)
Аватара пользователя
Yashied

Re: [решено] Как поменять раскладку клавиатуры через AutoIt на заданную?

Сообщение Yashied »

На самом деле это не есть хорошо. При смене раскладки клавиатуры системой посылаются сообщения WM_INPUTLANGCHANGE..., так вот, AutoIt окна, те что созданы с помощью GUICreate(), эти сообщения не обрабатывают. Только скрытое окно. В этом можно убедиться, применив _WinAPI_SetKeyboardLayout() к любому AutoIt-овскому окну, ничего не произойдет.
Ответить

Вернуться в «AutoIt»