// Draw the System Icon void cef_dark_window::DoDrawSystemMenuIcon(HDC hdc) { if (mWindowIcon == 0) { // We haven't cached the icon yet so figure out // which one we need. // First try to load the small icon mWindowIcon = (HICON)SendMessage(WM_GETICON, ICON_SMALL, 0); // Otherwise try to use the big icon if (!mWindowIcon) mWindowIcon = (HICON)SendMessage(WM_GETICON, ICON_BIG, 0); // If that doesn't work check the window class for an icon // Start with the small if (!mWindowIcon) mWindowIcon = reinterpret_cast<HICON>(GetClassLongPtr(GCLP_HICONSM)); // Then try to load the big icon if (!mWindowIcon) mWindowIcon = reinterpret_cast<HICON>(GetClassLongPtr(GCLP_HICON)); // Otherwise we need an icon, so just use the standard Windows default // application Icon which may very between versions if (!mWindowIcon) mWindowIcon = ::LoadIcon(NULL, IDI_APPLICATION); } RECT rectIcon; ComputeWindowIconRect(rectIcon); ::DrawIconEx(hdc, rectIcon.left, rectIcon.top, mWindowIcon, ::RectWidth(rectIcon), ::RectHeight(rectIcon), 0, NULL, DI_NORMAL); }
// Computes the Rect where the window caption is drawn in window coordinates void cef_dark_aero_window::ComputeWindowCaptionRect(RECT& rect) const { if (CanUseAeroGlass()) { RECT wr; GetWindowRect(&wr); rect.top = ::kWindowFrameSize; rect.bottom = rect.top + mNcMetrics.iCaptionHeight; RECT ir; ComputeWindowIconRect(ir); RECT mr; ComputeMinimizeButtonRect(mr); rect.left = ir.right + ::kWindowFrameSize; rect.right = mr.left - ::kWindowFrameSize; } else { cef_dark_window::ComputeWindowCaptionRect(rect); } }
// Computes the Rect where the window caption is drawn in window coordinates void cef_dark_window::ComputeWindowCaptionRect(RECT& rect) { RECT wr; GetWindowRect(&wr); int top = mNcMetrics.iBorderWidth; if (IsZoomed()) { top = ::kWindowFrameZoomFactorCY; } rect.top = top; rect.bottom = rect.top + mNcMetrics.iCaptionHeight; RECT ir; ComputeWindowIconRect(ir); RECT mr; ComputeMinimizeButtonRect(mr); rect.left = ir.right + ::GetSystemMetrics (SM_CXFRAME); rect.right = mr.left - ::GetSystemMetrics (SM_CXFRAME); }
// WindowProc handles dispatching of messages and routing back to the base class or to Windows LRESULT cef_dark_aero_window::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { bool callDefWindowProc = true; switch (message) { case WM_MEASUREITEM: if (HandleMeasureItem((LPMEASUREITEMSTRUCT)lParam)) return 0L; break; case WM_DRAWITEM: if (HandleDrawItem((LPDRAWITEMSTRUCT)lParam)) return 0L; break; case WM_SETICON: mWindowIcon = 0; { RECT rectIcon; ComputeWindowIconRect(rectIcon); InvalidateRect(&rectIcon); } break; } // First let the DesktopWindowManager handle the message and tell us if // we should pass the message to the default window proc LRESULT lr = DwpCustomFrameProc(message, wParam, lParam, &callDefWindowProc); switch(message) { case WM_SETTINGCHANGE: HandleSettingChange((UINT)wParam, (LPCWSTR)lParam); break; case WM_NCACTIVATE: case WM_ACTIVATE: if (mReady) { UpdateNonClientArea(); } break; case WM_NCMOUSELEAVE: // NOTE: We want anyone else interested in this message // to be notified. Otherwise the default implementation // may be in the wrong state HandleNcMouseLeave(); break; case WM_NCMOUSEMOVE: { POINT pt; POINTSTOPOINT(pt, lParam); if (HandleNcMouseMove((UINT)wParam, &pt)) return 0L; } break; case WM_NCLBUTTONDOWN: { POINT pt; POINTSTOPOINT(pt, lParam); if (HandleNcLeftButtonDown((UINT)wParam, &pt)) return 0L; } break; case WM_NCLBUTTONUP: { POINT pt; POINTSTOPOINT(pt, lParam); if (HandleNcLeftButtonUp((UINT)wParam, &pt)) return 0L; } break; } // call DefWindowProc? if (!callDefWindowProc) { return lr; } lr = cef_window::WindowProc(message, wParam, lParam); if (!mReady) return lr; switch (message) { case WM_GETMINMAXINFO: HandleGetMinMaxInfo((LPMINMAXINFO) lParam); break; case WM_SETTEXT: case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: case WM_MOVE: case WM_SIZE: case WM_SIZING: case WM_EXITSIZEMOVE: UpdateNonClientArea(); if (message == WM_WINDOWPOSCHANGED) { RECT rect; ComputeMenuBarRect(rect); InvalidateRect(&rect, TRUE); } break; case WM_EXITMENULOOP: mMenuActiveIndex = -1; break; case WM_ACTIVATEAPP: mIsActive = (BOOL)wParam; UpdateNonClientArea(); break; } return lr; }
// WM_NCHITTEST handler int cef_dark_aero_window::HandleNcHitTest(LPPOINT ptHit) { RECT rectWindow; GetWindowRect(&rectWindow); if (!::PtInRect(&rectWindow, *ptHit)) return HTNOWHERE; RECT rectCaption; ComputeWindowCaptionRect(rectCaption); ClientToScreen(&rectCaption); if (::PtInRect(&rectCaption, *ptHit)) return HTCAPTION; RECT rectCloseButton; ComputeCloseButtonRect(rectCloseButton); ClientToScreen(&rectCloseButton); if (::PtInRect(&rectCloseButton, *ptHit)) return HTCLOSE; RECT rectMaximizeButton; ComputeMaximizeButtonRect(rectMaximizeButton); ClientToScreen(&rectMaximizeButton); if (::PtInRect(&rectMaximizeButton, *ptHit)) return HTMAXBUTTON; RECT rectMinimizeButton; ComputeMinimizeButtonRect(rectMinimizeButton); ClientToScreen(&rectMinimizeButton); if (::PtInRect(&rectMinimizeButton, *ptHit)) return HTMINBUTTON; RECT rectSysIcon; ComputeWindowIconRect(rectSysIcon); ClientToScreen(&rectSysIcon); if (::PtInRect(&rectSysIcon, *ptHit)) return HTSYSMENU; if (!IsZoomed()) { // Left Border if (ptHit->x >= rectWindow.left && ptHit->x <= rectWindow.left + ::kWindowFrameSize) { // it's important that we know if the mouse is on a corner so that // the right mouse cursor is displayed if (ptHit->y <= rectWindow.top + ::kWindowFrameSize) return HTTOPLEFT; if (ptHit->y >= rectWindow.bottom - ::kWindowFrameSize) return HTBOTTOMLEFT; return HTLEFT; } // Right Border if (ptHit->x <= rectWindow.right && ptHit->x >= rectWindow.right - ::kWindowFrameSize) { // it's important that we know if the mouse is on a corner so that // the right mouse cursor is displayed if (ptHit->y <= rectWindow.top + ::kWindowFrameSize) return HTTOPRIGHT; if (ptHit->y >= rectWindow.bottom - ::kWindowFrameSize) return HTBOTTOMRIGHT; return HTRIGHT; } // Top and Bottom Borders if (ptHit->y <= rectWindow.top + ::kWindowFrameSize) return HTTOP; if (ptHit->y >= rectWindow.bottom - ::kWindowFrameSize) return HTBOTTOM; } RECT rectMenu; ComputeRequiredMenuRect(rectMenu); ClientToScreen(&rectMenu); if (::PtInRect(&rectMenu, *ptHit)) return HTMENU; // If it's in the menu bar but not actually // on a menu item, then return caption so // the window can be dragged from the dead space ComputeMenuBarRect(rectMenu); ClientToScreen(&rectMenu); if (::PtInRect(&rectMenu, *ptHit)) return HTCAPTION; // Aero requires that we return HTNOWHERE return HTNOWHERE; }
// WM_NCHITTEST handler int cef_dark_window::HandleNcHitTest(LPPOINT ptHit) { RECT rectWindow; GetWindowRect(&rectWindow); if (!::PtInRect(&rectWindow, *ptHit)) return HTNOWHERE; RECT rectClient; GetClientRect(&rectClient); ClientToScreen(&rectClient); if (::PtInRect(&rectClient, *ptHit)) return HTCLIENT; RECT rectCaption; ComputeWindowCaptionRect(rectCaption); NonClientToScreen(&rectCaption); if (::PtInRect(&rectCaption, *ptHit)) return HTCAPTION; RECT rectCloseButton; ComputeCloseButtonRect(rectCloseButton); NonClientToScreen(&rectCloseButton); if (::PtInRect(&rectCloseButton, *ptHit)) return HTCLOSE; RECT rectMaximizeButton; ComputeMaximizeButtonRect(rectMaximizeButton); NonClientToScreen(&rectMaximizeButton); if (::PtInRect(&rectMaximizeButton, *ptHit)) return HTMAXBUTTON; RECT rectMinimizeButton; ComputeMinimizeButtonRect(rectMinimizeButton); NonClientToScreen(&rectMinimizeButton); if (::PtInRect(&rectMinimizeButton, *ptHit)) return HTMINBUTTON; RECT rectSysIcon; ComputeWindowIconRect(rectSysIcon); NonClientToScreen(&rectSysIcon); if (::PtInRect(&rectSysIcon, *ptHit)) return HTSYSMENU; // Left Border if (ptHit->x >= rectWindow.left && ptHit->x <= rectWindow.left + ::GetSystemMetrics (SM_CYFRAME)) { // it's important that we know if the mouse is on a corner so that // the right mouse cursor is displayed if (ptHit->y <= rectWindow.top + ::GetSystemMetrics (SM_CYFRAME)) return HTTOPLEFT; if (ptHit->y >= rectWindow.bottom - ::GetSystemMetrics (SM_CYFRAME)) return HTBOTTOMLEFT; return HTLEFT; } // Right Border if (ptHit->x <= rectWindow.right && ptHit->x >= rectWindow.right - ::GetSystemMetrics (SM_CYFRAME)) { // it's important that we know if the mouse is on a corner so that // the right mouse cursor is displayed if (ptHit->y <= rectWindow.top + ::GetSystemMetrics (SM_CYFRAME)) return HTTOPRIGHT; if (ptHit->y >= rectWindow.bottom - ::GetSystemMetrics (SM_CYFRAME)) return HTBOTTOMRIGHT; return HTRIGHT; } // Top and Bottom Borders if (ptHit->y <= rectWindow.top + ::GetSystemMetrics (SM_CYFRAME)) return HTTOP; if (ptHit->y >= rectWindow.bottom - ::GetSystemMetrics (SM_CYFRAME)) return HTBOTTOM; // If it's not in the menu, it's in the caption RECT rectMenu; ComputeRequiredMenuRect(rectMenu); NonClientToScreen(&rectMenu); if (::PtInRect(&rectMenu, *ptHit)) return HTMENU; return HTCAPTION; }