Сабклассинг (SubClass) MDIClient в MFC
В MFC, окно MDICLIENT хранится в public переменной HWND
(m_hwndMDIClient) класса CMDIFrameWnd. CMDIFrameWnd является базовым
классом для CMainFrame в сгенерированном визардом MDI
приложении.
Для сабклассинга окна MDICLIENT необходимо проделать
три шага :
- Воспользуйтесь визардом, чтобы наследовать
класс от CWnd и назовите его CMDIClientWnd.
- В CMDIClientWnd добавьте функцию GetSuperWndProcAddr().
- Для сабклассинга окна MDICLIENT используйте CMDIClientWnd.
Как только будет сделан сабклассинг окна MDICLIENT,
обработчики сообщений и другие функции можно
будет располагать в классе CMDIClientWnd.
Ниже, каждый шаг расписан подробнее:
- Воспользуйтесь визардом, чтобы наследовать
класс от CWnd и назовите его CMDIClientWnd.
Подробнее об этом можно узнать в документации по
ClassWizard, в разделе "Adding a New Class".
- В CMDIClientWnd добавьте функцию GetSuperWndProcAddr().
ВНИМАНИЕ: Данный шаг необходим только если Вы
используете 16-битную версию Visual C++, а не 32-битную.
32-битная версия Visual C++ уже включает эту функцию.
Как только класс создан, добавьте следующий
прототип в заголовочный файл: public:
WNDPROC* GetSuperWndProcAddr();
А также добавьте следующую функцию в файл .CPP:
WNDPROC* CMDIClientWnd::GetSuperWndProcAddr() {
static WNDPROC NEAR pfnSuper = NULL;
return &pfnSuper;
}
- Используйте CMDIClientWnd для сабклассинга окна MDICLIENT
в классе CMDIFrameWnd class (обычно CMainFrame).
В класс CMainFrame добавьте public переменную типа
CMDIClientWnd назвав её m_wndMDIClient. Затем измените OnCreate
для CMainFrame как показано ниже: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndMDIClient.SubclassWindow (m_hWndMDIClient)) { // Добавить
TRACE ("Failed to subclass MDI client window\n"); // Добавить
return (-1); // Добавить
} // Добавить
...
}
После выполнения всех трёх шагов, Вы можете
использовать ClassWizard, чтобы добавить обработчики
сообщений в CMDIClientWnd подобно коду, который показан
ниже и который меняет фоновый цвет MDICLIENT.
BOOL CMDIClientWnd::OnEraseBkgnd(CDC* pDC)
{
// Устанавливаем цвет кисти, соответствующий цвету фона
CBrush backBrush(RGB(255, 128, 128));
// Записываем старую кисть
CBrush* pOldBrush = pDC->SelectObject(&backBrush);
CRect rect;
pDC->GetClipBox(&rect); // Стираем нужную область
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
PATCOPY);
pDC->SelectObject(pOldBrush);
return TRUE;
}
|