/** Set the position of the candidate window. */ static void SetCandidatePos(HWND hwnd) { HIMC hIMC = ImmGetContext(hwnd); if (hIMC != NULL) { CANDIDATEFORM cf; cf.dwIndex = 0; cf.dwStyle = CFS_EXCLUDE; if (EditBoxInGlobalFocus()) { Point pt = _focused_window->GetCaretPosition(); cf.ptCurrentPos.x = _focused_window->left + pt.x; cf.ptCurrentPos.y = _focused_window->top + pt.y; if (_focused_window->window_class == WC_CONSOLE) { cf.rcArea.left = _focused_window->left; cf.rcArea.top = _focused_window->top; cf.rcArea.right = _focused_window->left + _focused_window->width; cf.rcArea.bottom = _focused_window->top + _focused_window->height; } else { cf.rcArea.left = _focused_window->left + _focused_window->nested_focus->pos_x; cf.rcArea.top = _focused_window->top + _focused_window->nested_focus->pos_y; cf.rcArea.right = cf.rcArea.left + _focused_window->nested_focus->current_x; cf.rcArea.bottom = cf.rcArea.top + _focused_window->nested_focus->current_y; } } else { cf.ptCurrentPos.x = 0; cf.ptCurrentPos.y = 0; SetRectEmpty(&cf.rcArea); } ImmSetCandidateWindow(hIMC, &cf); } ImmReleaseContext(hwnd, hIMC); }
LRESULT CDuiWkeWebkit::OnImeStartComposition( UINT uMsg, WPARAM wParam,LPARAM lParam ) { wkeRect caret = m_pWebView->getCaret(); CRect rcClient; GetClient(&rcClient); CANDIDATEFORM form; form.dwIndex = 0; form.dwStyle = CFS_EXCLUDE; form.ptCurrentPos.x = caret.x + rcClient.left; form.ptCurrentPos.y = caret.y + caret.h + rcClient.top; form.rcArea.top = caret.y + rcClient.top; form.rcArea.bottom = caret.y + caret.h + rcClient.top; form.rcArea.left = caret.x + rcClient.left; form.rcArea.right = caret.x + caret.w + rcClient.left; COMPOSITIONFORM compForm; compForm.ptCurrentPos=form.ptCurrentPos; compForm.rcArea=form.rcArea; compForm.dwStyle=CFS_POINT; HWND hWnd=GetContainer()->GetHostHwnd(); HIMC hIMC = ImmGetContext(hWnd); ImmSetCandidateWindow(hIMC, &form); ImmSetCompositionWindow(hIMC,&compForm); ImmReleaseContext(hWnd, hIMC); return 0; }
LRESULT CWkeWebkitWnd::OnImeStartComposition(UINT uMsg, WPARAM wParam,LPARAM lParam, BOOL& bHandled) { wkeRect caret = m_pWebView->getCaret(); RECT rcClient; GetClientRect(m_hWnd, &rcClient); CANDIDATEFORM form; form.dwIndex = 0; form.dwStyle = CFS_EXCLUDE; form.ptCurrentPos.x = caret.x + rcClient.left; form.ptCurrentPos.y = caret.y + caret.h + rcClient.top; form.rcArea.top = caret.y + rcClient.top; form.rcArea.bottom = caret.y + caret.h + rcClient.top; form.rcArea.left = caret.x + rcClient.left; form.rcArea.right = caret.x + caret.w + rcClient.left; COMPOSITIONFORM compForm; compForm.ptCurrentPos=form.ptCurrentPos; compForm.rcArea=form.rcArea; compForm.dwStyle=CFS_POINT; HWND hWnd=m_pOwner->GetManager()->GetPaintWindow(); HIMC hIMC = ImmGetContext(hWnd); ImmSetCandidateWindow(hIMC, &form); ImmSetCompositionWindow(hIMC,&compForm); ImmReleaseContext(hWnd, hIMC); //bHandled = TRUE; return 0; }
static HRESULT WINAPI ActiveIMMApp_SetCandidateWindow(IActiveIMMApp* This, HIMC hIMC, CANDIDATEFORM *pCandidate) { BOOL rc; rc = ImmSetCandidateWindow(hIMC,pCandidate); if (rc) return S_OK; else return E_FAIL; }
void CTextEditor::SetCandidateForm() { HIMC himc = ImmGetContext(_hwnd); if (himc) { RECT rc; RECT rcStart; RECT rcEnd; CANDIDATEFORM cf; cf.dwIndex = 0; cf.dwStyle = CFS_EXCLUDE; if (_layout.RectFromCharPos(_nCompStart, &rcStart) && _layout.RectFromCharPos(_nCompEnd, &rcEnd) && _layout.RectFromCharPos(_nSelEnd, &rc)) { cf.ptCurrentPos.x = rc.left; cf.ptCurrentPos.y = rc.bottom - 1; if (rcStart.top == rcEnd.top) { cf.rcArea.left = min(rcStart.left, rcEnd.left); cf.rcArea.right = max(rcStart.right, rcEnd.right); } else { RECT rcClient; GetClientRect(_hwnd, &rcClient); cf.rcArea.left = rcClient.left; cf.rcArea.right = rcClient.right; } cf.rcArea.top = min(rcStart.top, rcEnd.top); cf.rcArea.bottom = max(rcStart.bottom, rcEnd.bottom); } else { cf.ptCurrentPos.x = 0; cf.ptCurrentPos.y = 0; cf.rcArea.left = 0; cf.rcArea.right = 0; cf.rcArea.top = 0; cf.rcArea.bottom = 0; } ImmSetCandidateWindow(himc, &cf); } ImmReleaseContext(_hwnd, himc); }
void QWindowsInputContext::cursorRectChanged() { if (!m_compositionContext.hwnd) return; const QInputMethod *inputMethod = qApp->inputMethod(); QRect cursorRectangle = inputMethod->cursorRectangle().toRect(); if (!cursorRectangle.isValid()) return; if (QWindowsContext::verboseInputMethods) qDebug() << __FUNCTION__<< cursorRectangle; const HIMC himc = ImmGetContext(m_compositionContext.hwnd); if (!himc) return; // Move candidate list window to the microfocus position. COMPOSITIONFORM cf; // ### need X-like inputStyle config settings cf.dwStyle = CFS_FORCE_POSITION; cf.ptCurrentPos.x = cursorRectangle.x(); cf.ptCurrentPos.y = cursorRectangle.y(); CANDIDATEFORM candf; candf.dwIndex = 0; candf.dwStyle = CFS_EXCLUDE; candf.ptCurrentPos.x = cursorRectangle.x(); candf.ptCurrentPos.y = cursorRectangle.y() + cursorRectangle.height(); candf.rcArea.left = cursorRectangle.x(); candf.rcArea.top = cursorRectangle.y(); candf.rcArea.right = cursorRectangle.x() + cursorRectangle.width(); candf.rcArea.bottom = cursorRectangle.y() + cursorRectangle.height(); if (m_compositionContext.haveCaret) SetCaretPos(cursorRectangle.x(), cursorRectangle.y()); ImmSetCompositionWindow(himc, &cf); ImmSetCandidateWindow(himc, &candf); ImmReleaseContext(m_compositionContext.hwnd, himc); }
LONG CImeView::OnInputLangChange(WPARAM dwCommand, LPARAM dwData) { if (ImmIsIME(m_hKeyLayout) && m_property & IME_PROP_AT_CARET) ClearData(); // Set new keyboard layout. InitIme(); if(Enter()) { for (int i = 0; i < MAX_LISTCAND; i++) { CANDIDATEFORM cf; if (m_property & IME_PROP_AT_CARET) { /* // This application do not want to set candidate window to // any position. Anyway, if an application need to set the // candiadet position, it should remove the if 0 code // the position you want to set cf.dwIndex = i; cf.dwStyle = CFS_CANDIDATEPOS; cf.ptCurrentPos.x = ptAppWantPosition[i].x; cf.ptCurrentPos.y = ptAppWantPosition[i].y; ImmSetCandidateWindow(m_hIMC, &CandForm ); */ } else { if (!ImmGetCandidateWindow(m_hIMC, i, &cf)) continue; if (cf.dwStyle == CFS_DEFAULT) continue; cf.dwStyle = CFS_DEFAULT; ImmSetCandidateWindow(m_hIMC, &cf); } } Leave(); } return (LONG)DefWindowProc(m_hWnd,WM_INPUTLANGCHANGE, dwCommand, dwData); }
LRESULT CALLBACK MCWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static Boolean isactive = True; KeySym keysym; MCStack *target; _Drawable _dw; Drawable dw = &_dw; dw->type = DC_WINDOW; dw->handle.window = (MCSysWindowHandle)hwnd; MCScreenDC *pms = (MCScreenDC *)MCscreen; MCStack *omousestack = MCmousestackptr; uint2 button; Boolean down; char buffer[XLOOKUPSTRING_SIZE]; MCPoint t_mouseloc; t_mouseloc = MCPointMake(LOWORD(lParam), HIWORD(lParam)); // IM-2014-01-28: [[ HiDPI ]] Convert screen to logical coords t_mouseloc = ((MCScreenDC*)MCscreen)->screentologicalpoint(t_mouseloc); // MW-2005-02-20: Seed the SSL random number generator #ifdef MCSSL SeedSSL(msg, wParam, lParam); #endif if (curinfo == NULL) curinfo = &dummycurinfo; switch (msg) { #ifdef FEATURE_RELAUNCH_SUPPORT case WM_COPYDATA: { LRESULT t_result; COPYDATASTRUCT *t_data; t_data = (COPYDATASTRUCT *)lParam; t_result = 0; if (t_data -> dwData == CWM_RELAUNCH) { MCresult -> clear(); MCParameter *t_first_parameter = NULL; MCParameter *t_current_parameter = NULL; extern char *strndup(const char *, unsigned int); char *t_command_line = strndup((char *)t_data -> lpData, t_data -> cbData); char *sptr = t_command_line; while(*sptr) { if (*sptr == '\\') *sptr = '/'; sptr++; } sptr = t_command_line; while(*sptr) { char *t_argument; int t_argument_length; while (isspace(*sptr)) sptr++; t_argument_length = 0; if (*sptr == '"') { t_argument = ++sptr; while (*sptr && *sptr != '"') { sptr++; t_argument_length += 1; } } else { t_argument = sptr; while(*sptr && !isspace(*sptr)) { sptr++; t_argument_length += 1; } } if (t_argument_length != 0) { MCParameter *t_parameter; MCString t_param; t_param . set(t_argument, t_argument_length); t_parameter = new MCParameter(t_param); if (t_first_parameter == NULL) t_first_parameter = t_parameter; else t_current_parameter -> setnext(t_parameter); t_current_parameter = t_parameter; } if (*sptr) sptr++; } if (MCdispatcher -> gethome() -> message(MCM_relaunch, t_first_parameter, False, True) != ES_NORMAL) t_result = 0; else { MCExecPoint t_ep; MCresult -> fetch(t_ep); if (t_ep . getsvalue() == "background") t_result = (LRESULT)HWND_BOTTOM; else t_result = MCdefaultstackptr -> getwindow() == NULL ? (LRESULT)HWND_BOTTOM : (LRESULT)(MCdefaultstackptr -> getwindow() -> handle . window); } while(t_first_parameter != NULL) { MCParameter *t_next; t_next = t_first_parameter -> getnext(); delete t_first_parameter; t_first_parameter = t_next; } free(t_command_line); MCresult -> clear(); } return t_result; } #endif case CWM_TASKBAR_NOTIFICATION: ((MCScreenDC *)MCscreen) -> processtaskbarnotify(hwnd, wParam, lParam); break; case WM_DISPLAYCHANGE: case WM_SETTINGCHANGE: { if (hwnd != ((MCScreenDC *)MCscreen) -> getinvisiblewindow()) break; ((MCScreenDC *)MCscreen) -> processdesktopchanged(true); } break; case WM_PALETTECHANGED: dw->handle.window = (MCSysWindowHandle)wParam; if (MCdispatcher->findstackd(dw) == NULL) { dw->handle.window = (MCSysWindowHandle)hwnd; MCStack *sptr = MCdispatcher->findstackd(dw); if (sptr != NULL) sptr->dirtyall(); } break; case WM_PAINT: { MCStack *t_stack; t_stack = MCdispatcher -> findstackd(dw); if (t_stack != nil) t_stack -> onpaint(); } break; case WM_SETFOCUS: //FocusIn if (curinfo->dispatch) { if (MCtracewindow == DNULL || hwnd != (HWND)MCtracewindow->handle.window) { dw->handle.window = (MCSysWindowHandle)GetFocus(); MCdispatcher->wkfocus(dw); } curinfo->handled = True; } else { MCEventnode *tptr = new MCEventnode(hwnd, msg, wParam, lParam, 0, MCmodifierstate, MCeventtime); pms->appendevent(tptr); } break; case WM_KILLFOCUS: //FocusOut: if (curinfo->dispatch) { if (MCtracewindow == DNULL || hwnd != (HWND)MCtracewindow->handle.window) MCdispatcher->wkunfocus(dw); curinfo->handled = True; } else { MCEventnode *tptr = new MCEventnode(hwnd, msg, wParam, lParam, 0, MCmodifierstate, MCeventtime); pms->appendevent(tptr); } break; case WM_SYSKEYDOWN: case WM_SYSCHAR: case WM_CHAR: case WM_KEYDOWN: { if (wParam == VK_CONTROL) break; char t_input_char; t_input_char = (char)wParam; if (IsWindowUnicode(hwnd)) { if (wParam >= 128) { bool t_is_unicode; WCHAR t_wide[1]; // MW-2012-07-25: [[ Bug 9200 ]] Make sure we roundtrip the input character // through 1252 *not* the active code page (which could be anything). t_wide[0] = (WCHAR)wParam; t_is_unicode = (WideCharToMultiByte(1252, 0, t_wide, 1, &t_input_char, 1, NULL, NULL) == 0); if (!t_is_unicode) { WCHAR t_reverse_wide[1]; t_is_unicode = MultiByteToWideChar(1252, 0, &t_input_char, 1, t_reverse_wide, 1) == 0; if (!t_is_unicode) t_is_unicode = t_reverse_wide[0] != t_wide[0]; } if (t_is_unicode && (msg == WM_CHAR || msg == WM_SYSCHAR)) { if (MCactivefield) { MCString t_unicode_string; t_unicode_string . set((char *)t_wide, 2); // MW-2012-02-03: [[ Unicode Block ]] Use the new finsert method to insert // text in unicode mode. MCactivefield -> finsertnew(FT_IMEINSERT, t_unicode_string, LCH_UNICODE, true); } break; } } } else if (wParam >= 128 && (((MCScreenDC *)MCscreen) -> system_codepage) != (((MCScreenDC *)MCscreen) -> input_codepage)) { WCHAR t_unicode_char; MultiByteToWideChar((((MCScreenDC *)MCscreen) -> input_codepage), 0, &t_input_char, 1, &t_unicode_char, 1); bool t_is_unicode; t_is_unicode = (WideCharToMultiByte((((MCScreenDC *)MCscreen) -> system_codepage), 0, &t_unicode_char, 1, &t_input_char, 1, NULL, NULL) == 0); if (!t_is_unicode) { WCHAR t_reverse_unicode_char; t_is_unicode = MultiByteToWideChar((((MCScreenDC *)MCscreen) -> system_codepage), 0, &t_input_char, 1, &t_reverse_unicode_char, 1) == 0; if (!t_is_unicode) t_is_unicode = t_reverse_unicode_char != t_unicode_char; } if (t_is_unicode) { if (MCactivefield) { MCString t_unicode_string; t_unicode_string . set((char *)&t_unicode_char, 2); // MW-2012-02-03: [[ Unicode Block ]] Use the new finsert method to insert // text in unicode mode. MCactivefield -> finsertnew(FT_IMEINSERT, t_unicode_string, LCH_UNICODE, true); } break; } } if (msg == WM_CHAR || msg == WM_SYSCHAR) wParam = t_input_char; buffer[0] = buffer[1] = 0; if (msg == WM_CHAR || msg == WM_SYSCHAR) buffer[0] = lastchar = wParam; // MW-2010-11-17: [[ Bug 3892 ]] Ctrl+Alt can be the same as AltGr. // If we are a CHAR message *and* have a non-control character *and* have Ctrl+Alt set, we discard the modifiers if ((msg == WM_CHAR || msg == WM_SYSCHAR) && wParam >= 32 && (MCmodifierstate & (MS_CONTROL | MS_ALT)) == (MS_CONTROL | MS_ALT)) MCmodifierstate = 0; if (curinfo->keysym == 0) // event came from some other dispatch keysym = pms->getkeysym(wParam, lParam); else keysym = curinfo->keysym; lastkeysym = keysym; if (MCmodifierstate & MS_CONTROL) if (wParam == VK_CANCEL || keysym == '.') { if (MCallowinterrupts && !MCdefaultstackptr->cantabort()) curinfo->abort = True; else MCinterrupt = True; } else if (msg == WM_KEYDOWN) buffer[0] = lastchar = wParam; if (curinfo->dispatch) { if (MCtracewindow == DNULL || hwnd != (HWND)MCtracewindow->handle.window) { uint2 count = LOWORD(lParam); while (count--) { if (!MCdispatcher->wkdown(dw, buffer, keysym) && (msg == WM_SYSKEYDOWN || msg == WM_SYSCHAR)) return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); if (count || lParam & 0x40000000) MCdispatcher->wkup(dw, buffer, keysym); } curinfo->handled = curinfo->reset = True; } } else { MCEventnode *tptr = new MCEventnode(hwnd, msg, wParam, lParam, keysym, MCmodifierstate, MCeventtime); pms->appendevent(tptr); } } break; case WM_KEYUP: case WM_SYSKEYUP: { if (curinfo->keysym == 0) // event came from some other dispatch keysym = pms->getkeysym(wParam, lParam); else keysym = curinfo->keysym; if (keysym == lastkeysym) buffer[0] = lastchar; else buffer[0] = 0; buffer[1] = 0; if (curinfo->dispatch) { if (MCtracewindow == DNULL || hwnd != (HWND)MCtracewindow->handle.window) { MCeventtime = GetMessageTime(); //krevent->time; MCdispatcher->wkup(dw, buffer, keysym); curinfo->handled = curinfo->reset = True; } } else { MCEventnode *tptr = new MCEventnode(hwnd, msg, wParam, lParam, 0, MCmodifierstate, MCeventtime); pms->appendevent(tptr); } } break; case WM_IME_STARTCOMPOSITION: if (!MCinlineinput) return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); break; case WM_IME_ENDCOMPOSITION: if (!MCinlineinput) return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); break; case WM_IME_CHAR: { if (!MCactivefield) break; uint2 unicodekey = MAXUINT2; uint4 destlen; if (IsWindowUnicode(hwnd)) { unicodekey = wParam; destlen = 2; } else { char multibytechar[3]; multibytechar[0] = HIBYTE((WORD)wParam) ; multibytechar[1] = LOBYTE((WORD)wParam) ; multibytechar[2] = '\0'; MCU_multibytetounicode(multibytechar, 2, (char *)&unicodekey, 2, destlen, MCS_langidtocharset(LOWORD(GetKeyboardLayout(0)))); } MCString unicodestr; unicodestr.set((char *)&unicodekey, destlen); // MW-2012-02-03: [[ Unicode Block ]] Use the new finsert method to insert // text in unicode mode. MCactivefield->finsertnew(FT_IMEINSERT, unicodestr, 0, true); } break; case WM_IME_COMPOSITION: { if (!MCinlineinput) return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); if (!MCactivefield) break; DWORD dwindex = 0; if (lParam & GCS_RESULTSTR) { MCactivefield->stopcomposition(True,False); dwindex = GCS_RESULTSTR; } else if (lParam & GCS_COMPSTR) { MCactivefield->startcomposition(); dwindex = GCS_COMPSTR; } HIMC hIMC = ImmGetContext(hwnd); if (!hIMC || !dwindex) break; int2 cursorpos = LOWORD(ImmGetCompositionStringA(hIMC, GCS_CURSORPOS, NULL, 0)); MCactivefield->setcompositioncursoroffset(cursorpos << 1); uint2 compstrsize = 0; char *compstring = NULL; compstrsize = (uint2)ImmGetCompositionStringW(hIMC, dwindex, NULL, 0); compstring = new char[compstrsize+sizeof(WCHAR)]; ImmGetCompositionStringW(hIMC, dwindex, compstring, compstrsize); MCString unicodestr(compstring, compstrsize); // MW-2012-02-03: [[ Unicode Block ]] Use the new finsert method to insert // text in unicode mode. MCactivefield->finsertnew(FT_IMEINSERT, unicodestr, 0, true); delete compstring; ImmReleaseContext(hwnd, hIMC); } break; case WM_IME_NOTIFY: //sent when IME opens windows switch (wParam) { case IMN_OPENCANDIDATE: { HIMC hIMC = ImmGetContext(hwnd); DWORD imeprop = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY); if (imeprop & IME_PROP_AT_CARET) { if (MCactivefield) { uint1 i; for (i = 0; i < 4; i++) { MCRectangle r; CANDIDATEFORM cdf; cdf.dwIndex = i; cdf.dwStyle = CFS_CANDIDATEPOS; MCactivefield->getcompositionrect(r, -1); cdf.ptCurrentPos.x = r.x; cdf.ptCurrentPos.y = r.y + r.height + 32; cdf.rcArea.right = 1; cdf.rcArea.left = r.x; cdf.rcArea.top = r.y + r.height + 32; cdf.rcArea.bottom = 1; ImmSetCandidateWindow(hIMC, &cdf); } } } } break; case IMN_SETOPENSTATUS: { COMPOSITIONFORM cpf; HIMC hIMC = ImmGetContext(hwnd); cpf.dwStyle = CFS_DEFAULT; cpf.ptCurrentPos.x = 0; cpf.ptCurrentPos.y = 0; ImmSetCompositionWindow(hIMC, &cpf); ImmReleaseContext(hwnd, hIMC); } break; } return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); break; case WM_SETCURSOR: if (curinfo->live && !pms->isgrabbed() && LOWORD(lParam) != HTCLIENT) return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); MCmousestackptr = MCdispatcher->findstackd(dw); if (MCmousestackptr != NULL) { MCmousestackptr->resetcursor(True); if (pms->getmousetimer() == 0) pms->setmousetimer(timeSetEvent(LEAVE_CHECK_INTERVAL, 100, mouseproc, 0, TIME_ONESHOT)); } if (omousestack != MCmousestackptr) { if (omousestack != NULL && omousestack != MCtracestackptr) omousestack->munfocus(); if (MCmousestackptr != NULL && MCmousestackptr != MCtracestackptr) MCmousestackptr->enter(); } break; case WM_CAPTURECHANGED: if (curinfo->live) { if (pms->isgrabbed()) { MCStack *sptr = MCdispatcher->findstackd(dw); if (sptr != NULL) { if (lastdown != 0) sptr->mup(lastdown); buffer[0] = 0x1B; // escape buffer[1] = '\0'; Boolean oldlock = MClockmessages; MClockmessages = True; sptr->kdown(buffer, XK_Escape); sptr->kup(buffer, XK_Escape); MClockmessages = oldlock; sptr->munfocus(); pms->setgrabbed(False); curinfo->handled = True; } capturehwnd = NULL; } } break; case WM_MOUSEMOVE: //MotionNotify: case WM_NCMOUSEMOVE: // IM-2013-09-23: [[ FullscreenMode ]] Update mouseloc with MCscreen getters & setters MCStack *t_old_mousestack; MCPoint t_old_mouseloc; MCscreen->getmouseloc(t_old_mousestack, t_old_mouseloc); if (t_old_mouseloc.x != t_mouseloc.x || t_old_mouseloc.y != t_mouseloc.y) { MCscreen->setmouseloc(t_old_mousestack, t_mouseloc); if (curinfo->dispatch) { if (msg != WM_NCMOUSEMOVE) MCscreen->setmouseloc(MCdispatcher->findstackd(dw), t_mouseloc); if (MCtracewindow == DNULL || hwnd != (HWND)MCtracewindow->handle.window) { if (t_old_mousestack != NULL && MCmousestackptr != t_old_mousestack) t_old_mousestack->munfocus(); if (msg == WM_MOUSEMOVE) { MCPoint t_clickloc; MCStack *t_stackptr; MCscreen->getclickloc(t_stackptr, t_clickloc); MCdispatcher->wmfocus(dw, t_mouseloc.x, t_mouseloc.y); if (capturehwnd != NULL && MCbuttonstate != 0 && !dragclick && (MCU_abs(t_mouseloc.x - t_clickloc.x) >= MCdragdelta || MCU_abs(t_mouseloc.y - t_clickloc.y) >= MCdragdelta)) { dragclick = True; MCdispatcher -> wmdrag(dw); } } else if (MCmousestackptr != NULL) MCmousestackptr->munfocus(); curinfo->handled = True; } } else { MCEventnode *tptr = new MCEventnode(hwnd, msg, wParam, lParam, 0, MCmodifierstate, MCeventtime); pms->appendevent(tptr); } } if (msg == WM_NCMOUSEMOVE) return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); break; case WM_APP: if (MCmousestackptr != NULL && MCdispatcher->getmenu() == NULL) { POINT p; if (!GetCursorPos(&p) || !MCU_point_in_rect(MCmousestackptr->getrect(), (int2)p.x, (int2)p.y)) { if (MCmousestackptr != MCtracestackptr) MCmousestackptr->munfocus(); } else pms->setmousetimer(timeSetEvent(LEAVE_CHECK_INTERVAL, 100, mouseproc, 0, TIME_ONESHOT)); } curinfo->handled = True; break; case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP || msg == WM_LBUTTONDBLCLK) button = 1; else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP || msg == WM_MBUTTONDBLCLK) button = 2; else button = 3; if (msg == WM_LBUTTONUP || msg == WM_MBUTTONUP || msg == WM_RBUTTONUP) { if (curinfo->live && !pms->isgrabbed()) { ReleaseCapture(); capturehwnd = NULL; } MCbuttonstate &= ~(1L << (button - 1)); down = False; lastdown = 0; } else { if (curinfo->live && !pms->isgrabbed()) { SetCapture(hwnd); capturehwnd = hwnd; lastdown = button; } MCbuttonstate |= 1L << (button - 1); down = True; if (msg == WM_LBUTTONDBLCLK || msg == WM_MBUTTONDBLCLK || msg == WM_RBUTTONDBLCLK) doubledown = True; } if (curinfo->dispatch) { if (MCtracewindow == DNULL || hwnd != (HWND)MCtracewindow->handle.window) if (down) if (doubledown) MCdispatcher->wdoubledown(dw, button); else { if (doubleclick && MCeventtime - clicktime < MCdoubletime && MCU_abs(MCclicklocx - t_mouseloc.x) < MCdoubledelta && MCU_abs(MCclicklocy - t_mouseloc.y) < MCdoubledelta) tripleclick = True; else tripleclick = False; doubleclick = False; // IM-2013-09-23: [[ FullscreenMode ]] Update clickloc with MCscreen getters & setters MCscreen->setclickloc(MCmousestackptr, t_mouseloc); dragclick = False; MCdispatcher->wmfocus(dw, t_mouseloc.x, t_mouseloc.y); MCdispatcher->wmdown(dw, button); } else { if (doubledown) { doubledown = False; doubleclick = True; clicktime = MCeventtime; MCdispatcher->wdoubleup(dw, button); } else MCdispatcher->wmup(dw, button); } curinfo->handled = curinfo->reset = True; } else { MCEventnode *tptr = new MCEventnode(hwnd, msg, wParam, lParam, 0, MCmodifierstate, MCeventtime); pms->appendevent(tptr); } break; case WM_SIZE: { MCStack *target = MCdispatcher->findstackd(dw); if (target != NULL) { if (wParam == SIZE_MINIMIZED) target->iconify(); else if (target->isiconic()) { MCstacks->restack(target); target->view_configure(true); target->uniconify(); SetWindowPos((HWND)target -> getwindow() -> handle . window, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); } else target->view_configure(true); curinfo->handled = True; } } break; case WM_MOVE: MCdispatcher->configure(dw); curinfo->handled = True; break; case WM_CLOSE: MCdispatcher->wclose(dw); curinfo->handled = True; break; case WM_GETMINMAXINFO: target = MCdispatcher->findstackd(dw); if (target != NULL) target->constrain(lParam); break; case WM_ERASEBKGND: break; case WM_TIMER: curinfo->handled = True; if (MCmousestackptr != NULL && MCdispatcher->getmenu() == NULL) { int2 x, y; pms->querymouse(x, y); MCRectangle rect; if (pms->getwindowgeometry(MCmousestackptr->getw(), rect) && capturehwnd == NULL && !pms->getgrabbed() && !MCU_point_in_rect(rect, x, y)) { MCmousestackptr->munfocus(); MCmousestackptr = NULL; } } break; case WM_CANCELMODE: if (pms->isgrabbed()) { buffer[0] = 0x1B; buffer[1] = '\0'; Boolean oldlock = MClockmessages; MClockmessages = True; MCdispatcher->wkdown(dw, buffer, XK_Escape); MCdispatcher->wkup(dw, buffer, XK_Escape); MClockmessages = oldlock; curinfo->handled = True; pms->setgrabbed(False); MCmousex = MCmousey = -1; // prevent button msg from reopening menu MCdispatcher->wmfocus(dw, MCmousex, MCmousey); } break; case MM_MCINOTIFY: if (wParam == MCI_NOTIFY_SUCCESSFUL) { MCPlayer *tptr = MCplayers; while (tptr != NULL) { if (lParam == (LPARAM)tptr->getDeviceID()) { if (tptr->isdisposable()) tptr->playstop(); else tptr->message_with_args(MCM_play_stopped, tptr->getname()); break; } tptr = tptr->getnextplayer(); } curinfo->handled = True; } break; case WM_USER: { uint2 i; for (i = 0 ; i < MCnsockets ; i++) { if (MCsockets[i]->fd == 0) MCsockets[i]->readsome(); if (wParam == MCsockets[i]->fd && !MCsockets[i]->shared) break; } if (i < MCnsockets) { if (WSAGETSELECTERROR(lParam)) { MCsockets[i]->error = new char[16 + I4L]; sprintf(MCsockets[i]->error, "Error %d on socket", WSAGETSELECTERROR(lParam)); MCsockets[i]->doclose(); } else { /* I.M * TODO - look in to this further: * we sometimes get FD_READ, but there's no data ready to read * so trying to read when using SSL results in us getting stuck * in SSTATE_RETRYREAD, which won't be cleared until data is * available to read. As a quick fix, we can check the socket with select() */ int t_events = 0; TIMEVAL t_time = {0,0}; fd_set rmaskfd, wmaskfd, emaskfd; FD_ZERO(&rmaskfd); FD_ZERO(&wmaskfd); FD_ZERO(&emaskfd); FD_SET(wParam, &rmaskfd); FD_SET(wParam, &emaskfd); select(0, &rmaskfd, &wmaskfd, &emaskfd, &t_time); if (FD_ISSET(wParam, &emaskfd)) t_events = t_events; if (FD_ISSET(wParam, &rmaskfd)) t_events |= FD_READ; if (FD_ISSET(wParam, &wmaskfd)) t_events |= FD_WRITE; switch (WSAGETSELECTEVENT(lParam)) { case FD_OOB: // bogus, from MCS_read_socket case FD_READ: if (t_events & FD_READ) MCsockets[i]->readsome(); break; case FD_WRITE: MCsockets[i]->writesome(); MCsockets[i]->setselect(); break; case FD_CONNECT: MCsockets[i]->writesome(); MCsockets[i]->readsome(); MCsockets[i]->setselect(); break; case FD_ACCEPT: MCsockets[i]->acceptone(); break; case FD_CLOSE: MCsockets[i]->readsome(); #ifdef MCSSL if (MCsockets[i]->fd != 0 && !MCsockets[i]->secure) #else if (MCsockets[i]->fd != 0) #endif MCsockets[i]->doclose(); break; } } } curinfo->handled = True; break; } case WM_WINDOWPOSCHANGING: { ((MCScreenDC *)MCscreen) -> restackwindows(hwnd, msg, wParam, lParam); // return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); } break; case WM_POWERBROADCAST: MCS_reset_time(); return TRUE; case WM_THEMECHANGED: case WM_SYSCOLORCHANGE: if (hwnd == pms->getinvisiblewindow() && MCcurtheme && MCcurtheme->getthemeid() == LF_NATIVEWIN) { MCcurtheme->unload(); MCcurtheme->load(); // MW-2011-08-17: [[ Redraw ]] The theme has changed so redraw everything. MCRedrawDirtyScreen(); } break; case WM_ACTIVATEAPP: if (wParam != isactive) { MCstacks->hidepalettes(!wParam); ((MCScreenDC *)MCscreen) -> hidebackdrop(!wParam); if (MCdefaultstackptr != NULL) MCdefaultstackptr->getcard()->message(wParam ? MCM_resume : MCM_suspend); isactive = wParam; if (!wParam) { if (pms->taskbarhidden) { //we are suspended, show menu bar for other process pms->showtaskbar(); pms->taskbarhidden = True; } } else { if (pms->taskbarhidden) { pms->taskbarhidden = False; pms->hidetaskbar(); } } } break; case WM_INPUTLANGCHANGE: { LCID t_locale_id; t_locale_id = MAKELCID(lParam, SORT_DEFAULT); char t_info[8]; GetLocaleInfoA(t_locale_id, LOCALE_IDEFAULTANSICODEPAGE, t_info, 8); ((MCScreenDC *)MCscreen) -> input_codepage = atoi(t_info); ((MCScreenDC *)MCscreen) -> system_codepage = GetACP(); } break; case WM_NCACTIVATE: if (MCactivatepalettes && wParam == FALSE && MCstacks->getactive()) { MCStack *sptr = MCdispatcher->findstackd(dw); if (sptr != NULL && sptr->getmode() == WM_PALETTE) wParam = TRUE; } return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: if (MCmousestackptr != NULL) { MCObject *mfocused = MCmousestackptr->getcard()->getmfocused(); if (mfocused == NULL) mfocused = MCmousestackptr -> getcard(); if (mfocused != NULL) { int4 val = (short)HIWORD(wParam); if (msg == WM_MOUSEWHEEL) { if (val < 0) mfocused->kdown("", XK_WheelUp); else mfocused->kdown("", XK_WheelDown); } else if (msg == WM_MOUSEHWHEEL) { if (val < 0) mfocused->kdown("", XK_WheelLeft); else mfocused->kdown("", XK_WheelRight); } } } break; default: return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam); } return 0; }
/************************************************************************ * * InputChangeHandler - WM_INPUTLANGCHANGE handler * ************************************************************************/ void InputChangeHandler( HWND hWnd ) { HIMC hIMC; // // If the old keyboard layout is IME, the ime ui data have to be free. // if (ImmIsIME(hCurKL)) { // // If application prefers to use near caret provded by IME, or // IME provides special UI, then no need to clean UD data. // if ( gImeUIData.fdwProperty & IME_PROP_SPECIAL_UI ) ; else if ( gImeUIData.fdwProperty & IME_PROP_AT_CARET ) ImeUIClearData(hWnd); else ; } // // Set new keyboard layout. // hCurKL = GetKeyboardLayout(0L); // // Get new property. // gImeUIData.fdwProperty = ImmGetProperty( hCurKL, IGP_PROPERTY ); // if this application set the candidate position, it need to set // it to default for the near caret IME if ( hIMC = ImmGetContext( hWnd ) ) { UINT i; for (i = 0; i < 4; i++) { CANDIDATEFORM CandForm; if ( gImeUIData.fdwProperty & IME_PROP_AT_CARET ) { CandForm.dwIndex = i; CandForm.dwStyle = CFS_CANDIDATEPOS; #if 0 // This application dooes not want to set candidate window // to any position. If an application need to set the // candidate position, it should remove the if 0 code // the position you want to set CandForm.ptCurrentPos.x = ptAppWantPosition[i].x; CandForm.ptCurrentPos.y = ptAppWantPosition[i].y; ImmSetCandidateWindow( hIMC, &CandForm ); #endif } else { if ( !ImmGetCandidateWindow( hIMC, i, &CandForm ) ) { continue; } if ( CandForm.dwStyle == CFS_DEFAULT ) { continue; } CandForm.dwStyle = CFS_DEFAULT; ImmSetCandidateWindow( hIMC, &CandForm ); } } ImmReleaseContext( hWnd, hIMC ); } return; }
// wke窗口的windows消息处理 LRESULT CDuiWkeView::WebViewWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if( !GetRresponse() ) { return 0; } // 对于键盘消息,如果此控件不是焦点控件,则退出 if( message >= WM_KEYFIRST && message <= WM_KEYLAST ) { //if( !IsFocusControl() ) return 0; } bool handled = true; switch (message) { case WM_COMMAND: ::SendMessage(m_hWnd, message, wParam, lParam); return 0; /* case WM_PAINT: if (m_pWebView) { PAINTSTRUCT ps = { 0 }; HDC hDcPaint = ::BeginPaint(hWnd, &ps); RECT rcClip; ::GetClipBox(hDcPaint,&rcClip); RECT rcClient; ::GetClientRect(hWnd, &rcClient); RECT rcInvalid; ::IntersectRect(&rcInvalid, &rcClip,&rcClient); m_pWebView->paint(hDcPaint,rcInvalid.left,rcInvalid.top, rcInvalid.right - rcInvalid.left, rcInvalid.bottom - rcInvalid.top, rcInvalid.left-rcClient.left, rcInvalid.top-rcClient.top,true); ::EndPaint(hWnd, &ps); } break; */ case WM_SIZE: if (m_pWebView) { m_pWebView->resize(LOWORD(lParam), HIWORD(lParam)); m_render.resize(LOWORD(lParam), HIWORD(lParam)); } break; case WM_KEYDOWN: { OnWmKeyDown(hWnd, message, wParam, lParam); } break; case WM_KEYUP: { unsigned int virtualKeyCode = wParam; unsigned int flags = 0; if (HIWORD(lParam) & KF_REPEAT) flags |= WKE_REPEAT; if (HIWORD(lParam) & KF_EXTENDED) flags |= WKE_EXTENDED; //flags = HIWORD(lParam); handled = m_pWebView->keyUp(virtualKeyCode, flags, false); m_render.render(m_pWebView); } break; case WM_CHAR: case WM_IME_CHAR: { unsigned int charCode = wParam; unsigned int flags = 0; if (HIWORD(lParam) & KF_REPEAT) flags |= WKE_REPEAT; if (HIWORD(lParam) & KF_EXTENDED) flags |= WKE_EXTENDED; //flags = HIWORD(lParam); handled = m_pWebView->keyPress(charCode, flags, false); m_render.render(m_pWebView); } break; case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_MOUSEMOVE: { if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN) { SetFocus(hWnd); SetCapture(hWnd); } else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP) { ReleaseCapture(); } int x = GET_X_LPARAM(lParam); int y = GET_Y_LPARAM(lParam); unsigned int flags = 0; if (wParam & MK_CONTROL) flags |= WKE_CONTROL; if (wParam & MK_SHIFT) flags |= WKE_SHIFT; if (wParam & MK_LBUTTON) flags |= WKE_LBUTTON; if (wParam & MK_MBUTTON) flags |= WKE_MBUTTON; if (wParam & MK_RBUTTON) flags |= WKE_RBUTTON; //flags = wParam; handled = m_pWebView->mouseEvent(message, x, y, flags); m_render.render(m_pWebView); } break; case WM_CONTEXTMENU: { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); if (pt.x != -1 && pt.y != -1) ScreenToClient(hWnd, &pt); unsigned int flags = 0; if (wParam & MK_CONTROL) flags |= WKE_CONTROL; if (wParam & MK_SHIFT) flags |= WKE_SHIFT; if (wParam & MK_LBUTTON) flags |= WKE_LBUTTON; if (wParam & MK_MBUTTON) flags |= WKE_MBUTTON; if (wParam & MK_RBUTTON) flags |= WKE_RBUTTON; handled = m_pWebView->contextMenuEvent(pt.x, pt.y, flags); m_render.render(m_pWebView); } break; case WM_MOUSEWHEEL: { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); ScreenToClient(hWnd, &pt); int delta = GET_WHEEL_DELTA_WPARAM(wParam); unsigned int flags = 0; if (wParam & MK_CONTROL) flags |= WKE_CONTROL; if (wParam & MK_SHIFT) flags |= WKE_SHIFT; if (wParam & MK_LBUTTON) flags |= WKE_LBUTTON; if (wParam & MK_MBUTTON) flags |= WKE_MBUTTON; if (wParam & MK_RBUTTON) flags |= WKE_RBUTTON; //flags = wParam; handled = m_pWebView->mouseWheel(pt.x, pt.y, delta, flags); m_render.render(m_pWebView); } break; case WM_SETFOCUS: m_pWebView->focus(); m_render.render(m_pWebView); // 设置对话框的焦点控件为此控件 SetCurrentFocusControl(TRUE); break; case WM_KILLFOCUS: m_pWebView->unfocus(); m_render.render(m_pWebView); // 清除对话框的焦点控件 //SetCurrentFocusControl(FALSE); break; case WM_TIMER: m_render.render(m_pWebView); break; case WM_IME_STARTCOMPOSITION: { wkeRect caret = m_pWebView->getCaret(); CANDIDATEFORM form; form.dwIndex = 0; form.dwStyle = CFS_EXCLUDE; form.ptCurrentPos.x = caret.x; form.ptCurrentPos.y = caret.y + caret.h; form.rcArea.top = caret.y; form.rcArea.bottom = caret.y + caret.h; form.rcArea.left = caret.x; form.rcArea.right = caret.x + caret.w; HIMC hIMC = ImmGetContext(hWnd); ImmSetCandidateWindow(hIMC, &form); ImmReleaseContext(hWnd, hIMC); } break; default: handled = false; break; } if (!handled) return DefWindowProc(hWnd, message, wParam, lParam); return 0; }
LRESULT CWebWindow::_windowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_CREATE: { DragAcceptFiles(hwnd, TRUE); //SetTimer(hwnd, 100, 20, NULL); } return 0; case WM_CLOSE: if (m_windowClosingCallback) { if (!m_windowClosingCallback(this, m_windowClosingCallbackParam)) return 0; } ShowWindow(hwnd, SW_HIDE); DestroyWindow(hwnd); return 0; case WM_DESTROY: { //KillTimer(hwnd, 100); RemovePropW(hwnd, L"wkeWebWindow"); m_hwnd = NULL; if (m_windowDestroyCallback) m_windowDestroyCallback(this, m_windowDestroyCallbackParam); wkeDestroyWebView(this); } return 0; //case WM_TIMER: // { // wkeRepaintIfNeeded(this); // } // return 0; case WM_PAINT: { PAINTSTRUCT ps = { 0 }; HDC hdc = BeginPaint(hwnd, &ps); _paintDC(hdc, (HDC)wkeGetViewDC(this)); EndPaint(hwnd, &ps); } return 0; case WM_ERASEBKGND: return TRUE; case WM_SIZE: { RECT rc = { 0 }; GetClientRect(hwnd, &rc); int width = rc.right - rc.left; int height = rc.bottom - rc.top; CWebView::resize(width, height); wkeRepaintIfNeeded(this); } return 0; case WM_DROPFILES: { wchar_t szFile[MAX_PATH + 8] = {0}; wcscpy(szFile, L"file:///"); HDROP hDrop = reinterpret_cast<HDROP>(wParam); UINT uFilesCount = DragQueryFileW(hDrop, 0xFFFFFFFF, szFile, MAX_PATH); if (uFilesCount != 0) { UINT uRet = DragQueryFileW(hDrop, 0, (wchar_t*)szFile + 8, MAX_PATH); if ( uRet != 0) { wkeLoadURLW(this, szFile); SetWindowTextW(hwnd, szFile); } } DragFinish(hDrop); } return 0; //case WM_NCHITTEST: // if (IsWindow(m_hwnd) && flagsOff(GetWindowLong(m_hwnd, GWL_STYLE), WS_CAPTION)) // { // IWebkitObserverPtr observer = m_observer.lock(); // if (!observer) // break; // QPoint cursor(LOWORD(lParam), HIWORD(lParam)); // ScreenToClient(m_hwnd, &cursor); // QRect clientRect; // QSize clientSize; // GetClientRect(hwnd, &clientRect); // clientSize.cx = clientRect.width(); // clientSize.cy = clientRect.height(); // EWebkitHitTest hit = observer->onHitTest(QWebkitView(thisView), clientSize, cursor); // switch (hit) // { // case eWebkitHitLeftTop: return HTTOPLEFT; // case eWebkitHitLeft: return HTLEFT; // case eWebkitHitLeftBottom: return HTBOTTOMLEFT; // case eWebkitHitRightTop: return HTTOPRIGHT; // case eWebkitHitRight: return HTRIGHT; // case eWebkitHitRightBottom: return HTBOTTOMRIGHT; // case eWebkitHitTop: return HTTOP; // case eWebkitHitBottom: return HTBOTTOM; // case eWebkitHitCaption: return HTCAPTION; // case eWebkitHitClient: return HTCLIENT; // case eWebkitHitNone: return HTCLIENT; // } // } // break; //case WM_SETCURSOR: // if (IsWindow(m_hwnd) && flagsOff(GetWindowLong(m_hwnd, GWL_STYLE), WS_CAPTION)) // { // WORD hit = LOWORD(lParam); // switch (hit) // { // case HTCAPTION: // case HTSYSMENU: // case HTMENU: // case HTCLIENT: // SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); // return TRUE; // case HTTOP: // case HTBOTTOM: // SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS))); // return TRUE; // case HTLEFT: // case HTRIGHT: // SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE))); // return TRUE; // case HTTOPLEFT: // case HTBOTTOMRIGHT: // SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE))); // return TRUE; // case HTTOPRIGHT: // case HTBOTTOMLEFT: // SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW))); // return TRUE; // default: // SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); // return TRUE; // } // } // break; //case WM_NCLBUTTONDOWN: // if (IsWindow(m_hwnd) && flagsOff(GetWindowLong(m_hwnd, GWL_STYLE), WS_CAPTION)) // { // int hit = wParam; // switch (hit) // { // case HTTOP: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_TOP, lParam); return 0; // case HTBOTTOM: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_BOTTOM, lParam); return 0; // case HTLEFT: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_LEFT, lParam); return 0; // case HTRIGHT: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_RIGHT, lParam); return 0; // case HTTOPLEFT: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_TOPLEFT, lParam); return 0; // case HTTOPRIGHT: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_TOPRIGHT, lParam); return 0; // case HTBOTTOMLEFT: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_BOTTOMLEFT, lParam); return 0; // case HTBOTTOMRIGHT: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_SIZE|WMSZ_BOTTOMRIGHT, lParam); return 0; // case HTCAPTION: SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_MOVE|4, lParam); return 0; // } // } // break; //case WM_NCLBUTTONDBLCLK: // if (IsWindow(m_hwnd) && flagsOff(GetWindowLong(m_hwnd, GWL_STYLE), WS_CAPTION)) // { // int hit = wParam; // if (hit == HTCAPTION) // { // if (IsZoomed(m_hwnd)) // SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam); // else // SendMessageW(m_hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, lParam); // return 0; // } // } // break; case WM_KEYDOWN: { unsigned int virtualKeyCode = wParam; unsigned int flags = 0; if (HIWORD(lParam) & KF_REPEAT) flags |= WKE_REPEAT; if (HIWORD(lParam) & KF_EXTENDED) flags |= WKE_EXTENDED; if (wkeFireKeyDownEvent(this, virtualKeyCode, flags, false)) return 0; } break; case WM_KEYUP: { unsigned int virtualKeyCode = wParam; unsigned int flags = 0; if (HIWORD(lParam) & KF_REPEAT) flags |= WKE_REPEAT; if (HIWORD(lParam) & KF_EXTENDED) flags |= WKE_EXTENDED; if (wkeFireKeyUpEvent(this, virtualKeyCode, flags, false)) return 0; } break; case WM_CHAR: { unsigned int charCode = wParam; unsigned int flags = 0; if (HIWORD(lParam) & KF_REPEAT) flags |= WKE_REPEAT; if (HIWORD(lParam) & KF_EXTENDED) flags |= WKE_EXTENDED; if (wkeFireKeyPressEvent(this, charCode, flags, false)) return 0; } break; case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_MOUSEMOVE: { if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN) { SetFocus(hwnd); SetCapture(hwnd); } else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP) { ReleaseCapture(); } int x = LOWORD(lParam); int y = HIWORD(lParam); unsigned int flags = 0; if (wParam & MK_CONTROL) flags |= WKE_CONTROL; if (wParam & MK_SHIFT) flags |= WKE_SHIFT; if (wParam & MK_LBUTTON) flags |= WKE_LBUTTON; if (wParam & MK_MBUTTON) flags |= WKE_MBUTTON; if (wParam & MK_RBUTTON) flags |= WKE_RBUTTON; if (wkeFireMouseEvent(this, message, x, y, flags)) return 0; } break; case WM_CONTEXTMENU: { POINT pt; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); if (pt.x != -1 && pt.y != -1) ScreenToClient(hwnd, &pt); unsigned int flags = 0; if (wParam & MK_CONTROL) flags |= WKE_CONTROL; if (wParam & MK_SHIFT) flags |= WKE_SHIFT; if (wParam & MK_LBUTTON) flags |= WKE_LBUTTON; if (wParam & MK_MBUTTON) flags |= WKE_MBUTTON; if (wParam & MK_RBUTTON) flags |= WKE_RBUTTON; if (wkeFireContextMenuEvent(this, pt.x, pt.y, flags)) return 0; } break; case WM_MOUSEWHEEL: { POINT pt; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); ScreenToClient(hwnd, &pt); int delta = GET_WHEEL_DELTA_WPARAM(wParam); unsigned int flags = 0; if (wParam & MK_CONTROL) flags |= WKE_CONTROL; if (wParam & MK_SHIFT) flags |= WKE_SHIFT; if (wParam & MK_LBUTTON) flags |= WKE_LBUTTON; if (wParam & MK_MBUTTON) flags |= WKE_MBUTTON; if (wParam & MK_RBUTTON) flags |= WKE_RBUTTON; if (wkeFireMouseWheelEvent(this, pt.x, pt.y, delta, flags)) return 0; } break; case WM_SETFOCUS: wkeSetFocus(this); return 0; case WM_KILLFOCUS: wkeKillFocus(this); return 0; case WM_IME_STARTCOMPOSITION: { wkeRect caret = wkeGetCaretRect(this); CANDIDATEFORM form; form.dwIndex = 0; form.dwStyle = CFS_EXCLUDE; form.ptCurrentPos.x = caret.x; form.ptCurrentPos.y = caret.y + caret.h; form.rcArea.top = caret.y; form.rcArea.bottom = caret.y + caret.h; form.rcArea.left = caret.x; form.rcArea.right = caret.x + caret.w; COMPOSITIONFORM compForm; compForm.ptCurrentPos = form.ptCurrentPos; compForm.rcArea = form.rcArea; compForm.dwStyle = CFS_POINT; HIMC hIMC = ImmGetContext(hwnd); ImmSetCandidateWindow(hIMC, &form); ImmSetCompositionWindow(hIMC, &compForm); ImmReleaseContext(hwnd, hIMC); } return 0; } return DefWindowProcW(hwnd, message, wParam, lParam); }
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; }
LRESULT CALLBACK CompStrWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HIMC hIMC = NULL; HIMC hOldIMC = NULL; switch (message) { case WM_CREATE: hIMC = ImmCreateContext(); hOldIMC = ImmAssociateContext(hWnd,hIMC); SetWindowLongPtr(hWnd, 0, (LONG_PTR)hOldIMC); fdwProperty = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY); break; case WM_CHAR: HandleChar(hWnd,wParam,lParam); break; case WM_LBUTTONUP: /* fall-through */ case WM_RBUTTONUP: if (hIMC = ImmGetContext(hWnd)) { HMENU hMenu = NULL; InitMenuItemIDTable(); hMenu = CreateImeMenu(hWnd, hIMC, NULL,(message == WM_RBUTTONUP)); if (hMenu) { DWORD dwItemData; DWORD dwPos = (DWORD)GetMessagePos(); int nCmd; nCmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_NONOTIFY | TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_TOPALIGN, LOWORD(dwPos), HIWORD(dwPos), hWnd, NULL); if (nCmd) { nCmd -= IDM_STARTIMEMENU; dwItemData = FindItemData(nCmd); ImmNotifyIME(hIMC, NI_IMEMENUSELECTED, nCmd, dwItemData); } } EndMenuItemIDTable(); DestroyMenu(hMenu); } break; case WM_IME_SETCONTEXT: if (fShowCand) { lParam &= ~ISC_SHOWUICANDIDATEWINDOW; } if (fdwProperty & IME_PROP_SPECIAL_UI) { // EMPTY } else if (fdwProperty & IME_PROP_AT_CARET) { lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW; } else { // EMPTY } return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_IME_STARTCOMPOSITION: // Normally, we should not call into HandleStartComposition // for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs // we should pass this message to DefWindowProc directly for // this kind of IMEs HandleStartComposition(hWnd,wParam,lParam); // pass this message to DefWindowProc for IME_PROP_SPECIAL_UI // and not IME_PROP_AT_CARET IMEs if (fdwProperty & IME_PROP_SPECIAL_UI) { return (DefWindowProc(hWnd, message, wParam, lParam)); } else if (fdwProperty & IME_PROP_AT_CARET) { // EMPTY } else { return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case WM_IME_ENDCOMPOSITION: // Normally, we should not call into HandleEndComposition // for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs // we should pass this message to DefWindowProc directly for // this kind of IMEs HandleEndComposition(hWnd,wParam,lParam); // pass this message to DefWindowProc for IME_PROP_SPECIAL_UI // and not IME_PROP_AT_CARET IMEs if (fdwProperty & IME_PROP_SPECIAL_UI) { return (DefWindowProc(hWnd, message, wParam, lParam)); } else if (fdwProperty & IME_PROP_AT_CARET) { // EMPTY } else { return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case WM_IME_COMPOSITION: // Normally, we should not call into HandleComposition // for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs // we should pass this message to DefWindowProc directly for // this kind of IMEs HandleComposition(hWnd,wParam,lParam); // pass this message to DefWindowProc for IME_PROP_SPECIAL_UI // and not IME_PROP_AT_CARET IMEs if (fdwProperty & IME_PROP_SPECIAL_UI) { return (DefWindowProc(hWnd, message, wParam, lParam)); } else if (fdwProperty & IME_PROP_AT_CARET) { // EMPTY } else { return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case WM_PAINT: HandlePaint(hWnd,wParam,lParam); break; case WM_IME_NOTIFY: { LRESULT lRet; // Normally, we should not call into HandleNotify // for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs // we should pass this message to DefWindowProc directly for // this kind of IMEs lRet = HandleNotify(hWnd, message, wParam, lParam); // pass this message to DefWindowProc for IME_PROP_SPECIAL_UI // and not IME_PROP_AT_CARET IMEs if (fdwProperty & IME_PROP_SPECIAL_UI) { return (DefWindowProc(hWnd, message, wParam, lParam)); } else if (fdwProperty & IME_PROP_AT_CARET) { // EMPTY } else { return (DefWindowProc(hWnd, message, wParam, lParam)); } return lRet; } case WM_DESTROY: hOldIMC = (HIMC)GetWindowLongPtr(hWnd, 0); hIMC = ImmAssociateContext(hWnd, hOldIMC); ImmDestroyContext(hIMC); break; case WM_INPUTLANGCHANGE: fdwProperty = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY); if (hIMC = ImmGetContext(hWnd)) { CANDIDATEFORM cdf = {0}; if (fdwProperty & IME_PROP_AT_CARET) { cdf.dwIndex = 0; cdf.dwStyle = CFS_CANDIDATEPOS; cdf.ptCurrentPos.x = ptImeUIPos.x; cdf.ptCurrentPos.y = ptImeUIPos.y; ImmSetCandidateWindow(hIMC, &cdf); } else { UINT i; // The candidate position should be decided by a near caret // IME. There are 4 candidate form in the input context for (i = 0; i < 4; i++) { if (!ImmGetCandidateWindow(hIMC, i, &cdf)) { continue; } if (cdf.dwStyle == CFS_DEFAULT) { continue; } cdf.dwStyle = CFS_DEFAULT; ImmSetCandidateWindow(hIMC, &cdf); } } ImmReleaseContext(hWnd, hIMC); } return (DefWindowProc(hWnd, message, wParam, lParam)); default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return 0L; }