深入剖析WTL—WTL框架窗口分析(4)

转载 2007年09月30日 11:01:00
superclass是一种生成新的窗口类的方法。它的中心思想是依靠现有的窗口类,克隆出另一个窗口类。被克隆的类可以是Windows预定义的窗口类,这些预定义的窗口类有按钮或下拉框控制等等。也可以是一般的类。克隆的窗口类使用被克隆的类(基类)的窗口消息处理函数。

克隆类可以有自己的窗口消息处理函数,也可以使用基类的窗口处理函数。

需要注意的是,superclass是在注册窗口类时就改变了窗口的行为。即通过指定基类的窗口函数或是自己定义的窗口函数。这与后面讲到的subclass是不同的。后者是在窗口创建完毕后,通过修改窗口函数的地址等改变一个窗口的行为的。

请看示例(摘自MSDN):

class CBeepButton: public CWindowImpl< CBeepButton >{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; // alternatively: DefWindowProc()      return 0;   }}; // CBeepButton


该类实现一个按钮,在点击它时,会有响声。

该类的消息映射处理WM_LBUTTONDOWN消息。其它的消息由Windows缺省窗口函数处理。

在消息映射前面,有一个宏--DECLARE_WND_SUPERCLASS()。它的作用就是申明BeepButton是Button的一个superclass。

分析一下这个宏:

#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; /}


这个宏定义了一个静态函数GetWndClassInfo()。这个函数返回了一个窗口类注册时用到的数据结构CWndClassInfo。该结构的详细定义如下:

struct _ATL_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 _ATL_WNDCLASSINFOW{ … …	{		return AtlModuleRegisterWndClassInfoW(&_Module, this, p);	}};typedef _ATL_WNDCLASSINFOA CWndClassInfoA;typedef _ATL_WNDCLASSINFOW CWndClassInfoW;#ifdef UNICODE#define CWndClassInfo CWndClassInfoW#else#define CWndClassInfo CWndClassInfoA#endif


这个结构调用了一个静态函数AtlModuleRegisterWndClassInfoA(&_Module, this, p);。这个函数的用处就是注册窗口类。

它指定了WndClassName是OrigWdClassName的superclass。

subclass

subclass是普遍采用的一种扩展窗口功能的方法。它的大致原理如下。

在一个窗口创建完了之后,将该窗口的窗口函数替换成新的窗口消息处理函数。这个新的窗口函数可以对某些需要处理的特定的消息进行处理,然后再将处理传给原来的窗口函数。

注意它与superclass的区别。

Superclass是以一个类为原版,进行克隆。既在注册新的窗口类时,使用的是基类窗口的窗口函数。

而subclass是在某一个窗口注册并创建后,通过修改该窗口的窗口消息函数的地址而实现的。它是针对窗口实例。

看一个从MSDN来的例子:

class CNoNumEdit: public CWindowImpl< CNoNumEdit >{   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;   }};


这里定义了一个只接收数字的编辑控件。即通过消息映射,定义了一个特殊的消息处理逻辑。

然后,我们使用CWindowImplT. SubclassWindow()来subclass一个编辑控件。

class CMyDialog: public CDialogImpl<CMyDialog>{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;};


上述代码中,ed.SubclassWindow( GetDlgItem( IDC_EDIT1 ) )语句是对IDC_EDIT1这个编辑控件进行subclass。该语句实际上是替换了编辑控件的窗口函数。

由于SubClassWindows()实现的机制和ATL封装窗口函数的机制一样,我们会在后面介绍ATL是怎么实现它的。
 

深入剖析WTL—WTL框架窗口分析 (4)

superclass superclass是一种生成新的窗口类的方法。它的中心思想是依靠现有的窗口类,克隆出另一个窗口类。被克隆的类可以是Windows预定义的窗口类,这些预定义的窗口类有按钮或下拉框...
  • benny5609
  • benny5609
  • 2008年03月26日 14:36
  • 679

深入剖析WTL—WTL框架窗口分析 (4)

superclass superclass是一种生成新的窗口类的方法。它的中心思想是依靠现有的窗口类,克隆出另一个窗口类。被克隆的类可以是Windows 预定义的窗口类,这些预定义的窗口类有按钮或下...
  • allenshi_szl
  • allenshi_szl
  • 2008年07月02日 14:09
  • 505

深入剖析WTL—WTL框架窗口分析(3)

在上面的例子中,CDerived从CBase中派生出来。CDerived类通过定义一个WM_LBUTTONDOWN消息处理函数来改变CBase类代表的窗口的功能。 这样,CBase类的消息映射定义了一...
  • kedoumy
  • kedoumy
  • 2007年09月30日 10:58
  • 280

深入剖析WTL—WTL框架窗口分析 (6)

WTL对框架窗口的封装ATL仅仅是封装了窗口函数和提供了消息映射。实际应用中,需要各种种类的窗口,比如,每个界面线程所对应的框架窗口。WTL正是在ATL基础上,为我们提供了框架窗口和其他各种窗口。 所...
  • benny5609
  • benny5609
  • 2008年03月26日 14:47
  • 680

深入剖析WTL—WTL框架窗口分析(1)

WTL的基础是ATL。WTL的框架窗口是ATL窗口类的继承。因此,先介绍一下ATL对Windows窗口的封装。 由第一部分介绍的Windows应用程序可以知道创建窗口和窗口工作的逻辑是: 1 注册一个...
  • kedoumy
  • kedoumy
  • 2007年09月30日 11:05
  • 360

深入剖析WTL—WTL框架窗口分析 (1)

WTL的基础是ATL。WTL的框架窗口是ATL窗口类的继承。因此,先介绍一下ATL对Windows窗口的封装。 由第一部分介绍的Windows应用程序可以知道创建窗口和窗口工作的逻辑是: 1 注册...
  • allenshi_szl
  • allenshi_szl
  • 2008年07月02日 14:05
  • 613

深入剖析WTL—WTL框架窗口分析1

WTL的基础是ATL。WTL的框架窗口是ATL窗口类的继承。因此,先介绍一下ATL对Windows窗口的封装。 由第一部分介绍的Windows应用程序可以知道创建窗口和窗口工作的逻辑是: 1 注册一个...
  • bairny
  • bairny
  • 2007年08月23日 15:15
  • 823

深入剖析WTL—WTL框架窗口分析 (1)

WTL的基础是ATL。WTL的框架窗口是ATL窗口类的继承。因此,先介绍一下ATL对Windows窗口的封装。 由第一部分介绍的Windows应用程序可以知道创建窗口和窗口工作的逻辑是: 1 注册一个...
  • benny5609
  • benny5609
  • 2008年03月26日 14:30
  • 535

深入剖析WTL—WTL框架窗口分析(3)

ATL对窗口消息处理函数的封装 在本节开始部分谈到的封装窗口的两个难题,其中第一个问题是怎样解决将窗口函数的消息转发到HWND相对应的类的实例中的相应函数。 下面我们来看一下,ATL采用的是什么办法来...
  • bairny
  • bairny
  • 2007年08月23日 15:23
  • 979

深入剖析WTL—WTL框架窗口分析(6)

WTL对框架窗口的封装ATL仅仅是封装了窗口函数和提供了消息映射。实际应用中,需要各种种类的窗口,比如,每个界面线程所对应的框架窗口。WTL正是在ATL基础上,为我们提供了框架窗口和其他各种窗口。 所...
  • jznsmail
  • jznsmail
  • 2004年12月01日 17:49
  • 1480
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入剖析WTL—WTL框架窗口分析(4)
举报原因:
原因补充:

(最多只允许输入30个字)