使CMFCPropertySheet可通过动态布局调整大小

时间:2018-06-20 19:29:11

标签: mfc

我看到了这个question,但答案中的链接不再有效。

我还找到了this,我尝试了一下却没用,this

我的任务应该很简单。我在CMFCPropertySheet上有几页,我想利用IDE中新的动态调整大小功能。因此,我设置了控件和控件的大小,但是当它们显示在工作表中时,就无法调整工作表/页面的大小。

尝试使用上述资源失败。

CMyPropertySheet的标题:

https://pastebin.com/k8yjhZh7

CMyPropertySheet的来源:

https://pastebin.com/kxexFPbU

为了测试,我刚刚创建了一个对话框应用程序,并添加了一个页面并将其分配给此工作表。

我只想支持属性表/页面的动态调整大小。我缺少什么,实际上是否还需要任何这些代码?

3 个答案:

答案 0 :(得分:1)

对于无模属性表:
看到这个SO链接 Resizing a modeless property sheet


对于模态特性表:
如何实现可调整大小的属性表
https://www.codeproject.com/Tips/214744/How-to-implement-a-resizable-property-sheet-class

在属性表窗口中添加WS_THICKFRAME样式。

int CALLBACK XmnPropSheetCallback(HWND hWnd, UINT message, LPARAM lParam)
{
    extern int CALLBACK AfxPropSheetCallback(HWND, UINT message, LPARAM lParam);
    // XMN: Call MFC's callback
    int nRes = AfxPropSheetCallback(hWnd, message, lParam);

    switch(message)
    {
    case PSCB_PRECREATE:
        // Set our own window styles
        ((LPDLGTEMPLATE)lParam)->style |= (DS_3DLOOK | DS_SETFONT
            | WS_THICKFRAME | WS_SYSMENU | WS_POPUP | WS_VISIBLE | WS_CAPTION);
        break;
    }
    return nRes;
}

INT_PTR CMyPropertySheet::DoModal()
{
    // Hook into property sheet creation code
    m_psh.dwFlags |= PSH_USECALLBACK;
    m_psh.pfnCallback = XmnPropSheetCallback;

    return CMFCPropertySheet::DoModal();
}

ps,原始文章有点旧。这使用m_psh来访问属性表的参数。

调整大小:

void CMyPropertySheet::OnSize(UINT nType, int cx, int cy)
{
    CPropertySheet::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;
        //override***
        //If you add child controls manually, you want to move not resize
        //if(child == &static_control)
            //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);
}

BOOL CMyPropertySheet::OnInitDialog()
{
    CPropertySheet::OnInitDialog();
    GetClientRect(&save_rc);
    GetClientRect(&minimum_rc);
    return TRUE;
}

答案 1 :(得分:1)

只要您对CPropertySheet而不是CMFCPropertySheet感到满意,请考虑使用ResizableLib。它包含一个CResizableSheet类,该类实现可调整大小的CPropertySheet版本。

答案 2 :(得分:1)

这是我想出的另一种答案。在我看来,我们根本没有理由不使用新的动态布局功能。刚开始时动态布局指针就是NULL

如果将以下私有方法添加到派生的属性表类中:

void CResizingMFCPropertySheet::SetupDynamicLayout()
{
    EnableDynamicLayout(TRUE);
    auto pManager = GetDynamicLayout();
    if (pManager != nullptr)
    {
        pManager->Create(this);

        // The navigation control only needs to be stretched vertically
        pManager->AddItem(m_pNavigationControl->GetSafeHwnd(),
            CMFCDynamicLayout::MoveNone(), CMFCDynamicLayout::SizeVertical(100));

        // The resize control needs to be moved 100% in both directions
        pManager->AddItem(m_lblResize.GetSafeHwnd(),
            CMFCDynamicLayout::MoveHorizontalAndVertical(100, 100), CMFCDynamicLayout::SizeNone());

        for (CWnd *child = GetWindow(GW_CHILD); child; child = child->GetWindow(GW_HWNDNEXT))
        {
            if (child->GetSafeHwnd() != m_lblResize.GetSafeHwnd() &&
                child->GetSafeHwnd() != m_pNavigationControl->GetSafeHwnd())
            {
                // All buttons need to be moved 100% in all directions
                if (child->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
                {
                    pManager->AddItem(child->GetSafeHwnd(),
                        CMFCDynamicLayout::MoveHorizontalAndVertical(100, 100), CMFCDynamicLayout::SizeNone());
                }
                else // This will be the main tab control which needs to be stretched in both directions
                {
                    pManager->AddItem(child->GetSafeHwnd(),
                        CMFCDynamicLayout::MoveNone(), CMFCDynamicLayout::SizeHorizontalAndVertical(100, 100));
                }
            }
        }
    }
}

然后从OnInitDialog调用它,则不需要任何OnSize事件处理程序,也不需要任何类型的手动绘制。