// This is a special version of GetClientRect for Aero Glass
//  to give us the portion of the window that is not our custom
//  non-client glass so we can:
//      1) Exclude it from drawing the background and other stuffs
//      2) Position the browser window in derived classes
BOOL cef_dark_aero_window::GetRealClientRect(LPRECT rect) const
{
    GetClientRect(rect);

    RECT rectMenu;
    ComputeRequiredMenuRect(rectMenu);

    RECT rectCaption;
    ComputeWindowCaptionRect(rectCaption);

    rect->top = rectCaption.bottom + ::RectHeight(rectMenu) + 4;
    rect->bottom -= ::kWindowFrameSize;
    rect->left += ::kWindowFrameSize;
    rect->right -= ::kWindowFrameSize;

    if (CanUseAeroGlass() && IsZoomed()) 
    {
        // adjust for auto-hide task bar
        WORD edges = WindowsTaskBar::GetAutoHideEdges(mWnd);
        if (edges & WindowsTaskBar::BOTTOM_EDGE) {
            rect->bottom += ::kWindowFrameSize;
        }
        if (edges & WindowsTaskBar::RIGHT_EDGE) {
            rect->right += ::kWindowFrameSize;
        }
        if (edges & WindowsTaskBar::LEFT_EDGE) {
            rect->left -= ::kWindowFrameSize;
        }
    }
    return TRUE;
}
// Computes the Rect where the menu bar is drawn in window coordinates
void cef_dark_window::ComputeMenuBarRect(RECT& rect)
{
    RECT rectClient;
    RECT rectCaption;

    ComputeWindowCaptionRect(rectCaption);
    ComputeLogicalClientRect(rectClient);

    rect.top = rectCaption.bottom + 1;
    rect.bottom = rectClient.top - 1;

    rect.left = rectClient.left;
    rect.right = rectClient.right;
}
// This is a special version of GetClientRect for Aero Glass
//  to give us the portion of the window that is not our custom
//  non-client glass so we can:
//      1) Exclude it from drawing the background and other stuffs
//      2) Position the browser window in derived classes
BOOL cef_dark_aero_window::GetRealClientRect(LPRECT rect) const
{
    GetClientRect(rect);

    RECT rectMenu;
    ComputeRequiredMenuRect(rectMenu);

    RECT rectCaption;
    ComputeWindowCaptionRect(rectCaption);

    rect->top = rectCaption.bottom + ::RectHeight(rectMenu) + 4;
    rect->bottom -= ::kWindowFrameSize;
    rect->left += ::kWindowFrameSize;
    rect->right -= ::kWindowFrameSize;

    return TRUE;
}
// Computes the Rect where the menu bar is drawn in window coordinates
void cef_dark_aero_window::ComputeMenuBarRect(RECT& rect) const
{
    if (CanUseAeroGlass()) {
        RECT rectClient;
        RECT rectCaption;

        ComputeWindowCaptionRect(rectCaption);
        GetRealClientRect(&rectClient);

        rect.top = rectCaption.bottom + 1;
        rect.bottom = rectClient.top - 1;

        rect.left = rectClient.left;
        rect.right = rectClient.right;
    } else {
        cef_dark_window::ComputeMenuBarRect(rect);
    }
}
// Draw the Caption Bar
void cef_dark_window::DoDrawTitlebarText(HDC hdc)
{
    if (mCaptionFont == 0) {
        mCaptionFont = ::CreateFontIndirect(&mNcMetrics.lfCaptionFont);
    }

    RECT textRect;
    ComputeWindowCaptionRect(textRect);

    HGDIOBJ hPreviousFont = ::SelectObject(hdc, mCaptionFont);        
    int oldBkMode = ::SetBkMode(hdc, TRANSPARENT);
    COLORREF oldRGB = ::SetTextColor(hdc, CEF_COLOR_NORMALTEXT);

    // Setup the rect to use to calculate the position
    RECT windowRect;
    GetWindowRect(&windowRect);
    ScreenToNonClient(&windowRect);

    // Get the title and the length
    int textLength = GetWindowTextLength() + 1;
    LPWSTR szCaption = new wchar_t [textLength + 1];
    ::ZeroMemory(szCaption, textLength + 1);
    int cchCaption = GetWindowText(szCaption, textLength);

    // Figure out how much space we need to draw ethe whole thing
    RECT rectTemp;
    ::SetRectEmpty(&rectTemp);
    ::DrawText(hdc, szCaption, ::wcslen(szCaption), &rectTemp, DT_SINGLELINE|DT_CALCRECT|DT_NOPREFIX);

    // Can it be centered within the window?
    if (((::RectWidth(windowRect) / 2) + (::RectWidth(rectTemp) / 2) + 1) < textRect.right) {
        windowRect.bottom = textRect.bottom;
        windowRect.top += textRect.top;
        ::DrawText(hdc, szCaption, cchCaption, &windowRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
    } else {
        // Can't be centered so LEFT justify and add ellipsis when truncated
        ::DrawText(hdc, szCaption, cchCaption, &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX);
    }
 
    delete []szCaption;
    ::SetTextColor(hdc, oldRGB);
    ::SetBkMode(hdc, oldBkMode);
    ::SelectObject(hdc, hPreviousFont);
}
// Computes the Rect where the menu bar is drawn in window coordinates
void cef_dark_aero_window::ComputeMenuBarRect(RECT& rect) const
{
    if (CanUseAeroGlass()) {
        RECT rectClient;
        RECT rectCaption;

        GetRealClientRect(&rectClient);

        if (IsZoomed()) {
            ComputeWindowCaptionRect(rectCaption);
            rect.top = rectCaption.bottom;
        } else {
            rect.top = ::GetSystemMetrics(SM_CYFRAME) + mNcMetrics.iCaptionHeight + 1;
        }
        rect.bottom = rectClient.top - 1;

        rect.left = rectClient.left;
        rect.right = rectClient.right;
    } else {
        cef_dark_window::ComputeMenuBarRect(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;
}