WEB开发网
开发学院软件开发VC MFC程序员WTL指南(2)ATL界面类 阅读

MFC程序员WTL指南(2)ATL界面类

 2008-01-19 20:26:41 来源:WEB开发网   
核心提示:这句代码static_cast<T*>(this) 就是窍门所在,它根据函数调用时的特殊处理将指向B1类型的指针this指派为D1或D2类型的指针,MFC程序员WTL指南(2)ATL界面类(3),因为模板代码是在编译其间生成的,所以只要编译器生成正确的继承列表,而DECLARE_WND_CLASS_EX宏还

这句代码static_cast<T*>(this) 就是窍门所在。它根据函数调用时的特殊处理将指向B1类型的指针this指派为D1或D2类型的指针,因为模板代码是在编译其间生成的,所以只要编译器生成正确的继承列表,这样指派就是安全的。(如果你写成:

class D3 : public B1<D2>

就会有麻烦) 之所以安全是因为this对象只可能是指向D1或D2(在某些情况下)类型的对象,不会是其他的东西。注意这很像C++的多态性(polymorphism),只是SayHi()方法不是虚函数。

要解释这是如何工作的,首先看对每个SayHi()函数的调用,在第一个函数调用,对象B1被指派为D1,所以代码被解释成:

void B1<D1>::SayHi()
{
   D1* pT = static_cast<D1*>(this);
   pT->PrintClassName();
}

由于D1没有重载PrintClassName(),所以查看基类B1,B1有PrintClassName(),所以B1的PrintClassName()被调用。

现在看第二个函数调用SayHi(),这一次对象被指派为D2类型,SayHi()被解释成:

void B1<D2>::SayHi()
{
   D2* pT = static_cast<D2*>(this);
   pT->PrintClassName();
}

这一次,D2含有PrintClassName()方法,所以D2的PrintClassName()方法被调用。

这种技术的有利之处在于:

  • 不需要使用指向对象的指针。
  • 节省内存,因为不需要虚函数表。
  • 因为没有虚函数表所以不会发生在运行时调用空指针指向的虚函数。
  • 所有的函数调用在编译时确定(译者加:区别于C++的虚函数机制使用的动态编连),有利于编译程序对代码的优化。

节省虚函数表在这个例子中看起来无足轻重(每个虚函数只有4个字节),但是设想一下如果有15个基类,每个类含有20个方法,加起来就相当可观了。

ATL 窗口类

好了,关于ATL的背景知识已经讲的构多了,到了该正式讲ATL的时候了。ATL在设计时接口定义和实现是严格区分开的,这在窗口类的设计中是最明显的,这一点类似于COM,COM的接口定义和实现是完全分开的(或者可能有多个实现)。

ATL有一个专门为窗口设计的接口,可以做全部的窗口操作,这就是CWindow。它实际上就是对HWND操作的包装类,对几乎所有以HWND句柄为第一个参数的窗口API的进行了封装,例如:SetWindowText() 和 DestroyWindow()。CWindow类有一个公有成员m_hWnd,使你可以直接对窗口的句柄操作,CWindow还有一个操作符HWND,你可以讲CWindow对象传递给以HWND为参数的函数,但这与CWnd::GetSafeHwnd()(译者加:MFC的方法)没有任何等同之处。

CWindow 与 MFC 的CWnd类有很大的不同,创建一个CWindow对象占用很少的资源,因为只有一个数据成员,没有MFC窗口中的对象链,MFC内部维持这一个对象链,此对象链将HWND映射到CWnd对象。还有一点与MFC的CWnd类不同的是当一个CWindow对象超出了作用域,它关联的窗口并不被销毁掉,这意味着你并不需要随时记得分离你所创建的临时CWindow对象。

在ATL类中对窗口过程的实现是CWindowImpl。CWindowImpl 含有所有窗口实现代码,例如:窗口类的注册,窗口的子类化,消息映射以及基本的WindowProc()函数,可以看出这与MFC的设计有很大的不同,MFC将所有的代码都放在一个CWnd类中。

还有两个独立的类包含对话框的实现,它们分别是CDialogImpl 和 CAxDialogImpl,CDialogImpl 用于实现普通的对话框而CAxDialogImpl实现含有ActiveX控件的对话框。

定义一个窗口的实现

任何非对话框窗口都是从CWindowImpl 派生的,你的新类需要包含三件事情:

  1. 一个窗口类的定义
  2. 一个消息映射链
  3. 窗口使用的默认窗口类型,称为window traits

窗口类的定义通过DECLARE_WND_CLASS宏或DECLARE_WND_CLASS_EX宏来实现。这辆个宏定义了一个CWndClassInfo结构,这个结构封装了WNDCLASSEX结构。DECLARE_WND_CLASS宏让你指定窗口类的类名,其他参数使用默认设置,而DECLARE_WND_CLASS_EX宏还允许你指定窗口类的类型和窗口的背景颜色,你也可以用NULL作为类名,ATL会自动为你生成一个类名。

上一页  1 2 3 4 5 6 7 8  下一页

Tags:MFC 程序员 WTL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接