c++ - 如何对 CPropertySheet 内的 CPropertyPage 重新排序

标签 c++ mfc cpropertysheet

我们有一个 CPropertySheet,里面有 5 个 CPropertyPage。

假设我们有这样的东西

1 2 3 4 5

然后,基于一些业务逻辑,当用户单击刷新时,我们希望

1 5 2 3 4

我们不想删除所有 CPropertyPage 并按正确的顺序重新创建它们(使用 AddPage()),我们只想更新页面在工作表中的位置。

这可能吗?

谢谢!

最佳答案

Microsoft 的 MFC CPropertySheet 没有执行此操作的函数,但是,如果您检查 Property Sheet Windows Controls API ,您可以通过删除要移动的页面然后将其插入到所需的位置来实现类似的效果。

为此,您首先需要子类化 CPropertySheet 并添加一个函数以按给定顺序插入页面:

//In the .h of your subclass

//Inserts the page at a given Index
void InsertPageAt(CPropertyPage* pPageToInsert, int nPos);

//In the .cpp file
void CPropertySheetControleur::InsertPageAt(CPropertyPage* pPage, int nPos)
{
    ASSERT_VALID(this);
    ENSURE_VALID(pPage);
    ASSERT_KINDOF(CPropertyPage, pPage);


    // add page to internal list
    m_pages.InsertAt(nPos, pPage);

    // add page externally
    if (m_hWnd != NULL)
    {
        // determine size of PROPSHEETPAGE array
        PROPSHEETPAGE* ppsp = const_cast<PROPSHEETPAGE*>(m_psh.ppsp);
        int nBytes = 0;
        int nNextBytes;
        for (UINT i = 0; i < m_psh.nPages; i++)
        {
            nNextBytes = nBytes + ppsp->dwSize;
            if ((nNextBytes < nBytes) || (nNextBytes < (int)ppsp->dwSize))
                AfxThrowMemoryException();
            nBytes = nNextBytes;
            (BYTE*&)ppsp += ppsp->dwSize;
        }

        nNextBytes = nBytes + pPage->m_psp.dwSize;
        if ((nNextBytes < nBytes) || (nNextBytes < (int)pPage->m_psp.dwSize))
            AfxThrowMemoryException();

        // build new prop page array
        ppsp = (PROPSHEETPAGE*)realloc((void*)m_psh.ppsp, nNextBytes);
        if (ppsp == NULL)
            AfxThrowMemoryException();
        m_psh.ppsp = ppsp;

        // copy processed PROPSHEETPAGE struct to end
        (BYTE*&)ppsp += nBytes;
        Checked::memcpy_s(ppsp, nNextBytes - nBytes , &pPage->m_psp, pPage->m_psp.dwSize);
        pPage->PreProcessPageTemplate(*ppsp, IsWizard());
        if (!pPage->m_strHeaderTitle.IsEmpty())
        {
            ppsp->pszHeaderTitle = pPage->m_strHeaderTitle;
            ppsp->dwFlags |= PSP_USEHEADERTITLE;
        }
        if (!pPage->m_strHeaderSubTitle.IsEmpty())
        {
            ppsp->pszHeaderSubTitle = pPage->m_strHeaderSubTitle;
            ppsp->dwFlags |= PSP_USEHEADERSUBTITLE;
        }
        HPROPSHEETPAGE hPSP = AfxCreatePropertySheetPage(ppsp);
        if (hPSP == NULL)
            AfxThrowMemoryException();

        if (!SendMessage(PSM_INSERTPAGE, nPos, (LPARAM)hPSP))
        {
            AfxDestroyPropertySheetPage(hPSP);
            AfxThrowMemoryException();
        }
        ++m_psh.nPages;
    }
} 

我将此函数基于 CPropertySheet::AddPage 代码,但在函数末尾,我替换了消息 PSM_ADDPAGEPSM_INSERTPAGE

然后,要将页面移动到特定位置,只需将其删除,然后将其添加到所需位置即可。

pPropertySheet->RemovePage(pPageToAdd);
pPropertySheet->InsertPageAt(pPageToAdd, nIndex);

关于c++ - 如何对 CPropertySheet 内的 CPropertyPage 重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18515152/

相关文章:

c++ - 如何正确更改 CPropertySheet 上的选项卡

c++ - Boost asio C++ 20 协程 : co_spawn a coroutine with a by-reference parameter unexpected result

c++ - 麻烦迭代结构

c++ - 如何防止不同插件中出现重复的资源 ID?

c++ - 尝试添加处理程序以控制 MFC 窗体时 Visual Studio 崩溃

c++ - CListCtrl 类重写和 OnTimer

C++ 模板函数,相同类型,多个实例化 : shares one same copy of code? 甚至在不同的 cpp/目标文件中

c++ - 如果作为参数传递,则打开文件,否则打开主应用程序菜单

c++ - MFC 中 CTabCtrl 与 CPropertySheet 哪个更受欢迎?

c++ - 在选项卡选择上更新 CPropertyPage