LRESULT WeaselIME::_OnIMENotify(LPINPUTCONTEXT lpIMC, WPARAM wp, LPARAM lp) { switch (wp) { case IMN_OPENCANDIDATE: { EZDBGONLYLOGGERPRINT("IMN_OPENCANDIDATE: HIMC = 0x%x", m_hIMC); if (m_preferCandidatePos) _SetCandidatePos(lpIMC); else _SetCompositionWindow(lpIMC); } break; case IMN_SETCANDIDATEPOS: { EZDBGONLYLOGGERPRINT("IMN_SETCANDIDATEPOS: HIMC = 0x%x", m_hIMC); _SetCandidatePos(lpIMC); } break; case IMN_SETCOMPOSITIONWINDOW: { EZDBGONLYLOGGERPRINT("IMN_SETCOMPOSITIONWINDOW: HIMC = 0x%x", m_hIMC); if (m_preferCandidatePos) _SetCandidatePos(lpIMC); else _SetCompositionWindow(lpIMC); } break; default: EZDBGONLYLOGGERPRINT("IMN_(0x%x): HIMC = 0x%x", wp, m_hIMC); } return 0; }
LRESULT WeaselIME::OnIMEFocus(BOOL fFocus) { EZDBGONLYLOGGERPRINT("On IME focus: %d, HIMC = 0x%x", fFocus, m_hIMC); LPINPUTCONTEXT lpIMC = ImmLockIMC(m_hIMC); if(!lpIMC) { return 0; } if (fFocus) { if(!(lpIMC->fdwInit & INIT_COMPFORM)) { lpIMC->cfCompForm.dwStyle = CFS_DEFAULT; GetCursorPos(&lpIMC->cfCompForm.ptCurrentPos); ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos); lpIMC->fdwInit |= INIT_COMPFORM; } m_client.FocusIn(); } else { m_client.FocusOut(); } ImmUnlockIMC(m_hIMC); return 0; }
void WeaselIME::_UpdateInputPosition(LPINPUTCONTEXT lpIMC, POINT pt) { EZDBGONLYLOGGERPRINT("_UpdateInputPosition: (%d, %d)", pt.x, pt.y); //EZDBGONLYLOGGERPRINT("cfCompForm: ptCurrentPos = (%d, %d), rcArea = (%d, %d)", // lpIMC->cfCompForm.ptCurrentPos.x, lpIMC->cfCompForm.ptCurrentPos.y, // lpIMC->cfCompForm.rcArea.left, lpIMC->cfCompForm.rcArea.top); //EZDBGONLYLOGGERPRINT("cfCandForm[0]: ptCurrentPos = (%d, %d), rcArea = (%d, %d)", // lpIMC->cfCandForm[0].ptCurrentPos.x, lpIMC->cfCandForm[0].ptCurrentPos.y, // lpIMC->cfCandForm[0].rcArea.left, lpIMC->cfCandForm[0].rcArea.top); //EZDBGONLYLOGGERPRINT("cfCandForm[1]: ptCurrentPos = (%d, %d), rcArea = (%d, %d)", // lpIMC->cfCandForm[1].ptCurrentPos.x, lpIMC->cfCandForm[1].ptCurrentPos.y, // lpIMC->cfCandForm[1].rcArea.left, lpIMC->cfCandForm[1].rcArea.top); if (pt.x == -1 && pt.y == -1) { EZDBGONLYLOGGERPRINT("Caret pos detection required."); if(!GetCaretPos(&pt)) { EZDBGONLYLOGGERPRINT("Failed to determine caret pos."); pt.x = pt.y = 0; } } ClientToScreen(lpIMC->hWnd, &pt); if (pt.x < -4096 || pt.x >= 4096 || pt.y < -4096 || pt.y >= 4096) { EZDBGONLYLOGGERPRINT("Input position out of range, possibly invalid."); return; } int height = abs(lpIMC->lfFont.W.lfHeight); if (height == 0) { HDC hDC = GetDC(lpIMC->hWnd); SIZE sz = {0}; GetTextExtentPoint(hDC, L"A", 1, &sz); height = sz.cy; ReleaseDC(lpIMC->hWnd, hDC); } const int width = 6; RECT rc; SetRect(&rc, pt.x, pt.y, pt.x + width, pt.y + height); EZDBGONLYLOGGERPRINT("Updating input position: (%d, %d)", pt.x, pt.y); m_client.UpdateInputPosition(rc); }
LRESULT WeaselIME::OnUIMessage(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp) { LPINPUTCONTEXT lpIMC = (LPINPUTCONTEXT)ImmLockIMC(m_hIMC); switch (uMsg) { case WM_IME_NOTIFY: { EZDBGONLYLOGGERPRINT("WM_IME_NOTIFY: wp = 0x%x, lp = 0x%x, HIMC = 0x%x", wp, lp, m_hIMC); _OnIMENotify(lpIMC, wp, lp); } break; case WM_IME_SELECT: { EZDBGONLYLOGGERPRINT("WM_IME_SELECT: wp = 0x%x, lp = 0x%x, HIMC = 0x%x", wp, lp, m_hIMC); if (m_preferCandidatePos) _SetCandidatePos(lpIMC); else _SetCompositionWindow(lpIMC); } break; case WM_IME_STARTCOMPOSITION: { EZDBGONLYLOGGERPRINT("WM_IME_STARTCOMPOSITION: wp = 0x%x, lp = 0x%x, HIMC = 0x%x", wp, lp, m_hIMC); if (m_preferCandidatePos) _SetCandidatePos(lpIMC); else _SetCompositionWindow(lpIMC); } break; default: if (!IsIMEMessage(uMsg)) { ImmUnlockIMC(m_hIMC); return DefWindowProcW(hWnd, uMsg, wp, lp); } EZDBGONLYLOGGERPRINT("WM_IME_(0x%x): wp = 0x%x, lp = 0x%x, HIMC = 0x%x", uMsg, wp, lp, m_hIMC); } ImmUnlockIMC(m_hIMC); return 0; }
int main(int argc, char**argv) { axter::ezlogger<>::set_verbosity_level_tolerance(axter::log_very_rarely); EZLOGGERFUNCTRACKER; int ReturnValue = 99; EZLOGGER_PRG_MAIN_ARG(argc, argv); EZDBGONLYLOGGER_PRG_MAIN_ARG(argc, argv); EZLOGGERVL_PRG_MAIN_ARG(axter::log_often, argc, argv); int i = 123; std::string somedata = "Hello World"; EZLOGGER(i); EZDBGONLYLOGGER(i); EZLOGGERVL(axter::log_often)(i); EZLOGGERVAR(somedata); EZDBGONLYLOGGERVAR(somedata); EZLOGGERVLVAR(axter::log_often, somedata); bool SomeConditionVar = true; EZLOGGERVAR(SomeConditionVar == false); EZDBGONLYLOGGERVAR(SomeConditionVar == false); EZLOGGERVLVAR(axter::log_often, SomeConditionVar == true); EZLOGGERVLVARIFY(axter::log_often, SomeConditionVar == false); EZLOGGERSTREAM << somedata << " " << i << std::endl; EZLOGGERSTREAM << somedata << " next line " << i << std::endl; EZLOGGERSTREAM2(std::cerr) << somedata << " next line " << i << std::endl; EZDBGONLYLOGGERSTREAM << somedata << " " << i << std::endl; EZDBGONLYLOGGERSTREAM << somedata << " next line " << i << std::endl; EZLOGGERVLSTREAM(axter::log_often) << somedata << " " << i << std::endl; // EZLOGGERVLSTREAM(axter::levels(axter::log_often, axter::warn, __FUNCSIG__ /*or GNU PRETTY_FUNCTION*/,"Xyz Facility")) << somedata << " " << i << std::endl; EZLOGGERPRINT("i = %i and somedata = %s", i, somedata.c_str()); EZDBGONLYLOGGERPRINT("i = %i and somedata = %s", i, somedata.c_str()); EZLOGGERVLPRINT(axter::log_often)("i = %i and somedata = %s", i, somedata.c_str()); //Alternative method EZLOGGERVL(axter::log_often).cprint("i = %i and somedata = %s", i, somedata.c_str()); EZLOGGER.cprint("i = %i and somedata = %s", i, somedata.c_str()); if (1) { EZLOGGERMARKER; EZDBGONLYLOGGERMARKER; EZLOGGERVLMARKER(axter::log_often); } some_func1(); return EZLOGGERVAR(ReturnValue); }
LRESULT WeaselIME::OnIMESelect(BOOL fSelect) { EZDBGONLYLOGGERPRINT("On IME select: %d, HIMC = 0x%x", fSelect, m_hIMC); if (fSelect) { // initialize weasel client m_client.Connect(launch_server); m_client.StartSession(); return _Initialize(); } else { m_client.EndSession(); return _Finalize(); } }
BOOL WeaselIME::ProcessKeyEvent(UINT vKey, KeyInfo kinfo, const LPBYTE lpbKeyState) { EZDBGONLYLOGGERPRINT("Process key event: vKey = 0x%x, kinfo = 0x%x, HIMC = 0x%x", vKey, UINT32(kinfo), m_hIMC); bool accepted = false; if (!m_client.Echo()) { m_client.Connect(launch_server); m_client.StartSession(); } weasel::KeyEvent ke; if (!ConvertKeyEvent(vKey, kinfo, lpbKeyState, ke)) { // unknown key event return FALSE; } accepted = m_client.ProcessKeyEvent(ke); // get commit string from server wstring commit; weasel::Status status; weasel::ResponseParser parser(&commit, NULL, &status); bool ok = m_client.GetResponseData(boost::ref(parser)); if (ok) { if (!commit.empty()) { _EndComposition(commit.c_str()); } else if (status.composing != m_composing) { if (m_composing) _EndComposition(NULL); else _StartComposition(); } } return (BOOL)accepted; }
static bool launch_server() { EZDBGONLYLOGGERPRINT("Launching weasel server."); // 從註冊表取得server位置 HKEY hKey; LSTATUS ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); if (ret != ERROR_SUCCESS) { error_message(L"註冊表信息無影了"); return false; } WCHAR value[MAX_PATH]; DWORD len = sizeof(value); DWORD type = 0; ret = RegQueryValueEx(hKey, L"WeaselRoot", NULL, &type, (LPBYTE)value, &len); if (ret != ERROR_SUCCESS) { error_message(L"未設置 WeaselRoot"); RegCloseKey(hKey); return false; } wpath weaselRoot(value); len = sizeof(value); type = 0; ret = RegQueryValueEx(hKey, L"ServerExecutable", NULL, &type, (LPBYTE)value, &len); if (ret != ERROR_SUCCESS) { error_message(L"未設置 ServerExecutable"); RegCloseKey(hKey); return false; } wpath serverPath(weaselRoot / value); RegCloseKey(hKey); // 啓動服務進程 wstring exe = serverPath.native_file_string(); wstring dir = weaselRoot.native_file_string(); STARTUPINFO startup_info = {0}; PROCESS_INFORMATION process_info = {0}; startup_info.cb = sizeof(startup_info); if (!CreateProcess(exe.c_str(), NULL, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startup_info, &process_info)) { EZDBGONLYLOGGERPRINT("ERROR: failed to launch weasel server."); error_message(L"服務進程啓動不起來 :("); return false; } if (!WaitForInputIdle(process_info.hProcess, 1500)) { EZDBGONLYLOGGERPRINT("WARNING: WaitForInputIdle() timed out; succeeding IPC messages might not be delivered."); } if (process_info.hProcess) CloseHandle(process_info.hProcess); if (process_info.hThread) CloseHandle(process_info.hThread); return true; }