发表回复 
输入法切换方法不完全小结
2011-10-30, 11 : 41 (这个帖子最后修改于: 2015-08-21 21 : 33 by robertL.)
输入法切换方法不完全小结
在论坛中之前有一些关于如何在脚本窗口或其他程序中切换输入法的帖子, 这里对一些常见的情况进行小结, 其中也包含不同方式的比较, 大家可以在实践中进行体会, 什么方式比较适合.
这个小结包括几个部分:
  1. 在脚本中常见的与输入法相关的操作代码: 一楼
  2. 在一楼代码中可能需要替换的常量值: 请参阅二楼
  3. 示例一: 切换脚本的 GUI 窗口输入法到半角状态: 请参阅三楼
  4. 示例二: 切换脚本 GUI 窗口的输入法为半角和英文标点状态: 请参阅四楼
参考: 目的: 对在程序中切换输入法一些常用操作进行小结.
注意: 下列对输入法状态切换的方法可能失效, 此时请检查是否满足以下条件
  1. 安装东亚语言支持
  2. 某些模式只有一些语言的输入法才支持 (例如日语或朝鲜语)
  3. 有些模式需要输入法内部支持 (例如在"简体中文-美式键盘"时切换全半角会没有效果)
键盘布局 (keyboard layout), 或输入区域标识符 (input locale identifier), 这里都特指输入法
关于输入法, 常见的需要实现的几种操作:
  1. 获取/设置当前系统中默认输入法
  2. 获取指定窗口首个线程当前输入法
  3. 获取系统中已安装输入法列表
  4. 获取/设置脚本 GUI 窗口当前输入法及输入法的各种状态
  5. 获取和设置其他窗口的输入法 (似乎无法获取和设置状态, 使用模拟热键或许可以设置, 请参阅五楼)
注:第 4 点中介绍的几个函数均只在对脚本自己的 GUI 窗口才有效。

1. 获取/设置当前系统中默认输入法
从注册表读取系统默认输入法
代码: (全选)
RegRead, SysDefaultIM, HKCU, Keyboard Layout\Preload, 1

2. 获取指定窗口首个线程当前输入法

代码: (全选)
;~ 参考 GetKeyboardLayout function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646296
HKL := DllCall("GetKeyboardLayout", "UInt", 0, "UInt")  ; 获取脚本当前输入法
HKL := DllCall("GetKeyboardLayout","UInt", DllCall("GetWindowThreadProcessId","UInt", hWnd, "UIntp", 0),UInt)

3. 获取系统中已安装输入法列表和当前用户已启用的输入法

代码: (全选)
;~ 从注册表读取已安装的所有输入法, 位置 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts
;~ 从中可以提取已安装的简体中文输入法 (以0804为结尾的输入法), 如果需要提示用户则提取其中的Layout Text进行提示
;~ 查看当前用户已启用的输入法, 位置 HKCU\Keyboard Layout\Preload
获取输入区域标识符列表, 输入区域标识符含义广泛, 包括 speech-to-text converter, Input Method Editor (IME) 和其他任何的输入形式.
代码: (全选)
;~ 参考 GetKeyboardLayoutList function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646297

