WTL 助手






4.92/5 (114投票s)
2004 年 11 月 24 日
13分钟阅读

772582

8841
Microsoft VC++.NET 2003 的一个插件,用于帮助 WTL 插入消息处理程序。
引言
当我开始使用 WTL 时,我发现没有工具可以帮助我像类向导那样添加消息处理程序。因此,我决定开发自己的 Microsoft Visual Studio (MS VS) 插件来完成这项工作。抱歉我的英语不好,我不太会说。
使用加载项
首先,您应该下载 WTL Helper Setup 并运行它来安装插件。该插件会自动注册快捷键 CTRL+ALT+W 来调用对话框。但是,如果您使用预定义的键盘映射方案之一,则快捷键注册会失败。相反,您应该创建当前键盘映射方案的副本。为此,请转到菜单 Tools->Options。在 Environment 部分,选择 Keyboard,按下 Save As 按钮并为新的键盘方案选择一个名称。然后,您可以手动设置 WTL Helper 的快捷键(其完整名称为 WtlHelper.Connect.WtlHelper)。
消息映射
如果插件安装正确,WTL Helper 子菜单将出现在 Tools 菜单中。单击 WTL Helper,您将看到上面显示的对话框。左侧 TreeView 面板的结构在 WTL 文件中进行了描述。如果使用安装程序,这些 WTL 文件将被解压到 {installation_path}\Messages 目录,或者它们位于源代码存档的 \wtl 子目录中。这些文件的描述如下。我已按类别对这些消息进行了分组,以便更快地搜索。如果您认为此顺序不方便,可以修改 WTL 文件以拥有自己的消息树视图。
DDX 映射
在对话框的左侧面板中,您可以看到所选对话框的控件 ID。默认情况下,组合框中只有对话框类。在右侧面板中,是与这些 ID 控件相对应的变量。
选项
其他菜单项 Options 允许您选择以下选项:
消息选项
- 消息处理程序的默认样式(新或旧)
- 消息处理程序的排序(开/关)
- 函数处理程序(内联或在 CPP 中)
- 将使用哪个
CRect
、CPoint
、CSize
类:WTL 或 ATL - 处理程序颜色
DDX 选项
- DDX 变量的默认保护级别
- 在 Variables 选项卡上仅显示对话框类还是所有类
- 对 DDX 变量使用类型前缀
更多关于这些选项的解释将在下面给出。
消息选项讨论
- WTL 3.1 及更高版本有一个名为 atlcrack.h 的文件。在此文件中,有许多消息处理程序可以解包(crack)
wParam
和lParam
。因此,消息处理程序函数变得更加简洁。但是,存在一些问题,因为 cracking 必须与以BEGIN_MSG_MAP_EX
而不是BEGIN_MSG_MAP
开头的消息映射一起使用。BEGIN_MSG_MAP
宏和 cracked handlers 仅适用于 ATL 7.0 及更高版本,并且仅适用于继承自CWindowIml
或CDialogImpl
的类。 - 您可以使用消息处理程序的排序,该排序默认启用。排序意味着消息映射中的所有新消息处理程序将按以下顺序插入:
- Windows 消息处理程序,如
WM_CREATE
、WM_DESTROY
等 - 命令消息处理程序:
WM_COMMAND
消息的一部分 - 通知消息处理程序:
WM_NOTIFY
消息的一部分 - 其他消息处理程序(用户定义的消息)
CHAIN_MSG_MAP
- Windows 消息处理程序,如
- 如果为 true,则函数插入到头文件中。否则,函数插入到 CPP 文件中。
- ATL 7.0 及更高版本有一个名为 atltypes.h 的文件。在此文件中,声明了
CRect
、CPoint
和CSize
等类。您也可以使用 WTL 类CRect
、CPoint
和CSize
。如果勾选此选项,您将使用 WTL 类。否则,您将使用 ATL 类。如果您选择 WTL 类,则文件 <atlmisc.h> 将包含在每个声明使用CRect
、CPoint
、CSize
的消息处理程序的头文件中。如果您选择 ATL 类,则文件 <atltypes.h> 将以相同方式包含。 - 从 0.9.9.0 版本开始,您还可以设置处理程序的突出显示颜色。只需按下按钮,您就会看到类似的对话框。
选择您最喜欢的颜色,处理程序将以该方式突出显示。
DDX 选项讨论
- 当对话框要求新 DDX 条目的参数时,变量的默认保护类型。
- 如果选中此选项,则在 Variables 选项卡上仅显示基于对话框的类。在其他情况下,将显示所有类。
- 如果设置此标志,则所有自动生成的变量名都将带有类型前缀,例如
i
(m_iVar1
)或str
(m_strVar2
)。
上下文菜单
从 0.9.9.0 版本开始,我添加了一些上下文菜单处理程序,以方便调用 WTL Helper。在 Visual Studio 2003 中,上下文菜单是 MS Office 命令栏。因此,我需要知道它们的名称来添加我的菜单项。以下是命令栏名称及其调用位置:
- 类视图项:类视图窗口
- 资源编辑器:除菜单编辑器外的所有资源编辑器
- 菜单设计器:菜单编辑器
加载插件后,我的菜单项会出现在这些上下文菜单中。
类视图
我添加了两个菜单项,用于显示 WTL Helper 的主窗口。唯一的区别是第一个将处理程序/函数页面设置为默认值,第二个将 DDX 变量页面设置为默认值。
资源编辑器
对于快捷键或工具栏按钮,您可以直接添加命令处理程序。
在上图中,您可以看到对话框的上下文菜单。前两项与类视图的相同。要使用最后一项,您需要拥有 WTL Wizards 至少 1.1 版本。WTL Wizards 是一组用于添加 WTL 类的对话框。
您无需显示 WTL Helper 的主窗口,就可以直接为控件添加处理程序或变量。
菜单编辑器
与快捷键或工具栏按钮相同,您可以直接为菜单项添加命令处理程序。
对话框资源视图
对话框编辑器也是如此。
获取选定的资源项
当我尝试获取当前资源 ID 和选定的资源项时遇到了一些麻烦。Visual Studio 插件框架没有记录在案的方法来获取此类信息。最困难的是确定当前正在编辑的资源及其 ID。我不是以正确的方式完成的(我不知道正确的方式),但我找到了一种解决方法。您可以看到,资源编辑窗口的标题由资源文件名、当前正在编辑资源的 ID 和资源类型组成。因此,我使用此标题来获取我需要的所有信息。
下一个问题是如何检索当前正在编辑的资源项(菜单项、对话框控件等)的 ID。您可以从 EnvDTE::SelectedItems
对象获取 EnvDTE::SelectionContainer
对象,然后可以获取选定项的对象。但是,对于资源项,没有这样的文档。这些对象定义在 ResEditPKGLib
中。要使用它们,您应该像这样导入具有 GUID {7365C6FE-4191-476B-A3FE-1CB6A7B1C119} 的 TLB:
#import "libid:7365C6FE-4191-476B-A3FE-1CB6A7B1C119" version("7.1") lcid("0") no_implementation
每个资源项对象都有一个 ID 属性,但这些对象没有通用接口。因此,我使用 IDispatch
接口的 Invoke
方法来检索当前资源项 ID。
重写函数
从 0.9.9.0 版本开始,我添加了重写父类某些函数的功能。在上图所示的菜单中,可以看到 CScrollWindowImpl
类的子类的菜单。前两个函数适用于除对话框类之外的所有类。其他函数仅适用于指定类。例如,DoScroll
和 DoPaint
仅适用于 CScrollImpl
的子类。
处理 EnvDTE 时遇到的问题
问题在于没有精确的映射定义。我认为在 Microsoft 中,映射被称为从预定义宏之一开始的对象,例如 BEGIN_MSG_MAP
、BEGIN_MESSAGE_MAP
等。这在使用 EnvDTE
的此对象时会产生一些问题。
宏 BEGIN_MSG_MAP_EX
不被识别为映射的开始;它被识别为一个函数。类声明中使用的所有宏也被识别为函数。但这并不是主要问题。主要问题是,当您使用 BEGIN_MSG_MAP_EX
或其他映射(如 DDX 映射)创建消息映射并尝试将函数插入源文档时,会返回错误。
第二个问题是某些映射条目和映射结束的识别。例如:
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>) CHAIN_MSG_MAP(CUpdateUI<CMainFrame>) CHAIN_MSG_MAP(CMessageFilter) CHAIN_MSG_MAP(CIdleHandler<CMainFrame>)
...被识别为
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>) CHAIN_MSG_MAP(CMessageFilter) CHAIN_MSG_MAP(CIdleHandler<CMainFrame>)
当我试图理解这种行为时,我发现第二个 CHAIN_MSG_MAP
带有参数模板化类(在示例中为 CUpdateUI<CMainFrame>
)未被识别。但是,如果第二个 CHAIN_MSG_MAP
是 CMessageFilter
,第三个是 CUpdateUI<CMainFrame>
,那么 CMessageFilter
可以正确识别,但 CUpdateUI<CMainFrame>
无法识别。
当某些映射条目在映射 EnvDTE
中未被识别时,映射的结束也不会被识别。BEGIN_MSG_MAP_EX
还有另一个问题。如果映射以 BEGIN_MSG_MAP_EX
开头,以 END_MSG_MAP
结尾,那么 EnvDTE
无法识别映射之后的任何 CodeElement
。我通过以下方式解决了这个问题:我在 stdafx.h 中添加了一个宏。
#define END_MSG_MAP_EX END_MSG_MAP
当我在与映射相同的头文件中添加此宏时,结果与没有宏时相同。但是,它在 stdafx.h 中运行良好。
Using the Code
主要功能位于文件 VSElements.h 或 VSElements.cpp 中。这是我对 EnvDTE
关于 CodeElement
接口的封装。有一些类包装了函数、变量、映射、类和函数的参数。
这些包装器中最重要的是映射包装器 VSMap
。我重写了这个类来获取映射条目,因为使用 EnvDTE::CodeElement
(种类为 EnvDTE::vsCMElementMap
)或 VCCodeModelLibrary::VCCodeMap
无法获得我们想要的精确结果。这些问题已在上面描述。
我创建了一个名为 VSMessageMap
的特殊类用于消息映射。我很抱歉文件中存在俄语注释,但没有足够的时间添加英文注释。您在工作时看到的所有对话框都在 \dialog 子目录中。用于解析资源的类在 \resources 子目录中。
结论
WTL Helper 的最新版本在此处:here。您可以帮助我使 WTL Helper 更好。我需要有人为我绘制工具栏和图标,因为我认为它们现在不太好。
历史
- 2004 年 11 月 24 日:0.6
- 首次发布
- 2004 年 11 月 25 日:0.6.0.1
- 修复了安装程序中的错误
- 将 WTL 文件添加到安装程序中
- 2004 年 12 月
- 0.7.5.0 1
- 将 COM 接口指针替换为
_com_ptr
对象 - 修复了 dialogs.dat 中
CAxDialogImpl
的错误名称 - 修复了 Alex Cherepanov 报告的错误
- 添加了在添加类型为
CString
的 DDX 映射条目时选择包含哪个CString
(ATL 或 WTL)的选项
- 将 COM 接口指针替换为
- 0.7.5.1 2
- 修复了映射条目没有参数的错误
- 在安装程序中放置了正确版本的插件
- 0.7.6.0 9
- 为 DDX 添加了两个小型增强功能
- 0.7.5.0 1
- 2004 年 12 月 21 日:0.8.0.0
- 移除了在添加控件消息的 DDX 变量时,在对话框的 ComboBox 中添加菜单和快捷键 ID
- DDX 的一些小修复
- 为
static
消息添加了 WTL 文件 - 添加了对嵌套类和命名空间的支持
- 重新构建了选项对话框
- 2004 年 12 月 23 日:0.8.1.0
- 在选项对话框中添加了 关于 页面
- 修复了 DDX 中的一个小错误
- 2005 年 1 月 11 日:0.8.2.0
- 修复了消息排序中的错误
- 现在在 关于 选项卡中显示版本号
- 区分系统选项和用户选项
- 添加了两个选项
- 将使用哪个
CRect
、CPoint
、CSize
类:WTL 或 ATL - 在 Variables 选项卡上仅显示对话框类或所有类
- 将使用哪个
- 2005 年 2 月 7 日:0.9.0.0
- 大量修复和优化
- 添加了对
ALT_MSG_MAP
的支持 - 添加了对
REFLECT_NOTIFICATIONS
和FORWARD_NOTIFICATIONS
的支持 - 更改了界面,现在对话框具有可调整大小的边框
- 添加了对
XXX_RANGE_XXX
处理程序的支持 - 为 Custom Window Message 添加了对
MESSAGE_HANDLER_EX
的支持 - 为工具提示添加了 WTL 文件
- 2005 年 2 月 11 日:0.9.0.1
- 修复了工具栏错误
- 2005 年 2 月 24 日:0.9.0.2
- 提高了稳定性
- 修复了一个小错误
- 2005 年 2 月 25 日:0.9.0.3
- 修复了 Ning 报告的错误
- 添加了为处理程序选择函数的功能(仅适用于通知或命令消息)
- 2005 年 2 月 28 日:0.9.0.4
- 修复了在 MFC 或控制台项目中启动 WTL Helper 时的错误
- 2005 年 3 月 10 日:0.9.0.5
- 添加了为 Windows 消息处理程序选择函数的功能,并改进了通知和命令消息
- 修复了尝试移至未插入的函数时发生的崩溃
- 修复了 Apply 按钮错误
- 2005 年 3 月 16 日:0.9.0.6
- 修复了资源文件加载错误
- 添加了对 XP 主题的支持
- 2005 年 3 月 21 日:0.9.0.7
- 修复了对话框类中没有
enum IDD
时发生的崩溃
- 修复了对话框类中没有
- 2005 年 3 月 29 日:0.9.1.0
- 修复了添加 DDX 变量对话框中控件类型检测错误的 bug
- 将 EDITBOX 的 DDX 变量的默认类型设置为
UINT
,该 EDITBOX 具有ES_NUMBER
样式而不是CString
- 为 DDX 变量添加了自动生成名称的功能
- 2005 年 4 月 26 日:0.9.1.1
- 添加了输入控件 ID 和函数名的非常长的名称的可能性
- 2005 年 5 月 23 日:0.9.1.2
- 修复了添加函数
- 2005 年 10 月 17 日:0.9.9.0
- 为处理程序添加了颜色高亮显示
- 添加了重写父函数(非
virtual
)的可能性 - 将菜单项添加到上下文菜单
- 增加了与 Visual Studio 2005 Beta 2 的兼容性
- 修复了一些错误
- 2005 年 10 月 28 日:0.9.9.1
- 为资源视图中的对话框项添加了上下文菜单
- 2005 年 11 月 10 日:1.0
- 更改了图标
- 在 Help->About 中添加了 WTL Helper 的信息
- 修复了与 Visual Studio 2005 的一些兼容性问题
- 2005 年 11 月 14 日:1.0.2
- 修复了分割器错误
- 修复了 Visual Studio 2005 的一些错误
- 2006 年 1 月 26 日:1.1
- 增加了对扩展消息反射宏的支持(WTL 7.5 及以上版本)
- 添加了“保存上次显示的页面”选项
- 添加了 WTL 版本信息的功能
- 添加了允许为对话框添加
PreTranslateMessage()
和OnIdle()
的选项
- 2006 年 2 月 17 日:1.1.3
- 修复了文件名处理错误
- 修复了尝试为对话框插入
PreTranslateMessage()
和OnIdle()
函数时发生的崩溃 - 修复了 Visual studio 2005 工具栏问题
- 一些小的修复和改进
- 2006 年 3 月 28 日:1.1.4
- 修复了在解决方案未加载时调用 WTL Helper 时发生的崩溃
- 2006 年 7 月 7 日:1.1.5
- 修复了 Visual studio 2005 工具栏问题
- 2006 年 11 月 14 日:1.1.6
- 修复了工具栏重复问题
- 2007 年 4 月 27 日:1.1.7
- 再次修复 :) Visual Studio 2005 中的工具栏问题
- 2007 年 8 月 27 日:1.1.8
- 修复了旧样式通知处理程序问题
- 添加了为当前解决方案保存旧样式或新样式处理程序的选项