// 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 maximize button is drawn in window coordinates
void cef_dark_window::ComputeMaximizeButtonRect(RECT& rect)
{
    ComputeCloseButtonRect(rect);

    rect.left -= (mSysMaximizeButton->GetWidth() + 1);
    rect.right = rect.left + mSysMaximizeButton->GetWidth();
    rect.bottom = rect.top + mSysMaximizeButton->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;
}