HKLNum := DllCall("GetKeyboardLayoutList", "UInt", 0, "UInt", 0)  
VarSetCapacity(HKLList, HKLNum*4, 0)
DllCall("GetKeyboardLayoutList", "UInt", HKLNum, "UInt", &HKLList)
loop, %HKLNum%
{
   HKL%A_Index% := NumGet(HKLList, (A_Index-1)*4 )
}
4. 获取/设置脚本自身 GUI 窗口当前输入法及输入法的各种状态
获取当前活动的输入法的 ID
代码: (全选)
;~ 参考 GetKeyboardLayoutName function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646298
VarSetCapacity(pwszKLID, 1)
DllCall("GetKeyboardLayoutName", "Ptr", &pwszKLID, "Int")
VarSetCapacity(pwszKLID, -1)
为脚本当前线程载入并激活某种已安装的键盘布局 (输入法) (由于 AutoHotkey 中没有真正的多线程, 所以实际上是为整个脚本激活输入法)
代码: (全选)
;~ 参考 LoadKeyboardLayout Function: http://msdn.microsoft.com/en-us/library/ms646305
DllCall("LoadKeyboardLayout", "Str", "E0260804", "UInt", 1)
ImmSimulateHotKey (对于简体中文) 可以实现这三种功能: 输入法/非输入法切换 (Ctrl+Space 的效果); 全/半角切换 (Shift+Space 的效果); 中英标点切换(Ctrl+PERIOD 的效果).
代码: (全选)
;~ 参考 ImmSimulateHotKey function: http://msdn.microsoft.com/en-us/library/dd318589
DllCall("Imm32.dll\ImmSimulateHotKey", "UInt", hWnd, "UInt", IME_CHOTKEY_IME_NONIME_TOGGLE)
获取输入上下文, 在访问上下文的信息前必须打开当前输入上下文.
代码: (全选)
;~ 参考 ImmGetContext function: http://msdn.microsoft.com/en-us/library/dd318558
hIMC := DllCall("Imm32.dll\ImmGetContext", "UInt", hWnd, "UInt")
判断输入法打开状态
代码: (全选)
;~ 参考 ImmGetOpenStatus function: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318566
DllCall("Imm32.dll\ImmGetOpenStatus", "UInt", hIMC, "Int")
获取输入法的转换信息 (其实是各种状态, 例如全角半角)
代码: (全选)
;~ ImmGetConversionStatus function: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318560
iMode := 0
iSentence := 0
DllCall("Imm32.dll\ImmGetConversionStatus", "UInt", hIMC, "UintP", iMode, "UintP", iSentence, "Int")
设置输入法的打开状态
代码: (全选)
;~ 参考 ImmSetOpenStatus function: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318586
DllCall("Imm32.dll\ImmSetOpenStatus", "UInt", hIMC, "Int", true, "Int")
ImmSetConversionStatus 可以设置输入法的各种状态 (首先系统必须安装东亚语言支持, 同时需设置的输入法必须支持 (不同状态的切换), 接着打开输入法, 这样才有效果)
代码: (全选)
;~ 参考 ImmSetConversionStatus function: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318584
DllCall("Imm32.dll\ImmSetConversionStatus", "UInt", hIMC, "UInt", iMode, "UInt", iSentence, "Int")
释放输入上下文, 每次调用 ImmGetContext 后都必须使用此函数释放句柄和相应的内存
代码: (全选)
;~ 参考 ImmReleaseContext function: http://msdn.microsoft.com/en-us/library/dd318576
DllCall("Imm32.dll\ImmReleaseContext", "UInt", hWnd, "UInt", hIMC)
5. 获取和设置其他窗口的输入法
设置指定窗口 (或对话框) 的输入法, 如果切换到没有安装的输入法那么会出现新键盘布局, 例如
代码: (全选)
;~ 参考: WM_INPUTLANGCHANGEREQUEST Message: http://msdn.microsoft.com/en-us/library/ms632630
;~ PostMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0x04090409,, ahk_id %hWnd%  ;切换为美国英语 (会添加一个键盘布局)
;~ PostMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0x08040804,, ahk_id %hWnd%  ;切换到简体中文 (美式键盘)
;~ PostMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0x0, %Control%, ahk_id %hWnd% ; 在所有语言和布局间逐个切换
代码: (全选)
;切换到简体中文 (美式键盘), 此方法只在一些情况下有效
PostMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0x08040804,, ahk_id %hWnd%
代码: (全选)
; 这种方法可以在对话框或活动窗口正运行的线程不是当前线程时有效, 建议使用
ControlGetFocus, Ctrl, ahk_id %hWnd%
SendMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0x08040804, %Ctrl%, ahk_id %hWnd%

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢amnesiac
2011-10-30, 16 : 44
 
