Чтобы изменить размер 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); } |