// Like UpdateNonClientArea, but sets up a clipping region to just update the system buttons void cef_dark_window::UpdateNonClientButtons () { // create a simple clipping region // that only includes the system buttons (min/max/restore/close) HDC hdc = GetWindowDC(); RECT rectCloseButton ; ComputeCloseButtonRect (rectCloseButton) ; RECT rectMaximizeButton ; ComputeMaximizeButtonRect (rectMaximizeButton) ; RECT rectMinimizeButton ; ComputeMinimizeButtonRect (rectMinimizeButton) ; RECT rectWindow ; ComputeLogicalWindowRect (rectWindow) ; ::ExcludeClipRect (hdc, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom); RECT rectButtons; rectButtons.top = rectCloseButton.top; rectButtons.right = rectCloseButton.right; rectButtons.bottom = rectCloseButton.bottom; rectButtons.left = rectMinimizeButton.left; HRGN hrgnUpdate = ::CreateRectRgnIndirect(&rectButtons); if (::SelectClipRgn(hdc, hrgnUpdate) != NULLREGION) { DoPaintNonClientArea(hdc); } ::DeleteObject(hrgnUpdate); ReleaseDC(hdc); }
// Computes the Rect where the minimize button is drawn in window coordinates void cef_dark_window::ComputeMinimizeButtonRect(RECT& rect) { ComputeMaximizeButtonRect(rect); rect.left -= (mSysMinimizeButton->GetWidth() + 1); rect.right = rect.left + mSysMinimizeButton->GetWidth(); rect.bottom = rect.top + mSysMinimizeButton->GetHeight(); }
// Draw the System Icons (close/min/max/restore) void cef_dark_window::DoDrawSystemIcons(HDC hdc) { Gdiplus::Image* CloseButton = mSysCloseButton; Gdiplus::Image* RestoreButton = mSysRestoreButton; Gdiplus::Image* MinimizeButton = mSysMinimizeButton; Gdiplus::Image* MaximizeButton = mSysMaximizeButton; if (mNonClientData.mButtonOver) { // If the mouse is over or down on a button then // we need to pick the correct image for that button's state switch (mNonClientData.mActiveButton) { case HTCLOSE: CloseButton = (mNonClientData.mButtonDown) ? mPressedSysCloseButton : mHoverSysCloseButton; break; case HTMAXBUTTON: RestoreButton = (mNonClientData.mButtonDown) ? mPressedSysRestoreButton : mHoverSysRestoreButton; MaximizeButton = (mNonClientData.mButtonDown) ? mPressedSysMaximizeButton : mHoverSysMaximizeButton; break; case HTMINBUTTON: MinimizeButton = (mNonClientData.mButtonDown) ? mPressedSysMinimizeButton : mHoverSysMinimizeButton; break ; } } RECT rcButton; Gdiplus::Rect rect; Gdiplus::Graphics grpx(hdc); ComputeCloseButtonRect(rcButton); ::RECT2Rect(rect, rcButton); grpx.DrawImage(CloseButton, rect); ComputeMaximizeButtonRect(rcButton); ::RECT2Rect(rect, rcButton); if (IsZoomed()) { grpx.DrawImage(RestoreButton, rect); } else { grpx.DrawImage(MaximizeButton, rect); } ComputeMinimizeButtonRect(rcButton); ::RECT2Rect(rect, rcButton); grpx.DrawImage(MinimizeButton, rect); }
// 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; }