在上面的代码中使用到一些常量, 这些值可以在相应的头文件中找到:
代码: (全选)
IME_CMODE_ALPHANUMERIC          0x0000
IME_CMODE_NATIVE                0x0001
IME_CMODE_CHINESE               IME_CMODE_NATIVE
/* IME_CMODE_HANGEUL is old name of IME_CMODE_HANGUL. It will be gone eventually. */
IME_CMODE_HANGEUL               IME_CMODE_NATIVE
IME_CMODE_HANGUL                IME_CMODE_NATIVE
IME_CMODE_JAPANESE              IME_CMODE_NATIVE
IME_CMODE_KATAKANA              0x0002  /* only effect under IME_CMODE_NATIVE */
IME_CMODE_LANGUAGE              0x0003
IME_CMODE_FULLSHAPE             0x0008
IME_CMODE_ROMAN                 0x0010
IME_CMODE_CHARCODE              0x0020
IME_CMODE_HANJACONVERT          0x0040
IME_CMODE_SOFTKBD               0x0080
IME_CMODE_NOCONVERSION          0x0100
IME_CMODE_EUDC                  0x0200
IME_CMODE_SYMBOL                0x0400
IME_CMODE_FIXED                 0x0800


IME_SMODE_NONE                  0x0000
IME_SMODE_PLAURALCLAUSE         0x0001
IME_SMODE_SINGLECONVERT         0x0002
IME_SMODE_AUTOMATIC             0x0004
IME_SMODE_PHRASEPREDICT         0x0008
IME_SMODE_CONVERSATION          0x0010

/* Windows for Simplified Chinese Edition hot key ID from 0x10 - 0x2F */
IME_CHOTKEY_IME_NONIME_TOGGLE           0x10
IME_CHOTKEY_SHAPE_TOGGLE                0x11
IME_CHOTKEY_SYMBOL_TOGGLE               0x12

WM_INPUTLANGCHANGEREQUEST            0x50
WM_INPUTLANGCHANGE                           0x51

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢amnesiac
2011-10-30, 17 : 01
 
示例一: 切换脚本的 GUI 窗口输入法到半角状态 (前面说明的较详细, 这里的代码不再解释):
代码: (全选)
; hWnd 为脚本 GUI 窗口的句柄
IME_CMODE_FULLSHAPE := 0x8
IME_CHOTKEY_SHAPE_TOGGLE := 0x11

hIMC := DllCall("Imm32.dll\ImmGetContext", "UInt", hWnd, "UInt")
if (DllCall("Imm32.dll\ImmGetOpenStatus", "UInt", hIMC, "Int"))
{  
   iMode := 0
   iSentence := 0
   if DllCall("Imm32.dll\ImmGetConversionStatus", "UInt", hIMC, "UIntP", iMode, "UIntP", iSentence, "Int")
   {  
      if ((iMode & IME_CMODE_FULLSHAPE) > 0)          ; 判断是否为全角状态
            DllCall("Imm32.dll\ImmSimulateHotKey", "UInt", hWnd, "UInt", IME_CHOTKEY_SHAPE_TOGGLE, "Int")
   }  
}
DllCall("Imm32.dll\ImmReleaseContext", "UInt", hWnd, "UInt", hIMC)

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢amnesiac
2011-10-30, 17 : 36
 
示例二: 切换脚本 GUI 窗口的输入法为半角和英文标点状态
代码: (全选)
; hWnd 为脚本 GUI 窗口的句柄
IME_CMODE_FULLSHAPE := 0x8
IME_CMODE_SYMBOL := 0x0400

