Как изменить порядок CPropertyPage внутри CPropertySheet

У нас есть CPropertySheet, внутри которого есть 5 CPropertyPage.

Допустим, у нас есть что-то подобное

1 2 3 4 5

Затем, основываясь на некоторой бизнес-логике, когда пользователь нажимает кнопку Обновить, мы хотели бы иметь

1 5 2 3 4

Мы не хотим удалять все CPropertyPage и воссоздавать их в правильном порядке (с AddPage()), мы просто хотим обновить положение страницы на листе.

Это возможно?

Спасибо!

2

Решение

Microsoft MFC CPropertySheet не имеет функции для этого, однако, если вы проверите API свойств Windows Controls, Вы можете добиться чего-то похожего, удалив страницу, которую вы хотите переместить, а затем вставив ее в нужное место.

Для этого сначала нужно создать подкласс 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_ADDPAGE в PSM_INSERTPAGE

Затем, чтобы переместить страницу в определенную позицию, просто удалите ее, а затем добавьте в нужную позицию.

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

Другие решения

Других решений пока нет …