Как изменить размер CPropertyPages во время выполнения
Чтобы изменить размер CPropertyPages в CPropertySheet во время выполнения надо:
- Наследовать класс от CPropertySheet и переопределить OnInitDialog().
- В OnInitDialog(), изменить размер CPropertySheet, CTabCtrl, и CPropertyPage(s) при помощи MoveWindow() или SetWindowPos()
- Сохранить размер и положение CPropertyPage.
- Обработать TCN_SELCHANGE в CPropertySheet, и изменить размер страницы.
- Обработать ID_APPLY_NOW в CPropertySheet, и изменить размер страницы.
Фактически CPropertySheet это диалог с CTabCtrl. Каждый CPropertyPage это дочерний класс CPropertySheet и отображается только внутри CTabCtrl. Вот почему мы так же должны изменять размер CTabCtrl. Чтобы получить CTabCtrl, вызовите CPropertySheet::GetTabControl(). Если Вы изменяете высоту property sheet, то возможно потребуется переместить кнопки окошка свойств. Пример, приведённый ниже, иллюстрирует это.
При первом создании, CPropertySheet запоминает размер и положение своих CPropertyPages. Когда пользователь выбирает другую закладку (tab), то CPropertySheet получает уведомление TCN_SELCHANGE. В ответ на это CPropertySheet показывает новую страницу используя размер и положение, которые он запомнил при первом создании. Тоже самое случается, когда пользователь кликает по кнопке Apply (ID_APPLY_NOW). Поэтому, чтобы потом мы могли изменить размер страниц, необходимо сохранять новый размер и положение.
Пример кода
/* Опции компилятора: поумолчанию
*/
// Этот пример добавляет 50 пикселей к ширине и высоте каждой страницы.
// CMySheet наследован от CPropertySheet. m_PageRect это переменная-член
// класса CMySheet и имеет тип RECT. WM_RESIZEPAGE это пользовательское
// сообщение.
// ... прототипы, которые необходимо добавить в объявление класса
class CMySheet : public CPropertySheet
{
// ... другие члены
// ... удостоверьтесь, что эти члены присутствуют
protected:
RECT m_PageRect;
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
virtual BOOL OnInitDialog();
afx_msg LRESULT OnResizePage(WPARAM wParam, LPARAM lParam);
afx_msg void OnApplyNow();
};
// ... измените и/или включите функции в файл .cpp ...
#define WM_RESIZEPAGE WM_USER + 111
BEGIN_MESSAGE_MAP(CMySheet, CPropertySheet)
//{{AFX_MSG_MAP(CMySheet)
// NOTE - the ClassWizard will add and remove mapping macros here.
// ... другие сообщения
//}}AFX_MSG_MAP
// ... add the 2 following entries here
ON_MESSAGE (WM_RESIZEPAGE, OnResizePage)
ON_COMMAND (ID_APPLY_NOW, OnApplyNow)
END_MESSAGE_MAP()
BOOL CMySheet::OnInitDialog()
{
CPropertySheet::OnInitDialog();
RECT rc;
// изменяем размер окошка свойств
GetWindowRect (&rc);
ScreenToClient (&rc);
rc.right += 50;
rc.bottom += 50;
MoveWindow (&rc);
// изменяем размер CTabCtrl
CTabCtrl* pTab = GetTabControl ();
ASSERT (pTab);
pTab->GetWindowRect (&rc);
ScreenToClient (&rc);
rc.right += 50;
rc.bottom += 50;
pTab->MoveWindow (&rc);
// изменяем размер страницы
CPropertyPage* pPage = GetActivePage ();
ASSERT (pPage);
// храним размер страницы в m_PageRect
pPage->GetWindowRect (&m_PageRect);
ScreenToClient (&m_PageRect);
m_PageRect.right += 50;
m_PageRect.bottom += 50;
pPage->MoveWindow (&m_PageRect);
// перемещаем кнопки OK, Cancel, и Apply
CWnd* pWnd = GetDlgItem(IDOK);
pWnd->GetWindowRect(&rc);
rc.bottom += 50;
rc.top += 50;
ScreenToClient(&rc);
pWnd->MoveWindow(&rc);
pWnd = GetDlgItem(IDCANCEL);
pWnd->GetWindowRect(&rc);
rc.bottom += 50;
rc.top += 50;
ScreenToClient(&rc);
pWnd->MoveWindow(&rc);
pWnd = GetDlgItem(ID_APPLY_NOW);
pWnd->GetWindowRect(&rc);
rc.bottom += 50;
rc.top += 50;
ScreenToClient(&rc);
pWnd->MoveWindow(&rc);
CenterWindow();
return TRUE;
}
LONG CMySheet::OnResizePage(UINT, LONG)
{
// изменяем размер страницы используя m_PageRect,
// которая была установлена в OnInitDialog()
CPropertyPage* pPage = GetActivePage ();
ASSERT (pPage);
pPage->MoveWindow (&m_PageRect);
return 0;
}
BOOL CMySheet::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
NMHDR* pnmh = (LPNMHDR) lParam;
// окошко свойств изменяет размер страницы всякий раз, когда она
// активна, поэтому нам необходимо изменить её размер
if (TCN_SELCHANGE == pnmh->code)
// необходимо постить сообщения, так как размер страницы должен
// быть изменён после обработки TCN_SELCHANGE
PostMessage (WM_RESIZEPAGE);
return CPropertySheet::OnNotify(wParam, lParam, pResult);
}
void CMySheet::OnApplyNow()
{
// окошко изменяет размер страницы всякий раз, когда нажимается
// кнопка Apply, поэтому необходимо изменить её размер так, как
// нам надо
PostMessage (WM_RESIZEPAGE);
}