WTL for MFC Programmers(4)

To explain how this works, let's look at each call to SayHi(). In the first call, the specialization B1<D1> is being used, so the SayHi() code expands to:

它是怎么工作的呢?让我们看看每一次的SayHi()的调用。第一次,使用特殊的B1<D1>SayHi()的代码展开如下:

void B1<D1>::SayHi()

{

D1* pT = static_cast<D1*>(this);

 

    pT->PrintClassName();

}

Since D1 does not override PrintClassName(), D1's base classes are searched. B1 has a PrintClassName() method, so that is the one called.

由于D1没有重载PrintClassName()D1的基类被找到,B1有一个PrintClassName()的方法,所有有了那次调用。

Now, take the second call to SayHi(). This time, it's using the specialization B1<D2>, and SayHi() expands to:

现在,再来看第二次SayHi()调用。这次,它使用B1<D2>SayHi()展开如下:

void B1<D2>::SayHi()

{

D2* pT = static_cast<D2*>(this);

 

    pT->PrintClassName();

}

This time, D2 does contain a PrintClassName() method, so that is the one that gets called.

这次D2包含了PrintClassName()函数,所以会直接调用这个函数。

The benefits of this technique are:

这个技巧的好处是:

·                                 It doesn't require using pointers to objects.

·                                 It saves memory because there is no need for vtbls.

·                                 It's impossible to call a virtual function through a null pointer at runtime because of an uninitialized vtbl.

·                                 All function calls are resolved at compile time, so they can be optimized.

·                                 它不需要用对象指针

·                                 它节约了vtbls所需的内存

·                                 在运行时不可能发生因为没有初始化vtbl而通过一个空指针调用虚函数。

·                                 所有的函数调用在编译时被处理并优化。

While the saving of a vtbl doesn't seem significant in this example (it would only be 4 bytes), think of the case where there are 15 base classes, some of those containing 20 methods, and thes savings adds up.

在这个例子中节约vtbl的内存空间似乎不是很有意义,因为它只需要4个字节,试想如果现在处理的是15个基类,每个基类都有20个方法,那会节约多少内存阿!

ATL Windowing Classes

OK, enough background! Time to dive into ATL. ATL is designed with a strict interface/implementation division, and that's evident in the windowing classes. This is similar to COM, where interface definitions are completely separate from an implementation (or possibly several implementations).

好的,有了足够的背景知识,下面我们将深入ATLATL原意是为了实现一种严格的接口/实现分离的机制,这在它的窗体类中是很明显的事情。这有点像COMCOM的接口定义就是完全和实现(可能是一个实现)分离的。

ATL has one class that defines the "interface" for a window, that is, what can be done with a window. This class is called CWindow. It is nothing more than a wrapper around an HWND, and it provides almost all of the User APIs that take an HWND as the first parameter, such as SetWindowText() and DestroyWindow(). CWindow has a public member m_hWnd that you can access if you need the raw HWND. CWindow also has a operator HWND method, so you can pass a CWindow object to a function that takes an HWND. There is no equivalent to CWnd::GetSafeHwnd().

ATL有一个定义了窗体接口的类CWindow。它是一个HWND句柄的封装,它几乎提供了用户API中所有的第一个参数是HWND的函数,例如SetWindowText()DestroyWindow()CWindow有一个公共的成员m_hWnd,如果你希望使用HWND句柄时,可以使用它。CWindow中没有与CWnd::GetSafeHwnd()等价的函数。

(如果你看过MFC的代码的话,CWnd::GetSafeHwnd()是在ASSERT(m_hWnd)后,返回了m_hWnd,使用CWindow::m_hWnd时,需要注意句柄是否为空,当然正常情况下为空的情况并不多见。 --- 蜗牛手记)

CWindow is very different from MFC's CWnd. CWindow objects are inexpensive to create, since there is only one data member, and there is no equivalent to the object maps that MFC keeps internally to map HWNDs to CWnd objects. Also unlike CWnd, when a CWindow object goes out of scope, the associated window is not destroyed. This means you don't have to remember to detach any temp CWindow objects you might create.

CWindowMFCCWnd有很多的不同。CWindow对象是一个很轻巧的对象,因为它只有一个数据成员,它不像CWnd那样保存着子类功能的函数映射。也不像CWnd那样在注销的时候自动销毁所连接的窗体(HWND),这就意味着你不得不自己detach所有你生成的临时CWindow对象。

The ATL class that has the implementation of a window is CWindowImpl. CWindowImpl contains the code for such things as window class registration, window subclassing, message maps, and a basic WindowProc(). Again, this is unlike MFC where everything is in one class, CWnd.

ATL还有一个窗体的实现类CWindowImplCWindowImpl包含像窗体注册,子类化,消息映射,WindowProc()函数这样功能的代码。要说明的是,这一点不像MFCMFC中的每件东西都在一个类中,CWnd

There are also two separate classes that contain the implementation of a dialog box, CDialogImpl and CAxDialogImpl. CDialogImpl is used for plain dialogs, while CAxDialogImpl is used for dialogs that host ActiveX controls.

2个单独的类包含对话框的实现,CDialogImplCAxDialogImplCDialogImpl用于建立简单的对话框,而CAxDialogImpl用于创建包含ActiveX控件的对话框。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WTL 具有两面性,确实是这样的。它没有MFC的界面(GUI)类库那样功能强大,但是能够生成很小的可执行文件。如果你象我一样使用MFC进行界面编程,你会觉得MFC提供的界面控件封装使用起来非常舒服,更不用说MFC内置的消息处理机制。当然,如果你也象我一样不希望自己的程序仅仅因为使用了MFC的框架就增加几百K的大小的话,WTL就是你的选择。当然,我们还要克服一些障碍: ATL样式的模板类初看起来有点怪异 没有类向导的支持,所以要手工处理所有的消息映射。 MSDN没有正式的文档支持,你需要到处去收集有关的文档,甚至是查看WTL的源代码。 买不到参考书籍 没有微软的官方支持 ATL/WTL的窗口与MFC的窗口有很大的不同,你所了解的有关MFC的知识并不全部适用与WTL。 从另一方面讲,WTL也有它自身的优势: 不需要学习或掌握复杂的文档/视图框架。 具有MFC的基本的界面特色,比如DDX/DDV和命令状态的自动更新功能(译者加:比如菜单的Check标记和Enable标记)。 增强了一些MFC的特性(比如更加易用的分隔窗口)。 可生成比静态链接的MFC程序更小的可执行文件(译者加:WTL的所有源代码都是静态链接到你的程序中的)。 你可以修正自己使用的WTL中的错误(BUG)而不会影响其他的应用程序(相比之下,如果你修正了有BUG的MFC/CRT动态库就可能会引起其它应用程序的崩溃。 如果你仍然需要使用MFCMFC的窗口和ATL/WTL的窗口可以“和平共处”。(例如我工作中的一个原型就使用了了MFC的CFrameWnd,并在其内包含了WTL的CSplitterWindow,在CSplitterWindow中又使用了MFC的CDialogs -- 我并不是为了炫耀什么,只是修改了MFC的代码使之能够使用WTL的分割窗口,它比MFC的分割窗口好的多)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值