Как изменить размер CPropertyPages во время выполнения

Чтобы изменить размер CPropertyPages в CPropertySheet во время выполнения надо:

  1. Наследовать класс от CPropertySheet и переопределить OnInitDialog().

  2. В OnInitDialog(), изменить размер CPropertySheet, CTabCtrl, и CPropertyPage(s) при помощи MoveWindow() или SetWindowPos()

  3. Сохранить размер и положение CPropertyPage.

  4. Обработать TCN_SELCHANGE в CPropertySheet, и изменить размер страницы.

  5. Обработать 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);
}
 
« Предыдущая статья   Следующая статья »