英文:
ImmNotifyIME failed while some IMM functions like ImmGetContext works well
问题
我正在使用Windows 10上的IME组合编写程序。
该程序使用DefWindowProc
来处理特定线程中的所有WM_IME_
消息,并在另一个线程中检查IMM上下文。
当我想要更改输入法的位置时,以下代码运行良好:
HWND idefhwnd = fpImmGetDefaultIMEWnd(hwnd);
::SendMessageW(idefhwnd, WM_IME_CONTROL, IMC_SETCOMPOSITIONWINDOW,
reinterpret_cast<LPARAM>(reinterpret_cast<void*>(&cpf)));
而以下代码失败了:
HIMC hImc = fpImmGetContext(hwnd);
fpImmSetCompositionWindow(hImc, &cpf);
fpImmReleaseContext(hwnd, hImc);
我想知道是什么情况导致了fpImmNotifyIME
失败,或者是否有其他方法可以暂时使候选框不可见。谢谢。
Details:
为了与旧编译器兼容,我使用了以下方式的dll:
hModImm32 = ::GetModuleHandleW(L"Imm32.dll");
fun = ::GetProcAddress(hModImm32, funcname);
某些IMM函数工作正常。我使用ImmAssociateContextEx
来暂时禁用IME。它运行良好。
using iace_t = decltype(ImmAssociateContextEx);
iace_t* fpImmAssociateContextEx = mcl_get_immfunc<iace_t>("ImmAssociateContextEx");
if (!fpImmAssociateContextEx) return false;
fpImmAssociateContextEx(hwnd, NULL, IACE_CHILDREN);
但我发现这不能在输入时关闭候选框。因此,在调用fpImmAssociateContextEx
之前,我尝试使用以下代码通知输入法在禁用它之前关闭窗口(就像https://stackoverflow.com/questions/70108591/how-to-hide-the-input-method-editor/70111565中的操作一样)。
HIMC himc = fpImmGetContext(hwnd); // himc != nullptr
fpImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
fpImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
所有的fpImmNotifyIME
都返回了FALSE
,并且没有做任何事情。
英文:
I'm writing a program using IME composition on Windows 10.
The program uses DefWindowProc
to handle all WM_IME_
message in a specific thread and check IMM context in another thread.
When I want to change the position of input method, the following code works well:
HWND idefhwnd = fpImmGetDefaultIMEWnd (hwnd);
::SendMessageW (idefhwnd, WM_IME_CONTROL, IMC_SETCOMPOSITIONWINDOW,
reinterpret_cast<LPARAM>(reinterpret_cast<void*>(&cpf)));
While following code failed:
HIMC hImc = fpImmGetContext (hwnd);
fpImmSetCompositionWindow (hImc, &cpf);
fpImmReleaseContext (hwnd, hImc);
I want to know what situation caused fpImmNotifyIME
to fail or is there any other way to temporarily make the candidate box invisible. Thanks.
Details:
To be compatible with old compiler, I use dll as follow:
hModImm32 = ::GetModuleHandleW (L"Imm32.dll");
fun = ::GetProcAddress (hModImm32, funcname);
Some imm functions are working properly. I used ImmAssociateContextEx
to disable IME temporarily. It works well.
using iace_t = decltype(ImmAssociateContextEx);
iace_t* fpImmAssociateContextEx = mcl_get_immfunc<iace_t>("ImmAssociateContextEx");
if (!fpImmAssociateContextEx) return false;
fpImmAssociateContextEx (hwnd, NULL, IACE_CHILDREN);
But I found out that this cannot close the candidate box when typing. So I'm trying to notify input method to close window when disabling it with following code before fpImmAssociateContextEx
is called. (just as https://stackoverflow.com/questions/70108591/how-to-hide-the-input-method-editor/70111565)
HIMC himc = fpImmGetContext (hwnd); // himc != nullptr
fpImmNotifyIME ( himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0 );
fpImmNotifyIME ( himc, NI_CLOSECANDIDATE, 0, 0 );
All fpImmNotifyIME
returned FALSE
and did nothing.
答案1
得分: 0
问题出在**'程序在一个特定的线程处理消息并在另一个线程中检查IMM上下文。'** ImmNotifyIME()
和 ImmSetCompositionWindow()
默认使用调用这些函数的线程的 HWND
。解决方法是通过 SendMessage()
通知负责处理消息循环的线程来调用这些函数。
英文:
The problem lies in 'The program handles message in a specific thread and check IMM context in another thread.' ImmNotifyIME()
and ImmSetCompositionWindow()
default to using the HWND
of the thread calling the functions. The solution is to call these functions by notifying the thread responsible for processing the message loop through SendMessage()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论