Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Переключение раскладки клавиатуры правым SHIFT

Ответить
Настройки темы
[решено] Переключение раскладки клавиатуры правым SHIFT

(*.*)


Сообщения: 36553
Благодарности: 6693


Конфигурация

Профиль | Сайт | Отправить PM | Цитировать


Привет, коллеги!

У меня исторически работал сабж с помощью Windows PowerPro, но в 7 эта чудесная функция работать перестала. Можно ли такое реализовать с помощью AutoIt?

Буду признателен за скрипт.

Спасибо!

-------
Канал Windows 11, etc | Чат @winsiders


Отправлено: 22:50, 12-03-2010

 

Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата Vadikan:
У меня исторически работал сабж с помощью Windows PowerPro, но в 7 эта чудесная функция работать перестала »
Не тестировал в Win 7, но на XP для этой задачи прекрасно работает SwitchIt.

Цитата Vadikan:
Можно ли такое реализовать с помощью AutoIt? »
Конечно:

Код: Выделить весь код
#include <Misc.au3>

Dim $hUser32_Dll = DllOpen("User32.dll")

;Задаём языки циклического переключения (в том же порядке в каком они выводятся в списке ниже)
;Можно указывать как коды языков, так и их названия (см. список в функций _OSGetLangString):
Dim $sLangs_String = "English_United_States|Russian|Ukrainian"
Dim $aLayouts_List = StringSplit($sLangs_String, "|")

;"Ctrl + Shift + E" для выхода из скрипта
HotKeySet("^+e", "_Exit_Proc")

While 1
    Sleep(100)

    If _IsPressed("A1", $hUser32_Dll) Then
        _SwitchIt_Proc()
    EndIf
WEnd

Func _SwitchIt_Proc()
    Local $hWnd = WinGetHandle("[ACTIVE]")
    Local $nOld_Layout = _WinAPI_GetKeyboardLayout($hWnd)
    Local $nNew_Layout = $nOld_Layout

    For $i = 1 To $aLayouts_List[0]
        If $aLayouts_List[$i] = $nOld_Layout Or _OSGetLangString($aLayouts_List[$i]) = $nOld_Layout Then
            If $i = $aLayouts_List[0] Then $i = -1
            $nNew_Layout = _OSGetLangString($aLayouts_List[$i+1])
            ExitLoop
        EndIf
    Next

    _WinAPI_LoadKeyboardLayout($nNew_Layout, $hWnd)
EndFunc

Func _Exit_Proc()
    Exit
EndFunc

Func _WinAPI_LoadKeyboardLayout($sLayoutID, $hWnd)
    Local $WM_INPUTLANGCHANGEREQUEST = 0x50

    If StringLen($sLayoutID) <= 3 Then $sLayoutID = "00000" & $sLayoutID
    Local $aRet = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)

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

Func _WinAPI_GetKeyboardLayout($hWnd)
    Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
    $aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])

    Return "0000" & Hex($aRet[0], 4)
EndFunc

