我在其他几个issues里看到有人在讨论,如何用代码控制输入法状态的问题。然后去做了一点功课,发现WM_IME_CONTROL消息可以实现该功能,但是小狼毫似乎没有正确处理该消息。
在Widnows平台上,可以用ImmGetDefaultIMEWnd获得输入法句柄,然后通过向该句柄发送WM_IME_CONTROL消息的方式,获得和控制输入法的状态(切换中英文输入状态,全角半角切换等)。
以下是用python写的完整示例:
import win32more.Windows.Win32.UI.WindowsAndMessaging as wm
import win32more.Windows.Win32.UI.Input.Ime as ime
IMC_GETCONVERSIONMODE = 1
IMC_SETCONVERSIONMODE = 2
IMC_GETOPENSTATUS = 5
hwnd = wm.GetForegroundWindow()
himc = ime.ImmGetDefaultIMEWnd(hwnd)
ret = wm.SendMessage(himc, wm.WM_IME_CONTROL, IMC_GETOPENSTATUS, 0)
print('open:', ret)
ret = wm.SendMessage(himc, wm.WM_IME_CONTROL, IMC_GETCONVERSIONMODE, 0)
print('conv:', ret)
print('\tNATIVE', (ret & ime.IME_CMODE_NATIVE))
print('\tKATAKANA', (ret & ime.IME_CMODE_KATAKANA))
print('\tLANGUAGE', (ret & ime.IME_CMODE_LANGUAGE))
print('\tFULLSHAPE', (ret & ime.IME_CMODE_FULLSHAPE))
print('\tROMAN', (ret & ime.IME_CMODE_ROMAN))
print('\tCHARCODE', (ret & ime.IME_CMODE_CHARCODE))
print('\tHANJACONVERT', (ret & ime.IME_CMODE_HANJACONVERT))
print('\tSOFTKBD', (ret & ime.IME_CMODE_SOFTKBD))
print('\tNOCONVERSION', (ret & ime.IME_CMODE_NOCONVERSION))
print('\tEUDC', (ret & ime.IME_CMODE_EUDC))
print('\tSYMBOL', (ret & ime.IME_CMODE_SYMBOL))
print('\tFIXED', (ret & ime.IME_CMODE_FIXED))
#ret = wm.SendMessage(himc, wm.WM_IME_CONTROL, IMC_SETCONVERSIONMODE, ime.IME_CMODE_ALPHANUMERIC)
#ret = wm.SendMessage(himc, wm.WM_IME_CONTROL, IMC_SETCONVERSIONMODE, ime.IME_CMODE_NATIVE)
下面这些定义Windows SDK里似乎没有,不过相关功能好像一直都可以用。
IMC_GETCONVERSIONMODE = 1
IMC_SETCONVERSIONMODE = 2
IMC_GETOPENSTATUS = 5
因为没有找到准确的文档,所以我就对比了一下微软拼音和小狼毫的返回值。
ret = wm.SendMessage(himc, wm.WM_IME_CONTROL, IMC_GETOPENSTATUS, 0)
print('open:', ret)
微软拼音中不管输入模式是中文还是英文,IMC_GETOPENSTATUS的返回值都是1。
小狼毫打开ascii_mode时返回1,没有问题。但是中文输入模式返回0,这里应该不太对。
open: 1
conv: 1033
NATIVE 1
KATAKANA 0
LANGUAGE 1
FULLSHAPE 8
ROMAN 0
CHARCODE 0
HANJACONVERT 0
SOFTKBD 0
NOCONVERSION 0
EUDC 0
SYMBOL 1024
FIXED 0
后面的部分微软拼音的返回值大概是上面这样,猜测各值的意义是:
- IME_CMODE_NATIVE:中文输入模式
- IME_CMODE_LANGUAGE: 未知
- IME_CMODE_FULLSHAPE: 全半角模式
- IME_CMODE_SYMBOL: 中英文标点
经过测试,可以通过组合上面各值的方式改变微软拼音的状态。
如果只是想切换中英文输入模式,可以直接单独发送IME_CMODE_NATIVE,可以成功切到中文输入状态,跟按Ctrl+Space的效果一样。
如果能提供WM_IME_CONTROL的相关支持,应该就能兼容市面上不少控制输入法状态的第三方工具了。只是不知道是不是还会出现某些方案没有“全角半角”和“中英文标点”的情况。
我在其他几个issues里看到有人在讨论,如何用代码控制输入法状态的问题。然后去做了一点功课,发现
WM_IME_CONTROL消息可以实现该功能,但是小狼毫似乎没有正确处理该消息。在Widnows平台上,可以用
ImmGetDefaultIMEWnd获得输入法句柄,然后通过向该句柄发送WM_IME_CONTROL消息的方式,获得和控制输入法的状态(切换中英文输入状态,全角半角切换等)。以下是用python写的完整示例:
下面这些定义Windows SDK里似乎没有,不过相关功能好像一直都可以用。
因为没有找到准确的文档,所以我就对比了一下微软拼音和小狼毫的返回值。
微软拼音中不管输入模式是中文还是英文,
IMC_GETOPENSTATUS的返回值都是1。小狼毫打开
ascii_mode时返回1,没有问题。但是中文输入模式返回0,这里应该不太对。后面的部分微软拼音的返回值大概是上面这样,猜测各值的意义是:
经过测试,可以通过组合上面各值的方式改变微软拼音的状态。
如果只是想切换中英文输入模式,可以直接单独发送
IME_CMODE_NATIVE,可以成功切到中文输入状态,跟按Ctrl+Space的效果一样。如果能提供
WM_IME_CONTROL的相关支持,应该就能兼容市面上不少控制输入法状态的第三方工具了。只是不知道是不是还会出现某些方案没有“全角半角”和“中英文标点”的情况。