Создание изменяемого размера CMFCPropertySheet с помощью динамических макетов
Я видел этот вопрос, но ссылка в ответе больше не действительна.
Я также нашел то, что я пытался и не работает, и это.
Моя задача должна быть простой. У меня есть несколько страниц на CMFCPropertySheet
и я хочу воспользоваться новыми функциями динамического изменения размера в IDE. Поэтому я установил изменение размеров элементов управления и, увы, при показе на листе нет возможности изменить размер листа / страниц.
Попытка вышеуказанных ресурсов не удалась.
Заголовок для CMyPropertySheet
:
Источник для CMyPropertySheet
:
Для тестирования я просто создал диалоговое приложение, добавил страницу и назначил ее этому листу.
Я просто хочу поддержать динамическое изменение размеров с помощью страниц свойств / страниц. Чего мне не хватает и нужен ли этот код на самом деле больше?
3 ответа
Для немодального окна свойств:
Посмотрите эту ссылку SO Изменение размера немодального окна свойств
Для модального листа свойств:
Как реализовать лист свойств с изменяемым размером
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;
}
Вот альтернативный ответ, который я придумал. Мне пришло в голову, что нет никаких оснований вообще не использовать новые функции динамического макета. Просто указатель динамического макета 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
обработчик событий и никакого ручного рисования любого вида.
На всякий случай, если вам подходит CPropertySheet вместо CMFCPropertySheet, рассмотрите возможность использования ResizableLib. Включает в себя класс CResizableSheet
который реализует изменяемый размер версии CPropertySheet.