hIMC := DllCall("Imm32.dll\ImmGetContext", "UInt", hWnd, "UInt")
if (DllCall("Imm32.dll\ImmGetOpenStatus", "UInt", hIMC, "Int"))
{  
   iMode := 0
   iSentence := 0
   if DllCall("Imm32.dll\ImmGetConversionStatus", "UInt", hIMC, "UIntP", iMode, "UIntP", iSentence, "Int")
   {  
        if (iMode & IME_CMODE_FULLSHAPE)    ; 判断是否为全角状态, 若等于零则为半角
        {
            iMode &= ~IME_CMODE_FULLSHAPE    ; 设置为半角
            ;~ 若在半角时要设置为全角则 iMode |= IME_CMODE_FULLSHAPE
        }
        if (iMode & IME_CMODE_SYMBOL)    ; 判断是否为中文标点
        {
            iMode &= ~IME_CMODE_SYMBOL    ; 设置为英文标点
            ;~ 若在英文标点时要设置为中文标点则 iMode |= IME_CMODE_SYMBOL
        }
        DllCall("Imm32.dll\ImmSetConversionStatus", "UInt", hIMC, "UInt", iMode, "UInt", iSentence, "Int")
   }  
}
DllCall("Imm32.dll\ImmReleaseContext", "UInt", hWnd, "UInt", hIMC)
前一个例子使用了 ImmSimulateHotKey, 而这个例子使用 ImmSetConversionStatus 函数, 后面这个函数可以设置更多状态, 其中一些需要相应支持.

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢amnesiac
2012-01-10, 14 : 12
 
一些注意点:
1. 美式键盘的语言代码
00000409: 这个是"英语(美国) 美式键盘", 安装这个后在输入法提示栏中会多出英语的输入语言, 一般不安装这个.
00000804: 这个是"中文(中国) 简体中文-美式键盘", 在简体系统中一般都有安装这个.
进行切换时上面两者都不能直接使用注册表中的数字标识符(其他e开始的可以), 对于00000409在切换时使用04090409, 而00000804则使用08040804.

2. 尽管上面的切换方法基本包括了常见的情况, 然而也许某些时候您希望使用模拟热键切换 (例如切换其他程序中的输入法全/半角状态). 默认的 Ctrl+Shift (在不同的输入语言之间切换), Ctrl+Space (输入法/非输入法切换), Shift+Space (全角/半角切换), Ctrl+PERIOD (中/英标点切换). 此时需要先判断当前系统中是否禁用或重新设置了热键, 主要是这个子键: HKEY_CURRENT_USER\Keyboard Layout\Toggle
(里面数字的含义留给需要的人测试了)

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 1用户表示感谢amnesiac
2012-02-13, 20 : 19
 
很需要,感谢LZ.
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-03-02, 15 : 24 (这个帖子最后修改于: 2014-08-12 22 : 45 by robertL.)
 
Thanks for your sharing,and I make some change for convenience:
代码: (全选)
GetLayout(win_id){
    ;win_id should be a HWND witch could get from something like this:
    ;WinGet, win_id, ID, ahk_pid %PID%
    Try {
    keyboard_layout := DllCall("GetKeyboardLayout","UInt", DllCall("GetWindowThreadProcessId","UInt", win_id, "UIntp", 0),UInt)
    SetFormat, integer, hex
    keyboard_layout += 0  
    SetFormat, integer, D
    keyboard_layout = %keyboard_layout%
    StringTrimLeft, keyboard_layout, keyboard_layout, 2   ;; Remove the Leading "0x"
    Return keyboard_layout
    } catch e {
        Throw Exception("Bad_WinID",-1)
    }
}

SetLayout(keyboard_layout, win_id){
    ;win_id should be a HWND witch could get from something like this:
    ;WinGet, win_id, ID, ahk_pid %PID%
    ;keyboard_layout should be something like "E0210804"
    ;or return from GetLayout(win_id)
    Try {
        DllCall("SendMessage", "UInt", win_id, "UInt", "80", "UInt", "1", "UInt", (DllCall("LoadKeyboardLayout", "Str", keyboard_layout, "UInt", "257")))
    } Catch e {
        Throw Exception("Error_Setting_Layout",-1)
    }
}
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-06-09, 23 : 31
 
