Skip to content

小狼毫未能正确处理WM_IME_CONTROL相关消息 #1371

Description

@oTnTh

我在其他几个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的相关支持,应该就能兼容市面上不少控制输入法状态的第三方工具了。只是不知道是不是还会出现某些方案没有“全角半角”和“中英文标点”的情况。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions