У нас есть CPropertySheet, внутри которого есть 5 CPropertyPage.
Допустим, у нас есть что-то подобное
1 2 3 4 5
Затем, основываясь на некоторой бизнес-логике, когда пользователь нажимает кнопку Обновить, мы хотели бы иметь
1 5 2 3 4
Мы не хотим удалять все CPropertyPage и воссоздавать их в правильном порядке (с AddPage()
), мы просто хотим обновить положение страницы на листе.
Это возможно?
Спасибо!
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);
Других решений пока нет …