Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
oTnTh opened this issue Sep 23, 2024 · 1 comment
Open

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

oTnTh opened this issue Sep 23, 2024 · 1 comment

Comments

@oTnTh
Copy link

oTnTh commented Sep 23, 2024

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

@hoodlum1980
Copy link

hoodlum1980 commented Oct 11, 2024

这是我对某个“文字输入”窗口 (hWndTarget)关闭“中文输入法”的代码(也就是切换到英文输入状态),对应的输入法应该是系统自带的微软拼音输入法,供参考~。~

HWND hCurWnd = ImmGetDefaultIMEWnd(hWndTarget);
if(SendMessage(hCurWnd, WM_IME_CONTROL, IMC_GETOPENSTATUS, 0))
{
	SendMessage(hCurWnd, WM_IME_CONTROL, IMC_SETOPENSTATUS, 0);
	// 已经切换到英文输入法。
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants