diff --git a/src/Key/KeyHandler.cpp b/src/Key/KeyHandler.cpp index 466d2aba..243ef214 100644 --- a/src/Key/KeyHandler.cpp +++ b/src/Key/KeyHandler.cpp @@ -13,6 +13,11 @@ #include "Ipc.h" #include "FanyDefines.h" +namespace +{ +std::wstring g_toggleImeFallbackBuffer; +} + ////////////////////////////////////////////////////////////////////// // // CMetasequoiaIME class @@ -80,6 +85,7 @@ VOID CMetasequoiaIME::_DeleteCandidateList(BOOL isForce, _In_opt_ ITfContext *pC HRESULT CMetasequoiaIME::_HandleComplete(TfEditCookie ec, _In_ ITfContext *pContext) { + g_toggleImeFallbackBuffer.clear(); _DeleteCandidateList(FALSE, pContext); // just terminate the composition @@ -96,6 +102,7 @@ HRESULT CMetasequoiaIME::_HandleComplete(TfEditCookie ec, _In_ ITfContext *pCont HRESULT CMetasequoiaIME::_HandleCancel(TfEditCookie ec, _In_ ITfContext *pContext) { + g_toggleImeFallbackBuffer.clear(); GlobalIme::word_for_creating_word = L""; _RemoveDummyCompositionForComposing(ec, _pComposition); @@ -109,17 +116,36 @@ HRESULT CMetasequoiaIME::_HandleCancel(TfEditCookie ec, _In_ ITfContext *pContex HRESULT CMetasequoiaIME::_HandleToogleIMEMode(TfEditCookie ec, _In_ ITfContext *pContext) { CStringRange keyStrokebuffer = _pCompositionProcessorEngine->GetKeystrokeBuffer(); + std::wstring commitString; + + _RemoveDummyCompositionForComposing(ec, _pComposition); if (keyStrokebuffer.GetLength()) { - std::wstring keyStrokeString(keyStrokebuffer.Get(), keyStrokebuffer.GetLength()); - FanyUtils::SendKeys(keyStrokeString); + commitString.assign(keyStrokebuffer.Get(), keyStrokebuffer.GetLength()); + CStringRange commitStringRange; + commitStringRange.Set(commitString.c_str(), commitString.length()); + OutputDebugString(fmt::format(L"commitString: {}", commitString).c_str()); + + HRESULT hr = _AddCharAndFinalize(ec, pContext, &commitStringRange); + if (FAILED(hr)) + { + FanyUtils::SendKeys(commitString); + } + } + else if (!g_toggleImeFallbackBuffer.empty()) + { + commitString = g_toggleImeFallbackBuffer; + // 实测这个在管理员窗口也是可以正常运行的 + FanyUtils::SendKeys(commitString); } - _RemoveDummyCompositionForComposing(ec, _pComposition); - _DeleteCandidateList(FALSE, pContext); + g_toggleImeFallbackBuffer.clear(); + // _DeleteCandidateList(FALSE, pContext); _TerminateComposition(ec, pContext); + // _HandleComplete(ec, pContext); + // CCompositionProcessorEngine *pCompositionProcessorEngine; // pCompositionProcessorEngine = _pCompositionProcessorEngine; @@ -181,6 +207,7 @@ HRESULT CMetasequoiaIME::_HandleCompositionInput(TfEditCookie ec, _In_ ITfContex #endif // Add virtual key to composition processor engine pCompositionProcessorEngine->AddVirtualKey(wch); + g_toggleImeFallbackBuffer.push_back(wch); _HandleCompositionInputWorker(pCompositionProcessorEngine, ec, pContext); @@ -532,6 +559,11 @@ HRESULT CMetasequoiaIME::_HandleCompositionBackspace(TfEditCookie ec, _In_ ITfCo DWORD_PTR vKeyLen = pCompositionProcessorEngine->GetVirtualKeyLength(); + if (!g_toggleImeFallbackBuffer.empty()) + { + g_toggleImeFallbackBuffer.pop_back(); + } + if (vKeyLen) { pCompositionProcessorEngine->RemoveVirtualKey(vKeyLen - 1); diff --git a/src/Utils/FanyUtils.cpp b/src/Utils/FanyUtils.cpp index 8e8c46c1..ecc7e812 100644 --- a/src/Utils/FanyUtils.cpp +++ b/src/Utils/FanyUtils.cpp @@ -3,6 +3,7 @@ #include "Globals.h" #include "FanyUtils.h" #include +#include using namespace std; @@ -15,34 +16,24 @@ std::string GetIMEDataDirPath() return IMEDataPath; } -void SendUnicode(const wchar_t data) -{ - INPUT input[4]; - HWND current_hwnd = GetForegroundWindow(); - SetFocus(current_hwnd); - - input[0].type = INPUT_KEYBOARD; - input[0].ki.wVk = 0; - input[0].ki.wScan = data; - input[0].ki.dwFlags = KEYEVENTF_UNICODE; - input[0].ki.time = 0; - input[0].ki.dwExtraInfo = GetMessageExtraInfo(); - SendInput(1, &input[0], sizeof(INPUT)); - - input[1].type = INPUT_KEYBOARD; - input[1].ki.wVk = 0; - input[1].ki.wScan = data; - input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; - input[1].ki.time = 0; - input[1].ki.dwExtraInfo = GetMessageExtraInfo(); - SendInput(1, &input[1], sizeof(INPUT)); -} - void SendKeys(std::wstring pinyin) { for (wchar_t ch : pinyin) { - SendUnicode(ch); + INPUT in[2]{}; + + in[0].type = INPUT_KEYBOARD; + in[0].ki.wScan = ch; + in[0].ki.dwFlags = KEYEVENTF_UNICODE; + + in[1] = in[0]; + in[1].ki.dwFlags |= KEYEVENTF_KEYUP; + + UINT sent = SendInput(2, in, sizeof(INPUT)); + if (sent != 2) + { + OutputDebugString(fmt::format(L"SendKeys failed.\n").c_str()); + } } }