15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как изменить размер 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);
 }