WTLVisual C++ 7.1Visual C++ 8.0Visual Studio .NET 2003Visual Studio 2005MFC初学者开发Visual StudioWindowsC++
MFC 停靠框架






4.37/5 (19投票s)
易于使用的 MFC 停靠框架等等...它还展示了一种混合 WTL 和 MFC 的适用方法。
目录
屏幕截图

简介
一个漂亮的 UI 是一个好的应用程序的重要组成部分,除此之外还有其他标准,例如性能、稳定/可靠性...就个人而言,我非常喜欢 CodeProject 很久以前发布的以下库。
- 自定义标签控件、选项卡式框架和选项卡式 MDI 作者:Daniel Bowen
- WTL 停靠窗口 作者:Sergey Klimov
- 选项卡控件和分隔器 - 混合在一起 作者:Igor Katrayev
这些列出的库是用 WTL 编写的。但是,将 MFC 和 WTL 混合在一起非常困难。显然,要求开发人员或团队放弃 MFC 并迁移到 WTL 世界是不合理的,仅仅因为有一些用 WTL 编写的优秀控件或视觉框架(有很多因素需要考虑,尤其是在像我工作的公司这样拥有数百名开发人员的公司)。不幸的是,直到现在 MFC 中还没有这样好且免费的视觉框架。无论有什么困难,我仍然希望能够使用它们,现在我的努力与您分享。
幕后
技术决策
有两种可能的方案
- 完全移植 WTL 源代码到 MFC:这种方法存在一些问题。首先,这需要我花费大量时间(仅仅是为了重写别人已经做过的事情)。其次,原始作者的错误修复和增强将无法及时更新。第三,如果有一天发布了另一个好的针对 WTL 的库,我将不得不再次移植。考虑到这些原因,我决定不采取这种方向。
- 混合 MFC 和 WTL:我知道这种方法有很多问题,正如文章 混合 WTL 与 MFC 的论坛中所显示的。由于我无意拥有一个通用的方法来集成所有(现在和未来)针对 WTL 的库,而仅仅是为了上面列出的这些库,我相信这是可能的。
它是如何工作的?
这是 MFC 包装器的核心
template<class TMFCWnd, class TWTLCWindow>
class ATL_NO_VTABLE CWTL4MFCWndT : public TMFCWnd
{
public:
typedef TWTLCWindow WTLClass;
WTLClass m_wndWTLPeer;
virtual void PreSubclassWindow()
{
m_wndWTLPeer.m_hWnd = m_hWnd;
__super::PreSubclassWindow();
}
virtual LRESULT WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
if(FALSE == m_wndWTLPeer.ProcessWindowMessage
(m_hWnd, nMsg, wParam, lParam, lResult))
{
ASSERT(::IsWindow(m_hWnd));
lResult = TMFCWnd::WindowProc(nMsg, wParam, lParam);
}
return lResult;
}
__if_exists(TWTLCWindow::PreTranslateMessage) {
virtual BOOL PreTranslateMessage(MSG* pMsg)
{
BOOL blRes1 = __super::PreTranslateMessage(pMsg);
BOOL blRes2 = m_wndWTLPeer.PreTranslateMessage(pMsg);
// if both WTL & MFC handle this message
// there maybe a problem, consider to override
// this method in derived class
ASSERT(FALSE == (blRes2 && blRes1));
return (blRes1 | blRes2);
}}
};
没什么可说的;对于每个窗口消息(WM_xxx
),如果相应的 WTL 对等体不处理它,MFC 包装器就会处理。
潜在问题
当 WTL 对等体处理了窗口消息(WM_xxx
)(从 ProcessWindowMessage
返回 TRUE
)但该消息对 MFC 框架也很重要时,就会出现问题。为了解决这个问题,我选择了一个非常简单的方法:**逐个进行测试和解决**。
使用代码
将此库应用于现有 MFC 项目很容易;以演示项目为例,作为您的起点。这是类图供快速参考。

支持的编译器
- Visual Studio 2003
- Visual Studio 2005 - 由于此编译器版本中的一些更改,请将预编译头内存分配限制设置为 200 或更高值,以避免错误 C3859。
错误修复和更新
- 基本上,一个错误或一个功能请求可能属于这个 MFC 包装器(1),或者原始 WTL 代码(2),或者两者兼有(3)。我将尝试修复属于类别(1)和(3)的错误,并将其他错误转交给相应的作者(我将尽量不触碰 WTL 代码,除非确实有必要,当然,需要征得原始作者的同意)。
- 由于该库只是一个包装器,请记住也要从其他作者那里获取更新,并从WTL 库获取更新。
致谢
我想感谢 Daniel Bowen、Sergey Klimov 和 Igor Katrayev 为他们出色的 WTL 库。也感谢他们同意允许我在本文中重新分发他们的源代码(稍作修改)。
历史
- 2007 年 10 月 12 日:初始版本