BOOL CreateTBar(HWND hWnd) { HIMC hIMC = NULL; BOOL fOpen; hWndToolBar = CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS, TOOLBAR_ID, NUMIMAGES, hInst, IDB_BMP, tbButton, sizeof(tbButton)/sizeof(TBBUTTON), BUTTONWIDTH, BUTTONHEIGHT, IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON)); UpdateShowCandButton(); hIMC = ImmGetContext(hWndCompStr); fOpen = ImmGetOpenStatus(hIMC); UpdateShowOpenStatusButton(fOpen); ImmReleaseContext(hWndCompStr,hIMC); return (hWndToolBar != 0); }
// &SetImeString static void funcSetImeString(HWND i_hwnd, int i_size) { _TCHAR *buf = new _TCHAR(i_size); DWORD len = 0; _TCHAR ImeDesc[GANA_MAX_ATOM_LENGTH]; UINT ImeDescLen; DWORD error; DWORD denom = 1; HANDLE hPipe = CreateFile(addSessionId(HOOK_PIPE_NAME).c_str(), GENERIC_READ, FILE_SHARE_READ, (SECURITY_ATTRIBUTES *)NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL); error = ReadFile(hPipe, buf, i_size, &len, NULL); CloseHandle(hPipe); ImeDescLen = ImmGetDescription(GetKeyboardLayout(0), ImeDesc, sizeof(ImeDesc)); if (_tcsncmp(ImeDesc, _T("SKKIME"), ImeDescLen) > 0) denom = sizeof(_TCHAR); HIMC hIMC = ImmGetContext(i_hwnd); if (hIMC == INVALID_HANDLE_VALUE) return; int status = ImmGetOpenStatus(hIMC); ImmSetCompositionString(hIMC, SCS_SETSTR, buf, len / denom, NULL, 0); delete buf; ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); if (!status) ImmSetOpenStatus(hIMC, status); ImmReleaseContext(i_hwnd, hIMC); }
void close() { if(IsWindow(hwnd_)) { Context himc(hwnd_); ImmSetOpenStatus(himc, FALSE); is_open_ = ImmGetOpenStatus(himc) ? true : false; } }
BOOL pymImmGetOpenStatus(HIMC hIMC) { PyMFC_PROLOGUE(pymFormatMessage); { PyMFCLeavePython lp; return ImmGetOpenStatus(hIMC); } PyMFC_EPILOGUE(0); }
bool open() { if(IsWindow(hwnd_)) { Context himc(hwnd_); ImmSetOpenStatus(himc, TRUE); is_open_ = ImmGetOpenStatus(himc) ? true : false; } return is_open_; }
bool onNotify(int status) { if(IsWindow(hwnd_)) { Context himc(hwnd_); if(status == IMN_SETOPENSTATUS) { is_open_ = ImmGetOpenStatus(himc) ? true : false; ImmReleaseContext(hwnd_, himc); return false; } } return true; }
BOOL GetImeOpenStatus(HWND hWnd) { BOOL ret = FALSE; HIMC hImc; if ((hImc = ImmGetContext(hWnd))) { ret = ImmGetOpenStatus(hImc); ImmReleaseContext(hWnd, hImc); } return ret; }
void handleOpenStatus(HWND hwnd) { //Only reported for japanese if(((unsigned long)(GetKeyboardLayout(0))&0xff)!=0x11) return; /* Obtain IME context */ HIMC imc = ImmGetContext(hwnd); if (!imc) return; BOOL opened=ImmGetOpenStatus(imc); if(opened!=lastOpenStatus) { nvdaControllerInternal_IMEOpenStatusUpdate(opened); lastOpenStatus=opened; } ImmReleaseContext(hwnd, imc); }
// &SetImeStatus static void funcSetImeStatus(HWND i_hwnd, int i_status) { HIMC hIMC; hIMC = ImmGetContext(i_hwnd); if (hIMC == INVALID_HANDLE_VALUE) return; if (i_status < 0) i_status = !ImmGetOpenStatus(hIMC); ImmSetOpenStatus(hIMC, i_status); ImmReleaseContext(i_hwnd, hIMC); }
BOOL GetOpenStatusByCodepage( HIMC hIMC, PCONSOLE_TABLE ConTbl ) { switch ( HKL_TO_LANGID(ConTbl->hklActive)) { case LANG_ID_JAPAN: return ImmGetOpenStatus(hIMC); break; case LANG_ID_TAIWAN: case LANG_ID_PRC: case LANG_ID_KOREA: if (ImmGetOpenStatus(hIMC)) { return ImmIsIME(ConTbl->hklActive); } break; default: return FALSE; } return FALSE; }
EXPORT BOOL SetInlinePosition(HWND hWnd, int x, int y, int font_height) { BOOL ret = FALSE; HIMC hIMC = ImmGetContext(hWnd); if (ImmGetOpenStatus(hIMC)) { COMPOSITIONFORM cf = {0}; cf.dwStyle = CFS_POINT; cf.ptCurrentPos.x = x; cf.ptCurrentPos.y = y; if (ImmSetCompositionWindow(hIMC, &cf)) { LOGFONTW lf = {0}; lf.lfHeight = font_height; // lf.lfFaceName = font_face; if (ImmSetCompositionFontW(hIMC, &lf)) { ret = TRUE; } } } ImmReleaseContext(hWnd, hIMC); return ret; }
bool Mint::IsNativeIME(void) const { HIMC hImc = ImmGetContext(GetInstance()->GetHWND()); if(hImc==NULL) return false; bool bNative = false; if(GetPrimaryLanguageIdentifier()==LANG_JAPANESE){ // ÀϺ»¾îÀΰæ¿ì ConversionMode°¡ ¾Æ´Ñ OpenSatus·Î ÀԷ±Ⱑ È°¼ºÈ µÇ¾ú´ÂÁö ¾Ë ¼ö ÀÖ´Ù. // ÀϺ»¾î IME ÀÌ»óÇÔ! bNative = (ImmGetOpenStatus(hImc)==TRUE); } else{ // ¿µ¹®(IME_CMODE_ALPHANUMERIC) ¶Ç´Â ³×ÀÌƼºê(IME_CMODE_NATIVE) ¾ð¾îÀÎÁö¸¦ ÆǺ° DWORD dwConvMode, dwSentMode; ImmGetConversionStatus(hImc, &dwConvMode, &dwSentMode); bNative = (dwConvMode&IME_CMODE_NATIVE); } ImmReleaseContext(GetInstance()->GetHWND(), hImc); return bNative; }
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { FARPROC lpProc = NULL; RECT rect = {0}; HMENU hMenu = NULL; HIMC hIMC = NULL; BOOL fOpen = FALSE; switch (message) { case WM_CREATE: // Create Status Window CreateTBar(hWnd); CreateStatus(hWnd); // Create Child Window GetClientRect(hWnd, &rect); if (!(hWndCompStr = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("CompStrWndClass"), NULL, WS_CHILD | WS_VISIBLE, // 0, 0, rect.right, rect.bottom - nStatusHeight, 0, 0, 0, 0, hWnd, NULL, hInst, NULL))) return FALSE; InitIMEUIPosition(hWndCompStr); if (!(hWndCandList = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("CandListWndClass"), NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL))) return FALSE; ShowWindow(hWndCompStr, SW_SHOW); ShowWindow(hWndCandList, SW_SHOWNA); SetStatusItems(hWnd); hMenu = GetMenu(hWnd); CheckMenuItem(hMenu,IDM_SHOWCAND, (fShowCand ? MF_CHECKED : MF_UNCHECKED)); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_ABOUT: lpProc = (FARPROC)MakeProcInstance(AboutDlg, hInst); DialogBox(hInst, TEXT("ABOUTBOX"), hWnd, (DLGPROC)lpProc); FreeProcInstance(lpProc); break; case IDM_FONT: { CHOOSEFONT cf = {0}; LOGFONT lfT = {0}; /* Set all structure fields to zero. */ memset(&cf, 0, sizeof(CHOOSEFONT)); memcpy(&lfT, &lf, sizeof(LOGFONT)); cf.lStructSize = sizeof(CHOOSEFONT); cf.hwndOwner = hWnd; cf.lpLogFont = &lfT; cf.Flags = CF_SCREENFONTS | CF_EFFECTS; cf.nFontType = SCREEN_FONTTYPE; if (ChooseFont(&cf)) { if (hFont) { DeleteObject(hFont); } memcpy(&lf, &lfT, sizeof(LOGFONT)); hFont = CreateFontIndirect(&lf); InvalidateRect(hWndCompStr,NULL,TRUE); UpdateWindow(hWndCompStr); } } break; case IDM_SHOWCAND: hMenu = GetMenu(hWnd); fShowCand = !fShowCand; CheckMenuItem(hMenu,IDM_SHOWCAND, (fShowCand ? MF_CHECKED : MF_UNCHECKED)); MoveCompCandWindow(hWnd); UpdateShowCandButton(); break; case IDM_OPENSTATUS: hIMC = ImmGetContext(hWndCompStr); fOpen = ImmGetOpenStatus(hIMC); ImmSetOpenStatus(hIMC,!fOpen); UpdateShowOpenStatusButton(!fOpen); ImmReleaseContext(hWndCompStr,hIMC); hMenu = GetMenu(hWnd); CheckMenuItem(hMenu,IDM_OPENSTATUS, (fOpen ? MF_UNCHECKED : MF_CHECKED)); break; case IDM_NATIVEMODE: /* fall-through */ case IDM_FULLHALF: /* fall-through */ case IDM_ROMAN: /* fall-through */ case IDM_CHARCODE: /* fall-through */ case IDM_HANJA: /* fall-through */ case IDM_SOFTKBD: /* fall-through */ case IDM_EUDC: /* fall-through */ case IDM_SYMBOL: HandleModeCommand(hWnd,wParam,lParam); break; case IDM_CONVERT: /* fall-through */ case IDM_CANCEL: /* fall-through */ case IDM_REVERT: /* fall-through */ case IDM_COMPLETE: /* fall-through */ case IDM_OPENCAND: /* fall-through */ case IDM_CLOSECAND: /* fall-through */ case IDM_NEXTCAND: /* fall-through */ case IDM_PREVCAND: HandleConvertCommand(hWnd,wParam,lParam); break; case IDM_NEXTCLAUSE: /* fall-through */ case IDM_PREVCLAUSE: HandleChangeAttr(hWnd,(LOWORD(wParam) == IDM_NEXTCLAUSE)); break; default: break; } break; case WM_SETFOCUS: SetFocus(hWndCompStr); break; case WM_NOTIFY: SetTooltipText(hWnd, lParam); break; case WM_SIZE: SendMessage(hWndStatus,message,wParam,lParam); SendMessage(hWndToolBar,message,wParam,lParam); if (wParam != SIZE_MINIMIZED) { MoveCompCandWindow(hWnd); } break; case WM_IME_NOTIFY: switch (wParam) { case IMN_OPENSTATUSWINDOW: /* fall-through */ case IMN_CLOSESTATUSWINDOW: break; case IMN_SETCONVERSIONMODE: return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case WM_DESTROY: if (hFont) { DeleteObject(hFont); } PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return 0L; }
static HRESULT WINAPI ActiveIMMApp_GetOpenStatus(IActiveIMMApp* This, HIMC hIMC) { return ImmGetOpenStatus(hIMC); }
//*********************************************************************** // // void ImeUISetOpenStatus() // // This handles WM_IME_REPORT message with wParam = IR_NOTIFY & // lParam = IMC_SETOPENSTATUS. // //********************************************************************** void ImeUISetOpenStatus( HWND hwnd ) { int i; // Lopp counter HIMC hIMC; // Storage for input context handle. // // If fail to get input context handle then do nothing // if ( !( hIMC = ImmGetContext( hwnd ) ) ) return; if ( ImmGetOpenStatus( hIMC ) ) { // // If the IME conversion engine is open, here we change // window's caption title to DBCS composition mode. // SetWindowText( hwnd, (LPSTR)szSteCompTitle ); } else { RECT rect = {0}; // // If the IME conversion engine is closed, here we // erase all already displayed composition chars if any, // change the window's caption title to normal. // GetClientRect( hwnd, &rect ); InvalidateRect( hwnd, &rect, FALSE ); SetWindowText( hwnd, (LPSTR)szSteTitle ); // // Here we close and destroy all of candidate windows // if IME conversion engine is closed. // for( i = 0; i <= MAX_LISTCAND; i++ ) { if ( gImeUIData.hListCand[ i ] ) { DestroyWindow( gImeUIData.hListCand[ i ] ); gImeUIData.hListCand[ i ] = NULL; GlobalFree( gImeUIData.hListCandMem[ i ] ); gImeUIData.hListCandMem[ i ] = NULL; } } // // Reset IMEUI's global data. // gImeUIData.uCompLen = 0; gImeUIData.ImeState = 0; ResetCaret( hwnd ); } ImmReleaseContext( hwnd, hIMC ); }
//********************************************************************** // // void RestoreImeUI() // // This repaints all displayed composition string if need. // Main window procedure will call this upon receiving // WM_PAINT message. // //********************************************************************** void RestoreImeUI( HWND hwnd ) { HIMC hIMC; // Storage for input context handle. LONG bufLen; // // // If fail to get input context handle then do nothing. // if ( !( hIMC = ImmGetContext( hwnd ) ) ) return; // // If IME conversion engine is open and there are any composition // string in the context then we redisplay them. // if ( ImmGetOpenStatus( hIMC ) && gImeUIData.ImeState && ( bufLen = ImmGetCompositionString( hIMC, GCS_COMPSTR, (void *)NULL, 0l ) ) > 0 ) { LPSTR lpCompStr; // Pointer to composition string HLOCAL hMem; // Storage for memory handle. LPSTR lpCompStrAttr = NULL; // Pointer to composition string's attribute LONG bufLenAttr; // HLOCAL hMemAttr = NULL; // Memory handle for composition string's // attributes. // // If fail to allocate and lock memory space for reading in // the composition string then do nothing. // if ( !( hMem = LocalAlloc( LPTR, (int)bufLen + 1 ) ) ) goto exit2; if( !( lpCompStr = (LPSTR) LocalLock( hMem ) ) ) { LocalFree( hMem ); goto exit2; } // // Get composition string and redisplay them. // if ( ImmGetCompositionString( hIMC, GCS_COMPSTR, lpCompStr, bufLen ) > 0 ) { // // Make sure whether we need to handle composition string's // attributes. // if ( ( bufLenAttr = ( ImmGetCompositionString( hIMC, GCS_COMPATTR, (void FAR*)NULL, 0l ) ) ) > 0 ) { // // If fail to allocate and lock memory space for reading in // the composition string's attribute then we assume // no attribute array. // if ( !( hMemAttr = LocalAlloc(LPTR, (int)bufLenAttr + 1 ))) goto nothing; if ( !( lpCompStrAttr = (LPSTR) LocalLock( hMemAttr ) ) ) { LocalFree( hMemAttr ); goto nothing; } ImmGetCompositionString( hIMC, GCS_COMPATTR, lpCompStrAttr, bufLenAttr ); lpCompStrAttr[ bufLenAttr ] = 0; } else { nothing: lpCompStrAttr = NULL; } lpCompStr[ bufLen ] = 0; DisplayCompString( hwnd, lpCompStr, lpCompStrAttr ); } LocalUnlock( hMem ); LocalFree( hMem ); if ( lpCompStrAttr ) { if (NULL != hMemAttr) { LocalUnlock( hMemAttr ); LocalFree( hMemAttr ); } } } exit2: ImmReleaseContext( hwnd, hIMC ); }
LRESULT CALLBACK globalKeyboardHookProcedure(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode >= HC_ACTION) { QWidget *focusWidget = QApplication::focusWidget(); // qobject_cast return NULL when the cast fail. bool widgetIsFocusable = qobject_cast<QLineEdit *>(focusWidget) || qobject_cast<QComboBox *>(focusWidget); if (widgetIsFocusable) { KBDLLHOOKSTRUCT *keyData = reinterpret_cast<KBDLLHOOKSTRUCT *>(lParam); // SYSTEM events are not 'trapped' by Jamtaba if (wParam == WM_SYSKEYDOWN || wParam == WM_SYSKEYUP) return CallNextHookEx(NULL, nCode, wParam, lParam); bool usingIME = ImmGetOpenStatus(ImmGetContext(GetActiveWindow())); // detect if japanese input (IME) is activated - issue #472 if (usingIME) { // we need detect if user is pressing VK_RETURN 2 times: 1 time to finish IME notation window and the second time to send the message in ninjam chat. bool hookingReturnKey = keyboardHook::lastImeKeyUpWasReturn && keyData->vkCode == VK_RETURN; if (wParam == WM_KEYUP) // we need "remember" if the last key was VK_RETURN keyboardHook::lastImeKeyUpWasReturn = !hookingReturnKey && keyData->vkCode == VK_RETURN; if (!hookingReturnKey) return CallNextHookEx(NULL, nCode, wParam, lParam); } QKeyEvent *ev = nullptr; QKeyEvent::Type eventType = (wParam == WM_KEYDOWN) ? QKeyEvent::KeyPress : QKeyEvent::KeyRelease; bool controlIsPressed = GetKeyState(VK_CONTROL) & 0x8000; bool shiftIsPressed = GetKeyState(VK_SHIFT) & 0x8000; // A-Z letters and numbers bool typingLetters = keyData->vkCode >= Qt::Key_A && keyData->vkCode <= Qt::Key_Z; bool typingNumbers = keyData->vkCode >= Qt::Key_0 && keyData->vkCode <= Qt::Key_9; bool typingInNumPad = keyData->vkCode >= VK_NUMPAD0 && keyData->vkCode <= VK_NUMPAD9; bool typingQuestionMark = keyData->vkCode == Qt::Key_questiondown || keyData->vkCode == Qt::Key_Question; if (typingLetters || typingNumbers || typingInNumPad || typingQuestionMark) { QString keyText = keyboardHook::vkCodeToText(keyData->vkCode, keyData->scanCode); Qt::KeyboardModifiers modifiers; if (controlIsPressed) modifiers |= Qt::ControlModifier; if (shiftIsPressed) { modifiers |= Qt::ShiftModifier; } ev = new QKeyEvent(eventType, keyData->vkCode, modifiers, keyText); } else { // other/special keys switch (keyData->vkCode) { case VK_BACK: ev = new QKeyEvent(eventType, Qt::Key_Backspace, Qt::NoModifier); break; case VK_DELETE: ev = new QKeyEvent(eventType, Qt::Key_Delete, Qt::NoModifier); break; case VK_SPACE: ev = new QKeyEvent(eventType, Qt::Key_Space, Qt::NoModifier, " "); break; case VK_RETURN: ev = new QKeyEvent(eventType, Qt::Key_Return, Qt::NoModifier); break; case VK_LEFT: ev = new QKeyEvent(eventType, Qt::Key_Left, QApplication::queryKeyboardModifiers()); break; case VK_RIGHT: ev = new QKeyEvent(eventType, Qt::Key_Right, QApplication::queryKeyboardModifiers()); break; case VK_END: ev = new QKeyEvent(eventType, Qt::Key_End, QApplication::queryKeyboardModifiers()); break; case VK_HOME: ev = new QKeyEvent(eventType, Qt::Key_Home, QApplication::queryKeyboardModifiers()); break; } } if (ev) { QApplication::postEvent(focusWidget, ev); return 1; // if we have a keyboard event Jamtaba will consume the event and don't forward to the Vst host. } } } return CallNextHookEx(NULL, nCode, wParam, lParam); // Forward the event to VST host }
static void test_ImmThreads(void) { HIMC himc, otherHimc, h1; igc_threadinfo threadinfo; HANDLE hThread; DWORD dwThreadId; BOOL rc; LOGFONT lf; COMPOSITIONFORM cf; DWORD status, sentence; POINT pt; himc = ImmGetContext(hwnd); threadinfo.event = CreateEvent(NULL, TRUE, FALSE, NULL); threadinfo.himc = himc; hThread = CreateThread(NULL, 0, ImmGetContextThreadFunc, &threadinfo, 0, &dwThreadId ); WaitForSingleObject(threadinfo.event, INFINITE); otherHimc = ImmGetContext(threadinfo.hwnd); todo_wine ok(himc != otherHimc, "Windows from other threads should have different himc\n"); todo_wine ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n"); if (0) /* FIXME: Causes wine to hang */ { h1 = ImmAssociateContext(hwnd,otherHimc); ok(h1 == NULL, "Should fail to be able to Associate a default context from a different thread\n"); h1 = ImmGetContext(hwnd); ok(h1 == himc, "Context for window should remain unchanged\n"); ImmReleaseContext(hwnd,h1); } /* OpenStatus */ rc = ImmSetOpenStatus(himc, TRUE); ok(rc != 0, "ImmSetOpenStatus failed\n"); rc = ImmGetOpenStatus(himc); ok(rc != 0, "ImmGetOpenStatus failed\n"); rc = ImmSetOpenStatus(himc, FALSE); ok(rc != 0, "ImmSetOpenStatus failed\n"); rc = ImmGetOpenStatus(himc); ok(rc == 0, "ImmGetOpenStatus failed\n"); rc = ImmSetOpenStatus(otherHimc, TRUE); todo_wine ok(rc == 0, "ImmSetOpenStatus should fail\n"); rc = ImmGetOpenStatus(otherHimc); todo_wine ok(rc == 0, "ImmGetOpenStatus failed\n"); rc = ImmSetOpenStatus(otherHimc, FALSE); todo_wine ok(rc == 0, "ImmSetOpenStatus should fail\n"); rc = ImmGetOpenStatus(otherHimc); ok(rc == 0, "ImmGetOpenStatus failed\n"); /* CompositionFont */ rc = ImmGetCompositionFont(himc, &lf); ok(rc != 0, "ImmGetCompositionFont failed\n"); rc = ImmSetCompositionFont(himc, &lf); ok(rc != 0, "ImmSetCompositionFont failed\n"); rc = ImmGetCompositionFont(otherHimc, &lf); ok(rc != 0 || broken(rc == 0), "ImmGetCompositionFont failed\n"); rc = ImmSetCompositionFont(otherHimc, &lf); todo_wine ok(rc == 0, "ImmSetCompositionFont should fail\n"); /* CompositionWindow */ rc = ImmSetCompositionWindow(himc, &cf); ok(rc != 0, "ImmSetCompositionWindow failed\n"); rc = ImmGetCompositionWindow(himc, &cf); ok(rc != 0, "ImmGetCompositionWindow failed\n"); rc = ImmSetCompositionWindow(otherHimc, &cf); todo_wine ok(rc == 0, "ImmSetCompositionWindow should fail\n"); rc = ImmGetCompositionWindow(otherHimc, &cf); ok(rc != 0 || broken(rc == 0), "ImmGetCompositionWindow failed\n"); /* ConversionStatus */ rc = ImmGetConversionStatus(himc, &status, &sentence); ok(rc != 0, "ImmGetConversionStatus failed\n"); rc = ImmSetConversionStatus(himc, status, sentence); ok(rc != 0, "ImmSetConversionStatus failed\n"); rc = ImmGetConversionStatus(otherHimc, &status, &sentence); ok(rc != 0 || broken(rc == 0), "ImmGetConversionStatus failed\n"); rc = ImmSetConversionStatus(otherHimc, status, sentence); todo_wine ok(rc == 0, "ImmSetConversionStatus should fail\n"); /* StatusWindowPos */ rc = ImmSetStatusWindowPos(himc, &pt); ok(rc != 0, "ImmSetStatusWindowPos failed\n"); rc = ImmGetStatusWindowPos(himc, &pt); ok(rc != 0, "ImmGetStatusWindowPos failed\n"); rc = ImmSetStatusWindowPos(otherHimc, &pt); todo_wine ok(rc == 0, "ImmSetStatusWindowPos should fail\n"); rc = ImmGetStatusWindowPos(otherHimc, &pt); ok(rc != 0 || broken(rc == 0), "ImmGetStatusWindowPos failed\n"); ImmReleaseContext(threadinfo.hwnd,otherHimc); ImmReleaseContext(hwnd,himc); DestroyWindow(threadinfo.hwnd); TerminateThread(hThread, 1); himc = ImmGetContext(GetDesktopWindow()); todo_wine ok(himc == NULL, "Should not be able to get himc from other process window\n"); }
LRESULT HandleNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HIMC hIMC = NULL; BOOL fOpen = FALSE; DWORD dwConvMode, dwSentMode; switch (wParam) { case IMN_OPENSTATUSWINDOW: /* fall-through */ case IMN_CLOSESTATUSWINDOW: break; case IMN_SETOPENSTATUS: SetStatusItems(hWnd); hIMC = ImmGetContext(hWnd); fOpen = ImmGetOpenStatus(hIMC); UpdateShowOpenStatusButton(fOpen); ImmReleaseContext(hWnd,hIMC); break; case IMN_SETCONVERSIONMODE: hIMC = ImmGetContext(hWnd); fOpen = ImmGetOpenStatus(hIMC); ImmGetConversionStatus(hIMC,&dwConvMode,&dwSentMode); if (fOpen) { SetConvModeParts(dwConvMode); UpdateModeButton(dwConvMode); } else { ClearConvModeParts(); } ImmReleaseContext(hWnd,hIMC); break; case IMN_OPENCANDIDATE: if (!fShowCand || (lParam != 0x01)) { if (fdwProperty & IME_PROP_SPECIAL_UI) { // Normally, we only need to set the composition window // position for a special UI IME } else if (fdwProperty & IME_PROP_AT_CARET) { CANDIDATEFORM cdf; HIMC hIMC; hIMC = ImmGetContext(hWnd); cdf.dwIndex = 0; cdf.dwStyle = CFS_CANDIDATEPOS; cdf.ptCurrentPos.x = ptImeUIPos.x; cdf.ptCurrentPos.y = ptImeUIPos.y; ImmSetCandidateWindow(hIMC,&cdf); ImmReleaseContext(hWnd,hIMC); } else { // Normally, we only need to set the composition window // position for a near caret IME } return (DefWindowProc(hWnd, message, wParam, lParam)); } case IMN_CHANGECANDIDATE: #ifdef _DEBUG { TCHAR szDev[80]; DWORD dwSize; LPCANDIDATELIST lpC; hIMC = ImmGetContext(hWnd); if (dwSize = ImmGetCandidateList(hIMC,0x0,NULL,0)) { lpC = (LPCANDIDATELIST)GlobalAlloc(GPTR,dwSize); ImmGetCandidateList(hIMC,0x0,lpC,dwSize); OutputDebugString(TEXT("DumpCandList!!!\r\n")); StringCchPrintf((LPTSTR)szDev,ARRAYSIZE(szDev),TEXT("dwCount %d\r\n"),lpC->dwCount); OutputDebugString((LPTSTR)szDev); StringCchPrintf((LPTSTR)szDev,ARRAYSIZE(szDev),TEXT("dwSelection %d\r\n"),lpC->dwSelection); OutputDebugString((LPTSTR)szDev); StringCchPrintf((LPTSTR)szDev,ARRAYSIZE(szDev),TEXT("dwPageStart %d\r\n"),lpC->dwPageStart); OutputDebugString((LPTSTR)szDev); StringCchPrintf((LPTSTR)szDev,ARRAYSIZE(szDev),TEXT("dwPageSize %d\r\n"),lpC->dwPageSize); OutputDebugString((LPTSTR)szDev); GlobalFree((HANDLE)lpC); } } #endif if (fShowCand && (lParam == 0x01)) { DWORD dwSize; if (!lpCandList) lpCandList = (LPCANDIDATELIST)GlobalAlloc(GPTR,sizeof(CANDIDATELIST)); hIMC = ImmGetContext(hWnd); if (dwSize = ImmGetCandidateList(hIMC,0x0,NULL,0)) { GlobalFree((HANDLE)lpCandList); lpCandList = (LPCANDIDATELIST)GlobalAlloc(GPTR,dwSize); ImmGetCandidateList(hIMC,0x0,lpCandList,dwSize); } else { memset(lpCandList, 0, sizeof(CANDIDATELIST)); } InvalidateRect(hWndCandList,NULL,TRUE); UpdateWindow(hWndCandList); ImmReleaseContext(hWnd,hIMC); } else { return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case IMN_CLOSECANDIDATE: if (fShowCand && (lParam == 0x01)) { if (!lpCandList) { lpCandList = (LPCANDIDATELIST)GlobalAlloc(GPTR,sizeof(CANDIDATELIST)); } memset(lpCandList, 0, sizeof(CANDIDATELIST)); InvalidateRect(hWndCandList,NULL,TRUE); UpdateWindow(hWndCandList); } else { return (DefWindowProc(hWnd, message, wParam, lParam)); } break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return 0; }
/** * ダイアログのプロシージャ。 * @param [in] hDlg ダイアログボックスのハンドルが格納されています * @param [in] uMsg メッセージが格納されています * @param [in] wParam メッセージの追加情報が格納されています * @param [in] lParam メッセージの追加情報が格納されています * @return メッセージを処理した場合は 0 以外(TRUE)、そうでなければ 0(FALSE) */ static BOOL CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND hwndComboBox = NULL; static HWND hwndEdit = NULL; static LRESULT selectedIndex = CB_ERR; static int length = 0; char *imeControl = NULL; switch (uMsg) { case WM_INITDIALOG: center_window(hDlg); hwndComboBox = GetDlgItem(hDlg, IDC_COMBO1); SendMessage(hwndComboBox, CB_LIMITTEXT, 0, 0); hwndEdit = GetWindow(hwndComboBox, GW_CHILD); SetFocus(hwndComboBox); SetFocus(GetDlgItem(hDlg, IDC_COMBO1)); for (unsigned int i = 0; i < history.size(); i++) { SendMessage(hwndComboBox, CB_INSERTSTRING, i, (LPARAM)history[i].c_str()); } CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, selectedRadioButton); CheckDlgButton(hDlg, IDC_CHECK1, selectedCheckBox); if (selectedRadioButton == IDC_RADIO1 || selectedRadioButton == IDC_RADIO2) { EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), FALSE); } if (selectedText.size() != 0) { SetWindowText(hwndEdit, selectedText.c_str()); } if ((imeControl = iniFile->read("IME", "control")) && strcmp(imeControl, "1") == 0) { HIMC hImc; DWORD dwConv, dwSent; hImc = ImmGetContext(hDlg); ImmGetConversionStatus(hImc, &dwConv, &dwSent); if (ImmGetOpenStatus(hImc)) { ImmSetOpenStatus(hImc, false); } ImmReleaseContext(hDlg, hImc); } // SetFocus でフォーカス移動を行った場合は FALSE を返さなければならない return FALSE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE; case IDOK: if (IsDlgButtonChecked(hDlg, IDC_RADIO1)) { selectedRadioButton = IDC_RADIO1; } else if (IsDlgButtonChecked(hDlg, IDC_RADIO2)) { selectedRadioButton = IDC_RADIO2; } else if (IsDlgButtonChecked(hDlg, IDC_RADIO3)) { selectedRadioButton = IDC_RADIO3; } else if (IsDlgButtonChecked(hDlg, IDC_RADIO4)) { selectedRadioButton = IDC_RADIO4; } selectedCheckBox = IsDlgButtonChecked(hDlg, IDC_CHECK1); // 設定ファイルに状態を書き出す switch (selectedRadioButton) { case IDC_RADIO1: iniFile->write("Config", "radio", "1"); break; case IDC_RADIO2: iniFile->write("Config", "radio", "2"); break; case IDC_RADIO3: iniFile->write("Config", "radio", "3"); break; case IDC_RADIO4: iniFile->write("Config", "radio", "4"); break; default: iniFile->write("Config", "radio", "1"); break; } if (selectedCheckBox) { iniFile->write("Config", "check", "TRUE"); } else { iniFile->write("Config", "check", "FALSE"); } // 履歴を保存 length = GetWindowTextLength(hwndEdit); if (length != 0) { char *buf = new char[length + 1]; buf[length] = '\0'; GetWindowText(hwndEdit, buf, length + 1); std::string temp = buf; delete[] buf; history.insert(history.begin(), temp); for (unsigned int i = 0; i < history.size() - 1; i++) { for (unsigned int j = i + 1; j < history.size(); j++) { std::string str1 = history[i]; std::string str2 = history[j]; if (str1 == str2) { history[j] = ""; } } } int index = 0; for (unsigned int i = 0; i < MAX_HISTORY && i < history.size(); i++) { if (history[i] != "") { std::string key = "history"; char num[3] = {0}; sprintf_s(num, "%d", index); key += num; iniFile->write("History", key.c_str(), history[i].c_str()); index++; } } } if (length != 0) { EndDialog(hDlg, IDOK); } else { EndDialog(hDlg, IDCANCEL); } return TRUE; case IDC_RADIO1: case IDC_RADIO2: CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, LOWORD(wParam)); EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), FALSE); return TRUE; case IDC_RADIO3: case IDC_RADIO4: CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, LOWORD(wParam)); EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), TRUE); return TRUE; case IDC_COMBO1: switch (HIWORD(wParam)) { case CBN_SELCHANGE: // 選択項目が変更されたとき case CBN_EDITUPDATE: // 直接入力で内容が変更されたとき。変更内容が表示される前に呼ばれる case CBN_EDITCHANGE: // 直接入力で内容が変更されたとき。変更内容が表示された後に呼ばれる selectedIndex = SendMessage(hwndComboBox, CB_GETCURSEL, 0, 0); break; } break; default: break; } return FALSE; case WM_TIMER: return FALSE; case WM_CLOSE: EndDialog(hDlg, WM_CLOSE); return TRUE; default: break; } return FALSE; }
/// hook of GetMessage LRESULT CALLBACK getMessageProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam) { if (!g.m_isInitialized) initialize(false); if (!g_hookData) return 0; MSG &msg = (*(MSG *)i_lParam); if (i_wParam != PM_REMOVE) goto finally; switch (msg.message) { case WM_COMMAND: case WM_SYSCOMMAND: notifyCommand(msg.hwnd, msg.message, msg.wParam, msg.lParam); break; case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: { if (HIMC hIMC = ImmGetContext(msg.hwnd)) { bool prev = g.m_isImeLock; g.m_isImeLock = !!ImmGetOpenStatus(hIMC); ImmReleaseContext(msg.hwnd, hIMC); if (prev != g.m_isImeLock) { notifyLockState(1); } } int nVirtKey = (int)msg.wParam; // int repeatCount = (msg.lParam & 0xffff); BYTE scanCode = (BYTE)((msg.lParam >> 16) & 0xff); bool isExtended = !!(msg.lParam & (1 << 24)); // bool isAltDown = !!(msg.lParam & (1 << 29)); // bool isKeyup = !!(msg.lParam & (1 << 31)); if (nVirtKey == VK_CAPITAL || nVirtKey == VK_NUMLOCK || nVirtKey == VK_KANA || nVirtKey == VK_SCROLL) notifyLockState(2); else if (scanCode == g_hookData->m_syncKey && isExtended == g_hookData->m_syncKeyIsExtended) notifySync(); break; } case WM_IME_STARTCOMPOSITION: g.m_isImeCompositioning = true; notifyLockState(3); break; case WM_IME_ENDCOMPOSITION: g.m_isImeCompositioning = false; notifyLockState(4); break; default: if (i_wParam == PM_REMOVE && msg.message == g.m_WM_MAYU_MESSAGE) { switch (msg.wParam) { case MayuMessage_notifyName: notifyName(msg.hwnd); break; case MayuMessage_funcRecenter: funcRecenter(msg.hwnd); break; case MayuMessage_funcSetImeStatus: funcSetImeStatus(msg.hwnd, msg.lParam); break; case MayuMessage_funcSetImeString: funcSetImeString(msg.hwnd, msg.lParam); break; } } break; } finally: return CallNextHookEx(s_hookDataArch->m_hHookGetMessage, i_nCode, i_wParam, i_lParam); }
/// hook of SendMessage LRESULT CALLBACK callWndProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam) { if (!g.m_isInitialized) initialize(false); if (!g_hookData) return 0; CWPSTRUCT &cwps = *(CWPSTRUCT *)i_lParam; if (0 <= i_nCode) { switch (cwps.message) { case WM_ACTIVATEAPP: case WM_NCACTIVATE: if (i_wParam) notifySetFocus(); break; case WM_SYSCOMMAND: switch (cwps.wParam) { case SC_MAXIMIZE: case SC_MAXIMIZE2: updateShow(cwps.hwnd, NotifyShow::Show_Maximized); break; case SC_MINIMIZE: case SC_MINIMIZE2: updateShow(cwps.hwnd, NotifyShow::Show_Minimized); break; case SC_RESTORE: case SC_RESTORE2: updateShow(cwps.hwnd, NotifyShow::Show_Normal); break; default: break; } /* through below */ case WM_COMMAND: notifyCommand(cwps.hwnd, cwps.message, cwps.wParam, cwps.lParam); break; case WM_SIZE: switch (cwps.wParam) { case SIZE_MAXIMIZED: updateShow(cwps.hwnd, NotifyShow::Show_Maximized); break; case SIZE_MINIMIZED: updateShow(cwps.hwnd, NotifyShow::Show_Minimized); break; case SIZE_RESTORED: updateShow(cwps.hwnd, NotifyShow::Show_Normal); break; default: break; } break; case WM_MOUSEACTIVATE: notifySetFocus(); break; case WM_ACTIVATE: if (LOWORD(cwps.wParam) != WA_INACTIVE) { notifySetFocus(); if (HIWORD(cwps.wParam)) { // check minimized flag // minimized flag on notifyShow(NotifyShow::Show_Minimized, false); //notifyShow(NotifyShow::Show_Normal, true); } } break; case WM_ENTERMENULOOP: g.m_isInMenu = true; notifySetFocus(true); break; case WM_EXITMENULOOP: g.m_isInMenu = false; notifySetFocus(true); break; case WM_SETFOCUS: g.m_isInMenu = false; // for kana if (g_hookData->m_correctKanaLockHandling) { if (HIMC hIMC = ImmGetContext(cwps.hwnd)) { bool status = !!ImmGetOpenStatus(hIMC); // this code set the VK_KANA state correctly. ImmSetOpenStatus(hIMC, !status); ImmSetOpenStatus(hIMC, status); ImmReleaseContext(cwps.hwnd, hIMC); } } notifySetFocus(); notifyLockState(5); break; case WM_IME_STARTCOMPOSITION: g.m_isImeCompositioning = true; notifyLockState(6); break; case WM_IME_ENDCOMPOSITION: g.m_isImeCompositioning = false; notifyLockState(7); break; case WM_IME_NOTIFY: if (cwps.wParam == IMN_SETOPENSTATUS) if (HIMC hIMC = ImmGetContext(cwps.hwnd)) { g.m_isImeLock = !!ImmGetOpenStatus(hIMC); ImmReleaseContext(cwps.hwnd, hIMC); notifyLockState(8); } break; } } return CallNextHookEx(s_hookDataArch->m_hHookCallWndProc, i_nCode, i_wParam, i_lParam); }