//----------------------------------------------------------------------------- void nsCaret::StopBlinking() { if (mDrawn) // erase the caret if necessary DrawCaret(PR_TRUE); NS_ASSERTION(!mDrawn, "Caret still drawn after StopBlinking()."); KillTimer(); }
//----------------------------------------------------------------------------- void nsCaret::StartBlinking() { if (mReadOnly) { // Make sure the one draw command we use for a readonly caret isn't // done until the selection is set DrawCaretAfterBriefDelay(); return; } PrimeTimer(); // If we are currently drawn, then the second call to DrawCaret below will // actually erase the caret. That would cause the caret to spend an "off" // cycle before it appears, which is not really what we want. This first // call to DrawCaret makes sure that the first cycle after a call to // StartBlinking is an "on" cycle. if (mDrawn) DrawCaret(PR_TRUE); DrawCaret(PR_TRUE); // draw it right away }
void nsCaret::UpdateCaretPosition() { // We'll recalculate anyway if we're not drawn right now. if (!mDrawn) return; // A trick! Make the DrawCaret code recalculate the caret's current // position. mDrawn = PR_FALSE; DrawCaret(PR_FALSE); }
void nsCaret::EraseCaret() { if (mDrawn) { DrawCaret(PR_TRUE); if (mReadOnly && mBlinkRate) { // If readonly we don't have a blink timer set, so caret won't // be redrawn automatically. We need to force the caret to get // redrawn right after the paint DrawCaretAfterBriefDelay(); } } }
nsresult nsCaret::CheckCaretDrawingState() { if (mDrawn) { // The caret is drawn; if it shouldn't be, erase it. if (!mVisible || !MustDrawCaret(PR_TRUE)) EraseCaret(); } else { // The caret is not drawn; if it should be, draw it. if (mPendingDraw && (mVisible && MustDrawCaret(PR_TRUE))) DrawCaret(PR_TRUE); } return NS_OK; }
LRESULT WINAPI User32DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL bUnicode) { PWND pWnd = NULL; if (hWnd) { pWnd = ValidateHwnd(hWnd); if (!pWnd) return 0; } switch (Msg) { case WM_NCPAINT: { return DefWndNCPaint(hWnd, (HRGN)wParam, -1); } case WM_NCCALCSIZE: { return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam); } case WM_POPUPSYSTEMMENU: { /* This is an undocumented message used by the windows taskbar to display the system menu of windows that belong to other processes. */ HMENU menu = GetSystemMenu(hWnd, FALSE); if (menu) TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON, LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL); return 0; } case WM_NCACTIVATE: { return DefWndNCActivate(hWnd, wParam, lParam); } case WM_NCHITTEST: { POINT Point; Point.x = GET_X_LPARAM(lParam); Point.y = GET_Y_LPARAM(lParam); return (DefWndNCHitTest(hWnd, Point)); } case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: iF10Key = iMenuSysKey = 0; break; case WM_NCLBUTTONDOWN: { return (DefWndNCLButtonDown(hWnd, wParam, lParam)); } case WM_LBUTTONDBLCLK: return (DefWndNCLButtonDblClk(hWnd, HTCLIENT, lParam)); case WM_NCLBUTTONDBLCLK: { return (DefWndNCLButtonDblClk(hWnd, wParam, lParam)); } case WM_NCRBUTTONDOWN: return NC_HandleNCRButtonDown( hWnd, wParam, lParam ); case WM_RBUTTONUP: { POINT Pt; Pt.x = GET_X_LPARAM(lParam); Pt.y = GET_Y_LPARAM(lParam); ClientToScreen(hWnd, &Pt); lParam = MAKELPARAM(Pt.x, Pt.y); if (bUnicode) { SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); } else { SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); } break; } case WM_NCRBUTTONUP: /* * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked * in Windows), but what _should_ we do? According to MSDN : * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND * message to the window". When is it appropriate? */ break; case WM_CONTEXTMENU: { if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) { if (bUnicode) { SendMessageW(GetParent(hWnd), Msg, wParam, lParam); } else { SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam); } } else { POINT Pt; LONG_PTR Style; LONG HitCode; Style = GetWindowLongPtrW(hWnd, GWL_STYLE); Pt.x = GET_X_LPARAM(lParam); Pt.y = GET_Y_LPARAM(lParam); if (Style & WS_CHILD) { ScreenToClient(GetParent(hWnd), &Pt); } HitCode = DefWndNCHitTest(hWnd, Pt); if (HitCode == HTCAPTION || HitCode == HTSYSMENU) { HMENU SystemMenu; UINT Flags; if((SystemMenu = GetSystemMenu(hWnd, FALSE))) { MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE), GetClassLongPtrW(hWnd, GCL_STYLE), HitCode); if(HitCode == HTCAPTION) Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON; else Flags = TPM_LEFTBUTTON; TrackPopupMenu(SystemMenu, Flags, Pt.x, Pt.y, 0, hWnd, NULL); } } } break; } case WM_PRINT: { DefWndPrint(hWnd, (HDC)wParam, lParam); return (0); } case WM_SYSCOLORCHANGE: { /* force to redraw non-client area */ DefWndNCPaint(hWnd, HRGN_WINDOW, -1); /* Use InvalidateRect to redraw client area, enable * erase to redraw all subcontrols otherwise send the * WM_SYSCOLORCHANGE to child windows/controls is required */ InvalidateRect(hWnd,NULL,TRUE); return (0); } case WM_PAINTICON: case WM_PAINT: { PAINTSTRUCT Ps; HDC hDC; /* If already in Paint and Client area is not empty just return. */ if (pWnd->state2 & WNDS2_STARTPAINT && !IsRectEmpty(&pWnd->rcClient)) { ERR("In Paint and Client area is not empty!\n"); return 0; } hDC = BeginPaint(hWnd, &Ps); if (hDC) { HICON hIcon; if (IsIconic(hWnd) && ((hIcon = (HICON)GetClassLongPtrW( hWnd, GCLP_HICON)))) { RECT ClientRect; INT x, y; GetClientRect(hWnd, &ClientRect); x = (ClientRect.right - ClientRect.left - GetSystemMetrics(SM_CXICON)) / 2; y = (ClientRect.bottom - ClientRect.top - GetSystemMetrics(SM_CYICON)) / 2; DrawIcon(hDC, x, y, hIcon); } EndPaint(hWnd, &Ps); } return (0); } case WM_CLOSE: DestroyWindow(hWnd); return (0); case WM_MOUSEACTIVATE: if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) { LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam); if (Ret) return (Ret); } return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE ); case WM_ACTIVATE: /* The default action in Windows is to set the keyboard focus to * the window, if it's being activated and not minimized */ if (LOWORD(wParam) != WA_INACTIVE && !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE)) { //ERR("WM_ACTIVATE %p\n",hWnd); SetFocus(hWnd); } break; case WM_MOUSEWHEEL: if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam); break; case WM_ERASEBKGND: case WM_ICONERASEBKGND: { RECT Rect; HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND); if (NULL == hBrush) { return 0; } if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC) { /* can't use GetClipBox with a parent DC or we fill the whole parent */ GetClientRect(hWnd, &Rect); DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2); } else { GetClipBox((HDC)wParam, &Rect); } FillRect((HDC)wParam, &Rect, hBrush); return (1); } case WM_CTLCOLORMSGBOX: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: case WM_CTLCOLORSCROLLBAR: return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX); case WM_CTLCOLOR: return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); case WM_SETCURSOR: { LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE); if (Style & WS_CHILD) { /* with the exception of the border around a resizable wnd, * give the parent first chance to set the cursor */ if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT) { HWND parent = GetParent( hWnd ); if (bUnicode) { if (parent != GetDesktopWindow() && SendMessageW( parent, WM_SETCURSOR, wParam, lParam)) return TRUE; } else { if (parent != GetDesktopWindow() && SendMessageA( parent, WM_SETCURSOR, wParam, lParam)) return TRUE; } } } return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style)); } case WM_SYSCOMMAND: return (DefWndHandleSysCommand(hWnd, wParam, lParam)); case WM_KEYDOWN: if(wParam == VK_F10) iF10Key = VK_F10; break; case WM_SYSKEYDOWN: { if (HIWORD(lParam) & KF_ALTDOWN) { /* Previous state, if the key was down before this message, this is a cheap way to ignore autorepeat keys. */ if ( !(HIWORD(lParam) & KF_REPEAT) ) { if ( ( wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU ) && !iMenuSysKey ) iMenuSysKey = 1; else iMenuSysKey = 0; } iF10Key = 0; if (wParam == VK_F4) /* Try to close the window */ { HWND top = GetAncestor(hWnd, GA_ROOT); if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE)) PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0); } else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT? { HWND hwnd = hWnd; while (GetParent(hwnd) != NULL) { hwnd = GetParent(hwnd); } DefWndScreenshot(hwnd); } else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC { WPARAM wParamTmp; HWND Active = GetActiveWindow(); // Noticed MDI problem. if (!Active) { FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n"); break; } wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW; SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam ); } } else if( wParam == VK_F10 ) { if (GetKeyState(VK_SHIFT) & 0x8000) SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1) ); iF10Key = 1; } break; } case WM_KEYUP: case WM_SYSKEYUP: { /* Press and release F10 or ALT */ if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU) && iMenuSysKey) || ((wParam == VK_F10) && iF10Key)) SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L ); iMenuSysKey = iF10Key = 0; break; } case WM_SYSCHAR: { iMenuSysKey = 0; if (wParam == VK_RETURN && IsIconic(hWnd)) { PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L ); break; } if ((HIWORD(lParam) & KF_ALTDOWN) && wParam) { if (wParam == VK_TAB || wParam == VK_ESCAPE) break; if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) SendMessageW( GetParent(hWnd), Msg, wParam, lParam ); else SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam ); } else /* check for Ctrl-Esc */ if (wParam != VK_ESCAPE) MessageBeep(0); break; } case WM_CANCELMODE: { iMenuSysKey = 0; /* FIXME: Check for a desktop. */ //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu(); MENU_EndMenu( hWnd ); if (GetCapture() == hWnd) { ReleaseCapture(); } break; } case WM_VKEYTOITEM: case WM_CHARTOITEM: return (-1); /* case WM_DROPOBJECT: return DRAG_FILE; */ case WM_QUERYDROPOBJECT: { if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES) { return(1); } break; } case WM_QUERYDRAGICON: { UINT Len; HICON hIcon; hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON); if (hIcon) { return ((LRESULT)hIcon); } for (Len = 1; Len < 64; Len++) { if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL) { return((LRESULT)hIcon); } } return ((LRESULT)LoadIconW(0, IDI_APPLICATION)); } case WM_ISACTIVEICON: { BOOL isai; isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0; return isai; } case WM_NOTIFYFORMAT: { if (lParam == NF_QUERY) return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI; break; } case WM_SETICON: { return DefWndSetIcon(pWnd, wParam, lParam); } case WM_GETICON: { return DefWndGetIcon(pWnd, wParam, lParam); } case WM_HELP: { if (bUnicode) { SendMessageW(GetParent(hWnd), Msg, wParam, lParam); } else { SendMessageA(GetParent(hWnd), Msg, wParam, lParam); } break; } case WM_SYSTIMER: { THRDCARETINFO CaretInfo; switch(wParam) { case 0xffff: /* Caret timer */ /* switch showing byte in win32k and get information about the caret */ if(NtUserxSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd)) { DrawCaret(hWnd, &CaretInfo); } break; } break; } case WM_QUERYOPEN: case WM_QUERYENDSESSION: { return (1); } case WM_INPUTLANGCHANGEREQUEST: { HKL NewHkl; if(wParam & INPUTLANGCHANGE_BACKWARD && wParam & INPUTLANGCHANGE_FORWARD) { return FALSE; } //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ? if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV; else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT; else NewHkl = (HKL) lParam; NtUserActivateKeyboardLayout(NewHkl, 0); return TRUE; } case WM_INPUTLANGCHANGE: { int count = 0; HWND *win_array = WIN_ListChildren( hWnd ); if (!win_array) break; while (win_array[count]) SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam); HeapFree(GetProcessHeap(),0,win_array); break; } case WM_QUERYUISTATE: { LRESULT Ret = 0; PWND Wnd = ValidateHwnd(hWnd); if (Wnd != NULL) { if (Wnd->HideFocus) Ret |= UISF_HIDEFOCUS; if (Wnd->HideAccel) Ret |= UISF_HIDEACCEL; } return Ret; } case WM_CHANGEUISTATE: { BOOL AlwaysShowCues = FALSE; WORD Action = LOWORD(wParam); WORD Flags = HIWORD(wParam); PWND Wnd; SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); if (AlwaysShowCues) break; Wnd= ValidateHwnd(hWnd); if (!Wnd || lParam != 0) break; if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) break; if (Flags & UISF_ACTIVE) { WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n"); } if (Action == UIS_INITIALIZE) { PDESKTOPINFO Desk = GetThreadDesktopInfo(); if (Desk == NULL) break; Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; /* We need to update wParam in case we need to send out messages */ wParam = MAKEWPARAM(Action, Flags); } switch (Action) { case UIS_SET: /* See if we actually need to change something */ if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) break; if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) break; /* Don't need to do anything... */ return 0; case UIS_CLEAR: /* See if we actually need to change something */ if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) break; if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) break; /* Don't need to do anything... */ return 0; default: WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action); break; } if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL) { /* We're a child window and we need to pass this message down until we reach the root */ hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent)); } else { /* We're a top level window, we need to change the UI state */ Msg = WM_UPDATEUISTATE; } if (bUnicode) return SendMessageW(hWnd, Msg, wParam, lParam); else return SendMessageA(hWnd, Msg, wParam, lParam); } case WM_UPDATEUISTATE: { BOOL Change = TRUE; BOOL AlwaysShowCues = FALSE; WORD Action = LOWORD(wParam); WORD Flags = HIWORD(wParam); PWND Wnd; SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); if (AlwaysShowCues) break; Wnd = ValidateHwnd(hWnd); if (!Wnd || lParam != 0) break; if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) break; if (Flags & UISF_ACTIVE) { WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n"); } if (Action == UIS_INITIALIZE) { PDESKTOPINFO Desk = GetThreadDesktopInfo(); if (Desk == NULL) break; Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; /* We need to update wParam for broadcasting the update */ wParam = MAKEWPARAM(Action, Flags); } switch (Action) { case UIS_SET: /* See if we actually need to change something */ if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) break; if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) break; /* Don't need to do anything... */ Change = FALSE; break; case UIS_CLEAR: /* See if we actually need to change something */ if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) break; if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) break; /* Don't need to do anything... */ Change = FALSE; break; default: WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action); return 0; } /* Pack the information and call win32k */ if (Change) { if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3))) break; } /* Always broadcast the update to all children */ EnumChildWindows(hWnd, UserSendUiUpdateMsg, (LPARAM)wParam); break; } /* Move to Win32k !*/ case WM_SHOWWINDOW: if (!lParam) break; // Call when it is necessary. case WM_SYNCPAINT: case WM_SETREDRAW: case WM_CLIENTSHUTDOWN: case WM_GETHOTKEY: case WM_SETHOTKEY: case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: case WM_APPCOMMAND: { LRESULT lResult; NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode); return lResult; } } return 0; }