请教 ImmGetConversionStatus的具体用法, 希望楼主指点,先谢谢了
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-06-10, 10 : 41
 
8# njhank

在一楼、三楼和四楼都有这个函数的使用示例,看不明白还是自己执行失败?最好把你执行失败的脚本和出现的错误一起发上来。

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-06-10, 21 : 42 (这个帖子最后修改于: 2015-08-21 21 : 43 by robertL.)
 
9# amnesiac

谢谢你,
没有错误,就是执行了没有反应。
代码: (全选)
WinGet, hWnd, ID, A
hIMC := DllCall("Imm32.dll\ImmGetContext", "UInt", hWnd, "UInt")
if (DllCall("Imm32.dll\ImmGetOpenStatus", "UInt", hIMC, "Int"))
{


我加了第一句获取句柄,第二句执行得hIMC的值为0,第3句if的判断条件都为false。不知道问题出现在哪里。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-07-13, 13 : 13
 
1# amnesiac
njhank 相同的问题,同求解决
最好能有个获取切换比如QQ输入法的中英文状态的示例
多谢管理员了
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-08-07, 15 : 35 (这个帖子最后修改于: 2015-08-21 21 : 45 by robertL.)
 
抱歉,现在才回复。
引用: 9# amnesiac

谢谢你,
没有错误,就是执行了没有反应。
WinGet, hWnd, ID, A
hIMC := DllCall("Imm32.dll\ImmGetContext", "UInt", hWnd, "UInt")
if (DllCall("Imm32.dll\ImmGetOpenStatus", "UInt", hIMC ...
njhank 发表于 2012-6-10 21:42[/url]
一楼第 4 点中介绍的几个函数只对脚本自己的 GUI 窗口才有效。
引用: 1# amnesiac
最好能有个获取切换比如QQ输入法的中英文状态的示例
多谢管理员了
ginneylover 发表于 2012-7-13 13:13
请参阅四楼的脚本进行适当调整。另外,切换中英文状态仅对脚本自己的 GUI 窗口有效。

AutoHotkey 学习指南 我的帖子
我不生产代码,我只是 AutoHotkey 的搬运工:从官方到中文;从其他语言到 AutoHotkey;有时则把 AutoHotkey 搬运到普通用户面前。
访问这个用户的网站 查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-05-27, 15 : 14 (这个帖子最后修改于: 2015-08-21 21 : 46 by robertL.)
RE: 输入法切换方法不完全小结
在这里挖坟应该没事吧。。
为什么切换输入法的代码无论是

代码: (全选)
ControlGetFocus, Ctrl, ahk_id %hWnd%
SendMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0xE0200804, %Ctrl%, ahk_id %hWnd%
还是
代码: (全选)
PostMessage, WM_INPUTLANGCHANGEREQUEST, 0, 0xE0200804, ahk_id %hWnd%
都没用0.0
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-05-28, 08 : 20 (这个帖子最后修改于: 2014-06-03 21 : 25 by robertL.)
RE: 输入法切换方法不完全小结
参考QA的问答还是关于输入法的问题(其中分享了个关于输入法的资源——一个AHK库)(很完善,良好封装的库)

One for all, but man for himself

帮推广:AHK知乎专栏
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-06-10, 20 : 59 (这个帖子最后修改于: 2014-06-10 21 : 00 by 兔子.)
RE: 输入法切换方法不完全小结
(2014-05-28 08 : 20)robertL 提到:  参考QA的问答还是关于输入法的问题(其中分享了个关于输入法的资源——一个AHK库)(很完善,良好封装的库)

补充说明,萝卜没说出最重点的地方,那就是使用这个日本友人的库,可以获取外部输入法的状态!!!

下载地址:
http://www6.atwiki.jp/_pub/eamat/MyScrip...121110.zip

下载后直接运行,可以看见演示!
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢兔子
2014-07-15, 02 : 32
RE: 输入法切换方法不完全小结
请问, 我想使用顶楼的某个语句达到window 8.1中 win+space的效果, 我不想使用模拟按键, 想使用api的方式, 请高手们指教一下. 谢谢.
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2014-07-17, 11 : 42
RE: 输入法切换方法不完全小结
(2014-07-15 02 : 32)anyone 提到:  请问, 我想使用顶楼的某个语句达到window 8.1中 win+space的效果, 我不想使用模拟按键, 想使用api的方式, 请高手们指教一下. 谢谢.

你楼上的那个库完美解决输入法状态的获取设置等等问题。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
[+] 2用户表示感谢兔子
2014-10-15, 19 : 47
RE: 输入法切换方法不完全小结
我想在程序开始的时候就默认英文输入法,
没有看懂怎么用的。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2015-08-21, 21 : 48 (这个帖子最后修改于: 2015-08-23 12 : 28 by robertL.)
RE: 输入法切换方法不完全小结
(2014-10-15 19 : 47)wangwenke448 提到:  我想在程序开始的时候就默认英文输入法,
没有看懂怎么用的。
输入法里可以设置默认模式如,英文,每个新启动的程序都会从这个模式开始。

我的《输入法 相关 学习 汇总》

One for all, but man for himself

帮推广:AHK知乎专栏
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2015-08-23, 22 : 01 (这个帖子最后修改于: 2015-11-14 18 : 56 by robertL.)
Smile 小结 V1.5
兔子 提到:补充说明,萝卜没说出最重点的地方,那就是使用这个日本友人的库,可以获取外部输入法的状态!!!
@兔子
学习了那个输入法库,记录下:
  • ImmGetDefaultIMEWnd。获取指定窗口的输入上下文(IME句柄)。
    可向IME句柄发送消息,以访问。消息类型有:WM_IME_CONTROL,此类型的消息参数有:
  • 输入窗体(概念上分,输入窗候选窗)对应IME实例对应的进程(IME中讲应该是线程,见下)
  • GetGUIThreadInfo:获取线程的信息。其中:
    • 线程可以是当前激活|前台窗口(默认),或,指定的线程。
    • 信息,对应GUITHREADINFO结构,包含:线程状态(光标输入、菜单、移动、弹出菜单、系统菜单)、激活窗口、具有键盘焦点的窗口、正捕获鼠标的窗口、拥有激活菜单的窗口、正移动或缩放的窗口、正显示光标的窗口、​光标位置
      此处用到激活窗口,见下。
    • 其中,光标位置参见请教,取插入符位置问题 @feiyue
  • 关于获取激活窗口的句柄的特别方法
    代码: (全选)
    GethWND(WinTitle){
        ControlGet,hwnd,HWND,,,%WinTitle%
        if  (WinActive(WinTitle))   {
            ptrSize := !A_PtrSize ? 4 : A_PtrSize
            VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
            NumPut(cbSize, stGTI,  0, "UInt")  ;   DWORD   cbSize;
            hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                     ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
                    ;8+PtrSize对应线程中的激活的窗口。
        }
        return hwnd
    }
    原先|常规的做法是通过MouseGetPos获取鼠标所在的控件的句柄。
    此处,对指定目标的句柄(上述鼠标所在的控件的句柄),如果目标激活|处于前台,则重新从系统中获取前台|激活窗口的句柄。
    因为输入法只有一个处于前台|激活窗口的实例。
相关:

One for all, but man for himself

帮推广:AHK知乎专栏
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
发表回复 


论坛跳转:


联系我们 | Autohotkey 中文站 | 回到顶部 | 回到正文区 | 精简(归档)模式 | RSS 聚合