Func _OSGetLangString($sOSLang_Code=-1)
    If $sOSLang_Code == 0 Then Return SetError(1, 0, 0)

    Local $aOSLang_Codes = StringSplit( _
        "0436|41c|0401|0801|0c01|1001|1401|1801|1c01|2001|2401|2801|2c01|3001|3401|3801|3c01|4001|042b|042c|082c|" & _
        "042d|0423|0402|0403|0404|0804|0c04|1004|1404|041a|0405|0406|0413|0813|0409|0809|0c09|1009|1409|1809|1c09|2009|2409|" & _
        "2809|2c09|3009|3409|0425|0438|0429|040b|040c|080c|0c0c|100c|140c|180c|0437|407|0807|0c07|1007|1407|408|040d|0439|" & _
        "040e|040f|0421|0410|0810|0411|043f|0457|0412|0426|0427|042f|043e|083e|044e|0414|0814|0415|0416|0816|0418|0419|044f|" & _
        "081a|0c1a|041b|0424|040a|080a|0c0a|100a|140a|180a|1c0a|200a|240a|280a|2c0a|300a|340a|380a|3c0a|400a|440a|480a|4c0a|" & _
        "500a|0441|041d|081d|0449|0444|041e|041f|0422|0420|0443|0843|042a", "|")

    Local $aOSLang_Strings = StringSplit( _
        "Afrikaans|Albanian|Arabic_Saudi_Arabia|Arabic_Iraq|Arabic_Egypt|Arabic_Libya|Arabic_Algeria|Arabic_Morocco|" & _
        "Arabic_Tunisia|Arabic_Oman|Arabic_Yemen|Arabic_Syria|Arabic_Jordan|Arabic_Lebanon|Arabic_Kuwait|Arabic_UAE|" & _
        "Arabic_Bahrain|Arabic_Qatar|Armenian|Azeri_Latin|Azeri_Cyrillic|Basque|Belarusian|Bulgarian|Catalan|Chinese_Taiwan|" & _
        "Chinese_PRC|Chinese_Hong_Kong|Chinese_Singapore|Chinese_Macau|Croatian|Czech|Danish|Dutch_Standard|Dutch_Belgian|" & _
        "English_United_States|English_United_Kingdom|English_Australian|English_Canadian|English_New_Zealand|English_Irish|" & _
        "English_South_Africa|English_Jamaica|English_Caribbean|English_Belize|English_Trinidad|English_Zimbabwe|" & _
        "English_Philippines|Estonian|Faeroese|Farsi|Finnish|French_Standard|French_Belgian|French_Canadian|French_Swiss|" & _
        "French_Luxembourg|French_Monaco|Georgian|German_Standard|German_Swiss|German_Austrian|German_Luxembourg|" & _
        "German_Liechtenstei|Greek|Hebrew|Hindi|Hungarian|Icelandic|Indonesian|Italian_Standard|Italian_Swiss|Japanese|" & _
        "Kazakh|Konkani|Korean|Latvian|Lithuanian|Macedonian|Malay_Malaysia|Malay_Brunei_Darussalam|Marathi|Norwegian_Bokmal|" & _
        "Norwegian_Nynorsk|Polish|Portuguese_Brazilian|Portuguese_Standard|Romanian|Russian|Sanskrit|Serbian_Latin|" & _
        "Serbian_Cyrillic|Slovak|Slovenian|Spanish_Traditional_Sort|Spanish_Mexican|Spanish_Modern_Sort|Spanish_Guatemala|" & _
        "Spanish_Costa_Rica|Spanish_Panama|Spanish_Dominican_Republic|Spanish_Venezuela|Spanish_Colombia|Spanish_Peru|" & _
        "Spanish_Argentina|Spanish_Ecuador|Spanish_Chile|Spanish_Uruguay|Spanish_Paraguay|Spanish_Bolivia|Spanish_El_Salvador|" & _
        "Spanish_Honduras|Spanish_Nicaragua|Spanish_Puerto_Rico|Swahili|Swedish|Swedish_Finland|Tamil|Tatar|Thai|Turkish|" & _
        "Ukrainian|Urdu|Uzbek_Latin|Uzbek_Cyrillic|Vietnamese", "|")

    For $i = 1 To $aOSLang_Codes[0]
        If $sOSLang_Code = -1 Then
            If @OSLang = $aOSLang_Codes[$i] Then Return "0000" & $aOSLang_Strings[$i]
        Else
            If $sOSLang_Code = $aOSLang_Codes[$i] Then Return "0000" & $aOSLang_Strings[$i]
            If $sOSLang_Code = $aOSLang_Strings[$i] Then Return "0000" & $aOSLang_Codes[$i]
        EndIf
    Next

    Return SetError(1, 0, 0)
EndFunc
Это будет циклический переключать раскладку в текущем окне.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 23:55, 12-03-2010 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Ещё один способ, на этот раз учитываются используемые в системе раскладки клавиатуры, т.е не нужно теперь указывать языки вручную:

Код: Выделить весь код
#include <Misc.au3>

Global $hUser32_Dll = DllOpen("User32.dll")
Global $nKey = "A1"

;Получаем список используемых в системе раскладок клавиатуры (для циклического переключения)
Global $aLayouts_List = _WinAPI_GetKeyboardLayoutList()

;"Ctrl + Shift + E" для выхода из скрипта
HotKeySet("^+e", "_Exit_Proc")

