TN001. Регистрация класса Window

В этом примечании описываются подпрограммы MFC, которые регистрируют специальные компоненты WNDCLASS, необходимые Microsoft Windows. Рассматриваются конкретные WNDCLASS атрибуты, используемые MFC и Windows.

Проблема

Атрибуты объекта CWnd , такие как дескриптор HWND в Windows, хранятся в двух местах: объект окна и WNDCLASSобъект . Имя WNDCLASS передается общим функциям создания окна, таким как CWnd::Create и CFrameWnd::Create , в параметре lpszClassName .

Это WNDCLASS необходимо зарегистрировать с помощью одного из четырех способов:

  • Неявно с помощью MFC, предоставленного WNDCLASS.

  • Неявно путем подкласса элемента управления Windows (или другого элемента управления).

  • Явным образом путем вызова MFC AfxRegisterWndClass или AfxRegisterClass.

  • Явным образом путем вызова подпрограммы Windows RegisterClass.

Поля WNDCLASS

Структура WNDCLASS состоит из различных полей, описывающих класс окна. В следующей таблице показаны поля и указано, как они используются в приложении MFC:

Поле Описание
lpfnWndProc window proc, должен быть AfxWndProc
cbClsExtra не используется (должно быть равно нулю)
cbWndExtra не используется (должно быть равно нулю)
hInstance автоматически заполняется AfxGetInstanceHandle
hIcon значок для окон фрейма, см. ниже
hCursor Cursor для при наведении указателя мыши на окно см. ниже
hbrBackground цвет фона, см. ниже
lpszMenuName не используется (должно иметь значение NULL)
lpszClassName имя класса, см. ниже

Предоставленные WNDCLASSes

Более ранние версии MFC (до MFC 4.0) предоставляли несколько предопределенных классов Window. Эти классы Window больше не предоставляются по умолчанию. Приложения должны использовать AfxRegisterWndClass с соответствующими параметрами.

Если приложение предоставляет ресурс с указанным идентификатором ресурса (например, AFX_IDI_STD_FRAME), MFC будет использовать этот ресурс. В противном случае будет использоваться ресурс по умолчанию. Для значка используется стандартный значок приложения, а для курсора — стандартный курсор со стрелкой.

Два значка поддерживают приложения MDI с одним типом документов: один значок для main приложения, другой значок для знаковых окон документов или MDIChild. Для документов нескольких типов с разными значками необходимо зарегистрировать дополнительные WNDCLASSэлементы или использовать функцию CFrameWnd::LoadFrame .

CFrameWnd::LoadFrame зарегистрирует с WNDCLASS помощью идентификатора значка, указанного в качестве первого параметра, и следующих стандартных атрибутов:

  • стиль класса : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

  • значок AFX_IDI_STD_FRAME

  • Курсор-стрелка

  • COLOR_WINDOW цвет фона

Значения цвета фона и курсора для CMDIFrameWnd не используются, так как клиентская область CMDIFrameWnd полностью охватывается окном MDICLIENT . Корпорация Майкрософт не рекомендует использовать подклассы окна MDICLIENT , поэтому по возможности используйте стандартные цвета и типы курсоров.

Элементы управления подклассами и надклассами

Если вы используете подкласс или суперкласс элемента управления Windows (например, CButton), класс автоматически получает WNDCLASS атрибуты, предоставляемые в реализации этого элемента управления Windows.

Функция AfxRegisterWndClass

MFC предоставляет вспомогающую функцию для регистрации класса окна. С учетом набора атрибутов (стиль класса окна, курсор, фоновая кисть и значок) создается искусственное имя, а полученный класс окна регистрируется. Например,

const char* AfxRegisterWndClass(UINT nClassStyle,
    HCURSOR hCursor,
    HBRUSH hbrBackground,
    HICON hIcon);

Эта функция возвращает временную строку созданного зарегистрированного класса окна. Дополнительные сведения об этой функции см. в разделе AfxRegisterWndClass.

Возвращаемая строка является временным указателем на буфер статической строки. Он действителен до следующего вызова AfxRegisterWndClass. Если вы хотите сохранить эту строку, сохраните ее в переменной CString , как показано в следующем примере:

CString strWndClass = AfxRegisterWndClass(CS_DBLCLK, ...);

...
CWnd* pWnd = new CWnd;
pWnd->Create(strWndClass, ...);

...

AfxRegisterWndClass вызовет исключение CResourceException , если не удалось зарегистрировать класс окна (из-за плохих параметров или нехватки памяти Windows).

Функции RegisterClass и AfxRegisterClass

Если вы хотите сделать что-нибудь более сложное, чем то, что AfxRegisterWndClass предоставляет, можно вызвать API RegisterClass Windows или функцию AfxRegisterClassMFC . Функции CWnd,CFrameWnd and CMDIChildWndCreate принимают в качестве первого параметра имя lpszClassName строки для класса Window. Вы можете использовать любое зарегистрированное имя класса окна, независимо от метода, который использовался для его регистрации.

Важно использовать AfxRegisterClass (или AfxRegisterWndClass) в библиотеке DLL в Win32. Win32 не отменяет автоматическую отмену регистрации классов, зарегистрированных библиотекой DLL, поэтому при завершении работы библиотеки DLL необходимо явно отменить регистрацию классов. AfxRegisterClass Использование вместо RegisterClass этого обрабатывается автоматически. AfxRegisterClass поддерживает список уникальных классов, зарегистрированных библиотекой DLL, и автоматически отменяет регистрацию при завершении работы библиотеки DLL. При использовании RegisterClass в библиотеке DLL необходимо отменить регистрацию всех классов при завершении работы библиотеки DLL (в функции DllMain ). Сбой может привести RegisterClass к неожиданному сбою при попытке другого клиентского приложения использовать библиотеку DLL.

См. также раздел

Технические примечания по числу
Технические примечания по категориям