Analysis of WTL-WTL Frame WTL Analysis (4)

xiaoxiao2021-03-06  65

SuperClass is a way to generate a new window class. Its central idea is to rely on existing window classes, cloning another window class. Class cloned can be Windows predefined window classes, these predefined window classes have buttons or pull-down box controls, and more. It can also be a general class. Cloning window class uses the window message processing function of the cloned class (base class).

Clones can have their own window message processing function, or the base class window processing function.

It should be noted that SuperClass changes the behavior of the window when registering a window class. That is, by specifying a window function of the base class or the window function you define. This is different from the subclass described later. The latter is to change the behavior of a window by modifying the address of the window function after the window is created.

Please see the example (from MSDN):

Class CbeepButton: Public CWINDOWIMPL

{

PUBLIC:

Declare_wnd_superclass (_t ("beepbutton"), _t ("button"))))

Begin_MSG_MAP (CbeepButton)

Message_handler (WM_LButtondown, ONLBUTTONDOWN)

END_MSG_MAP ()

Lresult Onlbuttondown (Uint, WParam, Lparam, Bool & Bhandled)

{

MessageBeep (MB_ICONASTERISK);

BHANDLED = false; // alternative: defWindowProc ()

Return 0;

}

}; // cbeepbutton

This class implements a button, and there will be sound when you click on it.

Message map of this class processes the WM_LButtondown message. Other messages are processed by the Windows default window function.

In front of the message mapping, there is a macro - Declare_Wnd_superClass (). Its role is to declare BeepButton is a superclass of Button.

Analyze this macro:

#define declare_wnd_superclass (wndclassname, OrigWndClassName) /

Static CWndclassInfo & GetWndclassInfo () /

{/

Static CWNDClassInfo WC = /

{/

{SizeOf (Wndclassex), 0, StartWindowProc, /

0, 0, NULL, NULL, NULL, NULL, NULL, WNDCLASSNAME, NULL}, /

OrigWndClassName, NULL, NULL, TRUE, 0, _T ("") /

}; /

Return WC; /

}

This macro defines a static function GetWndClassInfo (). This function returns a window class registration data structure CWndClassInfo. The detailed definition of this structure is as follows:

Struct _tl_wndclassinfoa

{

WNDCLASSEXA M_WC;

LPCSTR M_LPSZORIGNAME;

WndProc PWNDPROC;

LPCSTR M_LPSZCURSORID;

BOOL M_BSYSTEMCURSOR;

Atom m_atom;

Char m_szautoname [13];

Atom Register (WNDPROC * P)

{

Return AtlmoduleRegisterWndClassInfoa (& _ Module, this, P);

}

}

Struct _tl_wndclassinfow

{

...

{

Return AtlmoduleRegisterWndClassInfow (& _ Module, this, P);

}

Typedef _tl_wndclassinfoa cWndclassInfoa;

TYPEDEF _TL_WNDCLASSINFOW CWNDCLASSINFOW;

#ifdef unicode

#define CWndClassInfo CWndClassInfow

#ELSE

#define CWndClassInfo CWndClassInfoa

#ENDIF

This structure calls a static function atlmoduleRegisterWndClassInfoa (& _ Module, this, P) ;. The use of this function is the registration window class.

It specifies that WNDClassName is SuperClassName of OrigwdClassName.

Subclass

Subclass is a general way to extend the window functionality. Its roughly is as follows.

After the window is created, the window function of the window is replaced with a new window message processing function. This new window function can process some specific messages that need to be processed, and then pass the process to the original window function.

Note that it is different from superclass.

SuperClass is a cloning in a class as an original. When you register a new window class, use the window function of the base class window.

Subclass is implemented after a window is registered and created, is implemented by modifying the address of the window message function of the window. It is for window instances.

Look at an example from MSDN:

Class CnonumEdit: Public CWindowImpl

{

Begin_MSG_MAP (CNONUMEDIT)

Message_handler (wm_char, onchar)

END_MSG_MAP ()

Lresult Onchar (uint, wparam wparam, lparam, bool & bhandled)

{

TCHAR CH = WPARAM;

IF (_t ('0') <= ch && ch <= _t ('9'))

MessageBeep (0);

Else

BHANDLED = false;

Return 0;

}

}

A editing control that only receives only a number is received. That is, a special message processing logic is defined by message mapping.

Then we use CWindowImplt. SubclassWindow () to Subclass an editing control.

Class CMYDIALOG: PUBLIC CDIALOGIMPL

{

PUBLIC:

ENUM {IDD = IDD_DIALOG1};

Begin_MSG_MAP (CMYDIALOG)

Message_handler (WM_INITDIALOG, OnInitdialog)

END_MSG_MAP ()

Lresult OnInitdialog (Uint, WParam, Lparam, Bool &)

{

Ed.SubclassWindow (Getdlgitem (IDC_EDit1));

Return 0;

}

CnonuMedit Ed;

}

In the above code, ed.subclassWindow (getdlgitem (IDC_EDIT1)) statement is subclass to IDC_EDit1. This statement is actually replacing the window function of the editing control.

Due to the mechanism of SubclassWindows () and the mechanism of ATL package functions, we will introduce how ATL implement it later.

转载请注明原文地址:https://www.9cbs.com/read-85722.html

New Post(0)