While 1
    Sleep(10)

    If _IsPressed($nKey, $hUser32_Dll) Then
        While _IsPressed($nKey, $hUser32_Dll)
            Sleep(1)
        WEnd

        _SwitchIt_Proc()
    EndIf
WEnd

Func _SwitchIt_Proc()
    Local $hWnd = WinGetHandle("[ACTIVE]")
    Local $nOld_Layout = _WinAPI_GetKeyboardLayout($hWnd)

    For $i = 1 To $aLayouts_List[0]
        If $aLayouts_List[$i] = $nOld_Layout Then
            $i += 1
            If $i > $aLayouts_List[0] Then $i = 1

            _WinAPI_LoadKeyboardLayout($aLayouts_List[$i], $hWnd)

            ExitLoop
        EndIf
    Next
EndFunc

Func _Exit_Proc()
    Exit
EndFunc

Func _WinAPI_LoadKeyboardLayout($sLayoutID, $hWnd)
    Local $WM_INPUTLANGCHANGEREQUEST = 0x50

    If StringLen($sLayoutID) <= 3 Then $sLayoutID = "00000" & $sLayoutID
    Local $aRet = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)

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

Func _WinAPI_GetKeyboardLayout($hWnd)
    Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
    $aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])

    Return "0000" & Hex($aRet[0], 4)
EndFunc

Func _WinAPI_GetKeyboardLayoutList()
    Local $Ret

    $Ret = DllCall('user32.dll', 'int', 'GetKeyboardLayoutList', 'int', 0, 'ptr', 0)
    If (@error) Or ($Ret[0] = 0) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $tData = DllStructCreate('ptr[' & $Ret[0] & ']')

    $Ret = DllCall('user32.dll', 'int', 'GetKeyboardLayoutList', 'int', $Ret[0], 'ptr', DllStructGetPtr($tData))
    If (@error) Or ($Ret[0] = 0) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $List[$Ret[0] + 1] = [$Ret[0]]

    For $i = 1 To $List[0]
        $List[$i] = Hex(BitAND(DllStructGetData($tData, 1, $i), 0xFFFF))
    Next

    Return $List
EndFunc

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Последний раз редактировалось Creat0R, 13-03-2010 в 19:41. Причина: Поправлен пример

Это сообщение посчитали полезным следующие участники:

Отправлено: 02:25, 13-03-2010 | #3


Аватара для madmasles

Ветеран


Сообщения: 812
Благодарности: 353

Профиль | Отправить PM | Цитировать


Creat0R,
У меня не работает
Код: Выделить весь код
;"Ctrl + Shift + E" для выхода из скрипта
HotKeySet("^+e", "_Exit_Proc")
Меняю на
Код: Выделить весь код
;"Ctrl+Shift+F12" для выхода из скрипта
HotKeySet("^+{F12}", "_Exit_Proc")
Никаких проблем (Windows XP SP3 раскладка по умолчанию русская.)
А переключение отлично работает и память практически не кушает (~5,5 Мб). Класс!

Отправлено: 10:57, 13-03-2010 | #4


(*.*)


Сообщения: 36553
Благодарности: 6693

Профиль | Сайт | Отправить PM | Цитировать


Creat0R, если честно, у меня скрипт работает как-то нестабильно - то переключает, то нет.

Но спасибо за наводку на SwitchIt. Когда-то очень-очень давно я ей пользовался по-моему, но потом стал использовать PowerPro, т.к. в двух программах смысла не было.

Вопрос решен, благодарю!

-------
Канал Windows 11, etc | Чат @winsiders


Отправлено: 13:31, 13-03-2010 | #5


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата Vadikan:
если честно, у меня скрипт работает как-то нестабильно - то переключает, то нет. »
Может какое то другое приложение перехватывает клавишу Shift? а возможно пауза в цикле большая, можно попробовать изменить на Sleep(10).
Это в обеих вариантах такое поведение?

Цитата madmasles:
У меня не работает »
Это известная проблема.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 13:52, 13-03-2010 | #6


Аватара для madmasles

Ветеран


Сообщения: 812
Благодарности: 353

Профиль | Отправить PM | Цитировать


