Сабклассинг (SubClass) MDIClient в MFC

В MFC, окно MDICLIENT хранится в public переменной HWND (m_hwndMDIClient) класса CMDIFrameWnd. CMDIFrameWnd является базовым классом для CMainFrame в сгенерированном визардом MDI приложении.

Для сабклассинга окна MDICLIENT необходимо проделать три шага :

  1. Воспользуйтесь визардом, чтобы наследовать класс от CWnd и назовите его CMDIClientWnd.
  2. В CMDIClientWnd добавьте функцию GetSuperWndProcAddr().
  3. Для сабклассинга окна MDICLIENT используйте CMDIClientWnd.

Как только будет сделан сабклассинг окна MDICLIENT, обработчики сообщений и другие функции можно будет располагать в классе CMDIClientWnd.

Ниже, каждый шаг расписан подробнее:

  1. Воспользуйтесь визардом, чтобы наследовать класс от CWnd и назовите его CMDIClientWnd.

    Подробнее об этом можно узнать в документации по ClassWizard, в разделе "Adding a New Class".

  2. В CMDIClientWnd добавьте функцию GetSuperWndProcAddr().

    ВНИМАНИЕ: Данный шаг необходим только если Вы используете 16-битную версию Visual C++, а не 32-битную. 32-битная версия Visual C++ уже включает эту функцию.

    Как только класс создан, добавьте следующий прототип в заголовочный файл:
     public:
    WNDPROC* GetSuperWndProcAddr();

    А также добавьте следующую функцию в файл .CPP:

     WNDPROC* CMDIClientWnd::GetSuperWndProcAddr() {
    static WNDPROC NEAR pfnSuper = NULL;
    return &pfnSuper;
    }

     

  3. Используйте 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;
}

 

 
« Предыдущая статья   Следующая статья »