mfcpropertysheet

Resizing property sheet is affecting the outlook bar dimensions


This is my OnSize method for resizing a property sheet:

void CResizingMFCPropertySheet::OnSize(UINT nType, int cx, int cy)
{
    CMFCPropertySheet::OnSize(nType, cx, cy);

    if (!GetActivePage()) return;
    if (!GetTabControl()) return;

    if (nType == SIZE_MINIMIZED)
        return;

    int dx = cx - save_rc.Width();
    int dy = cy - save_rc.Height();

    int count = 0;
    for (CWnd *child = GetWindow(GW_CHILD); child; child = child->GetWindow(GW_HWNDNEXT))
        count++;

    HDWP hDWP = ::BeginDeferWindowPos(count);

    for (CWnd *child = GetWindow(GW_CHILD); child; child = child->GetWindow(GW_HWNDNEXT))
    {
        bool move = false;

        //If you add child controls manually, you want to move not resize
        if(child == &m_lblResize && m_lblResize.GetSafeHwnd() != nullptr)
            move = true;

        CRect r;
        child->GetWindowRect(&r);
        ScreenToClient(&r);

        if (move || child->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
        {
            //move the main buttons and the child controls
            r.left += dx;
            r.top += dy;
            ::DeferWindowPos(hDWP, child->m_hWnd, 0, r.left, r.top, 0, 0,
                SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
        }
        else
        {
            //this must be a child window, resize it
            r.right += dx;
            r.bottom += dy;
            ::DeferWindowPos(hDWP, child->m_hWnd, 0, 0, 0, r.Width(), r.Height(),
                SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
        }
    }

    ::EndDeferWindowPos(hDWP);
    GetClientRect(&save_rc);
    Invalidate(TRUE);
}

However, if I change the look and feel of my property sheet like this:

SetIconsList(IDB_MAINT_DB_LARGE, 32);
SetLook(CMFCPropertySheet::PropSheetLook_OutlookBar);

And then I resize my property sheet:

Outlook Bar

How do we adjust OnSize to leave the outlook bar width alone? We only need to resize the height.

There is this question and associated answers but the link in the answer to a Microsoft Knowledge base article is not working. Either way, OnSize needs to be customised to render the PropSheetLook_OutlookBar correctly. Somehow ...

Update

According to Spy it is a toolbar:

Spy results


Solution

  • The first thing I did was add this to my resizing class header:

    protected:
        CWnd* InitNavigationControl() override;
    private:
        CWnd * m_pNavigationControl;
    

    Then, I added this to the source file:

    CWnd* CResizingMFCPropertySheet::InitNavigationControl()
    {
        m_pNavigationControl = CMFCPropertySheet::InitNavigationControl();
    
        return m_pNavigationControl;
    }
    

    Finally, I adjusted the OnSize method:

    void CResizingMFCPropertySheet::OnSize(UINT nType, int cx, int cy)
    {
        CMFCPropertySheet::OnSize(nType, cx, cy);
    
        if (!GetActivePage()) return;
        if (!GetTabControl()) return;
    
        if (nType == SIZE_MINIMIZED)
            return;
    
        int dx = cx - save_rc.Width();
        int dy = cy - save_rc.Height();
    
        int count = 0;
        for (CWnd *child = GetWindow(GW_CHILD); child; child = child->GetWindow(GW_HWNDNEXT))
            count++;
    
        HDWP hDWP = ::BeginDeferWindowPos(count);
        for (CWnd *child = GetWindow(GW_CHILD); child; child = child->GetWindow(GW_HWNDNEXT))
        {
            bool move = false;
    
            //If you add child controls manually, you want to move not resize
            if(child == &m_lblResize && m_lblResize.GetSafeHwnd() != nullptr)
                move = true;
    
            CRect r;
            child->GetWindowRect(&r);
            ScreenToClient(&r);
    
            if (move || child->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
            {
                //move the main buttons and the child controls
                r.left += dx;
                r.top += dy;
                ::DeferWindowPos(hDWP, child->m_hWnd, 0, r.left, r.top, 0, 0,
                    SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
            }
            else
            {
                if (child->GetSafeHwnd() == m_pNavigationControl->GetSafeHwnd())
                {
                    r.bottom += dy;
                    ::DeferWindowPos(hDWP, child->m_hWnd, nullptr,
                        r.left, r.top, r.Width(), r.Height(),
                        SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
                }
                else
                {
                    //this must be a child window, resize it
                    r.right += dx;
                    r.bottom += dy;
                    ::DeferWindowPos(hDWP, child->m_hWnd, 0, 0, 0, r.Width(), r.Height(),
                        SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
                }
            }
        }
    
        ::EndDeferWindowPos(hDWP);
        GetClientRect(&save_rc);
        Invalidate(TRUE);
    }
    

    As you can see, we were able to test against the handler for the navigation control. So the result:

    Bar