Creat0R,
С паузой Sleep(100) у меня стабильнее работают оба варианта, чем с паузой на Sleep(10), но все равно не 100%. Добавил после _SwitchIt_Proc() Beep(500, 100) - оба варианта отрабатывают на 100%.

Отправлено: 15:13, 13-03-2010 | #7


Аватара для Yashied

Старожил


Сообщения: 206
Благодарности: 88

Профиль | Отправить PM | Цитировать


Введите контрольный флаг для блокировки повторных нажатий и не нужно никаких Sleep() и Beep(). И нет необходимости вызывать DllOpen(), он загружается вместе с AutoIt.

Код: Выделить весь код
Global $Flag = _IsPressed("A1")

...

While 1
    Sleep(1)
    If _IsPressed("A1") Then
        If Not $Flag Then
            _SwitchIt_Proc()
            $Flag = 1
        EndIf
    Else
        $Flag = 0
    EndIf
WEnd

...
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:39, 13-03-2010 | #8


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата Yashied:
Введите контрольный флаг для блокировки повторных нажатий »
Хорошая идея, я как то забыл про этот метод.

Цитата Yashied:
нет необходимости вызывать DllOpen(), он загружается вместе с AutoIt »
Есть, об этом сказанно в справке:
Цитата:
Remarks:
If calling this function repeatidly, should open 'user32.dll' and pass in handle.
Чтобы dll'ка не загружалась при каждом вызове.

А ещё лучше так:

Код: Выделить весь код
While 1
    Sleep(10)

    If _IsPressed("A1", $hUser32_Dll) Then
        While _IsPressed("A1", $hUser32_Dll)
            Sleep(10)
        WEnd

        _SwitchIt_Proc()
    EndIf
WEnd

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 19:26, 13-03-2010 | #9


Аватара для Yashied

Старожил


Сообщения: 206
Благодарности: 88

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
Чтобы dll'ка не загружалась при каждом вызове. »
Это описание к функции _IsPressed(), я сомниваюсь, что его когда-нибудь обновляли. Возможно раньше это было так, но вот простой пример, как проверить загружена или нет Dll:

Код: Выделить весь код
#Include <GDIPlus.au3>

ConsoleWrite('user32.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\user32.dll') & @CR)
ConsoleWrite('shell32.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\shell32.dll') & @CR)
ConsoleWrite('psapi.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\psapi.dll') & @CR)
ConsoleWrite('shlwapi.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\shlwapi.dll') & @CR)
ConsoleWrite('wininet.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\wininet.dll') & @CR)

ConsoleWrite('------------------------------' & @CR)

ConsoleWrite('iphlpapi.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\iphlpapi.dll') & @CR)
$hDll = DllOpen('iphlpapi.dll')
ConsoleWrite('iphlpapi.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\iphlpapi.dll') & @CR)
DllClose($hDll)
ConsoleWrite('iphlpapi.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\iphlpapi.dll') & @CR)

ConsoleWrite('------------------------------' & @CR)

ConsoleWrite('gdiplus.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\gdiplus.dll') & @CR)
_GDIPlus_Startup()
ConsoleWrite('gdiplus.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\gdiplus.dll') & @CR)
_GDIPlus_Shutdown()
ConsoleWrite('gdiplus.dll: ' & _WinAPI_GetModuleHandle(@SystemDir & '\gdiplus.dll') & @CR)

Отправлено: 20:42, 13-03-2010 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Переключение раскладки клавиатуры правым SHIFT

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Интерфейс - [решено] IE8 Как вернуться на нормальное переключение раскладки,а не ctrl+2 shift'a lem785 Microsoft Windows 2000/XP 2 16-08-2009 19:06
Разное - [решено] Смена раскладки клавиатуры как по Ctrl+Shift так и по Alt+Shift nghst Microsoft Windows 2000/XP 1 22-01-2008 10:34
[решено] переключение раскладки клавиатуры Sergey Ugryumov Microsoft Windows NT/2000/2003 5 16-10-2007 12:25
Переключение раскладки по Shift+Shift Cubbie Microsoft Windows 2000/XP 3 10-09-2005 09:14
Запретить Переключение Раскладки Клавиатуры. Guest Microsoft Windows 95/98/Me (архив) 8 29-11-2002 23:04




 
Переход