В 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; } |