作者:李晓飞
下载本文示例工程
一、闲聊
首先,在这里向前段时间没来得及回复你们问题的朋友们说声对不起了,这段时间工作实在太忙,我快倒!哈哈!好了,让我们转入正题,今天要谈的话题是COM,稍微深入一点,不知道大家用过C++Test或者Visual Assistant(可到VC知识库工具栏目下载)之类的软件没有,它们都有个非常引人注目的功能,那就是把它们自身嵌入到VC开发环境中去。这个功能让我痴迷不已,原因只有一个:我想做一个可以嵌入VC开发环境的VC工程解析器(VC/Delphi工程解析器已被收录在VC知识库在线杂志第19期中),这样用户在VC开发环境中就可以直接对当前或所有工程进行各种分析,统计。那么实现它简单吗?简单,Next和Copy即可轻松完成;仅仅这些吗?不是,它的背后还有博大精深的COM做支撑。不管困难与否,还是让我们先试为快。
二、效果图
三、实现步骤:
<3.1>新建一个<DevStudio Add-in Wizard>类型工程,输入工程名称"CodeAnalyser".
<3.2>进入第二个画面,系统要求用户输入插件的名称和描述信息。并且要求用户选择
是否需要生成工具栏以及是否自动添加VC事件响应代码。
<3.3>点击"Finish"结束向导,进入代码编辑窗口。
在这里我们要说的一点是:该工程引用了ICommands接口,并从该接口上派生出 CCommands类。该类完成了所有用户自定义函数接口,VC应用程序消息响应和VC调试动作的消息响应工作。当我们真正为CCommands类添加成员函数之前我们必须先为ICommands接口添加相应的函数接口声明。在本工程中我总共为ICommands接口添加了两个函数接口,它们名字分别为:GetCurDirCommandMethod和QuitCommandMethod声明如下:(在CodeAnalyer.odl文件中)
interface ICommands : IDispatch
{
// methods
[id(1)] //在Vtable中的函数索引号
HRESULT GetCurDirCommandMethod(); //得到VC当前工作目录
[id(2)] //在Vtable中的函数索引号
HRESULT QuitCommandMethod (); //退出VC编辑器
};
在接口ICommands添加接口函数,那么相应的我们也要在类CCommands中声明和实现ICommands接口函数,函数的内部代码和普通工程代码没什么区别。
//Implement(CCommands类内部接口函数的声明)
public:
STDMETHOD(GetCurDirCommandMethod)(THIS);
STDMETHOD(QuitCommandMethod)(THIS);
//Function Code(Ccommands类内部接口函数的实现)
//得到当前VC开发环境的工作目录[您也可以让它成为你想要实现的功能代码]
STDMETHODIMP CCommands::GetCurDirCommandMethod()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
BSTR bstrCurDir;
m_pApplication->get_CurrentDirectory(&bstrCurDir);
CString str(bstrCurDir);
::MessageBox(NULL, str, "VC工作目录", MB_OK | MB_ICONINFORMATION);
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
return S_OK;
}
//退出VC开发环境
STDMETHODIMP CCommands::QuitCommandMethod()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
if(::MessageBox(NULL,
"您想退出VC++编辑器吗(Y/N)?",
"询问信息...",
MB_YESNO | MB_ICONQUESTION) == IDYES)
m_pApplication->Quit();
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
return S_OK;
}
<3.4>
创建工具栏,连接工具栏按钮事件所有的幕后工作已经准备就绪,只差个工具栏界面就一切OK了。打开类CDSAddIn,它里面有三个成员函数,其中
OnConnection和
OnDisconnection成员函数的意义非常重要。它们的意义如下:
<1>
OnConnection:
插件的初始化任务都在这里完成。如COM服务的启动,工具栏/菜单栏的创建,工具栏按钮/菜单项的添加与修改等等。<2>
OnDisconnection:
插件的卸载工作都在这里完成。如COM服务的卸载,工具栏/菜单栏的销毁,释放等等。
了解了它们各自的用途之后我们就可以在相应的消息事件中添加代码了。很显然工具栏的初始化应该在
OnConnection事件中完成。
在
OnConnection事件中系统首先获得了VC应用程序接口,然后调用一个接口函数:AddCommand来为插件添加命令和命令影射函数。然后再使用另外一个接口函数AddCommandBarButton向工具栏中添加工具栏按钮,其中每个工具栏按钮会和一个命令标志符号相连接,这样就能实现按钮和命令(消息)之间的一一对应。下面是
添加一个命令和一个工具栏按钮的代码(如果你要添加多个工具栏按钮只要重复此步骤即可):
LPCTSTR szCommand = _T("GetCurDirCommand");
VARIANT_BOOL bRet;
CString strCmdString;
strCmdString.LoadString(IDS_CMD_STRING);
strCmdString = szCommand + strCmdString;
CComBSTR bszCmdString(strCmdString);
CComBSTR bszMethod(_T("GetCurDirCommandMethod"));
CComBSTR bszCmdName(szCommand); //和下面添加工具栏按钮对应
VERIFY_OK(pApplication->AddCommand(bszCmdString,bszMethod,0,dwCookie,&bRet));
//AddCommand 参数含义:
//bszCmdString:命令字符串。
//bszMethod:Icommands接口函数名。
//第三个参数代表位图偏移量。
//第四和第五个参数分贝为系统参数和返回值(参照MSDN的IApplication介绍)
if (bRet == VARIANT_FALSE)
{
*OnConnection = VARIANT_FALSE;
return S_OK;
}
//添加工具栏按钮
if (bFirstTime == VARIANT_TRUE)
{
VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));
}
<3.5>
编译,连接及在VC中引入插件以上就是我们所有的代码工作,接下来赶快Build以下吧。编译通过的话,在你的工程Debug目录下会有个dll文件。然后打开VC编辑器,在VC任何一个工具栏上点击鼠标右键,弹出如下图所示菜单。然后选择”Customize”子菜单,打开如下图所示的工具栏定制窗口:
接着选择该窗口的最后一页"Add-Ins and Macro Files"出现下图所示窗口。
然后点击”Browse...”按钮,这时打开你工程下的Debug目录中的DLL文件,这样你就可以看到你制作的工具栏了。同样你再次打开上面的菜单,这次可以看到多了一个工具栏,并且名字乱七八糟的,怎么改变工具栏的名字呢?方法很简单:打开上面窗口中的”Toolbars”选项页,在工具栏列表框中找到你的工具栏,然后在”Toolbar name”编辑框中输入你想要的名字即可。再打开上面的菜单看看名字是不是变了,哈哈!
OK,今天的话题就聊到这里,还是老规矩,有什么问题请MAIL给我,再次祝大家学习愉快. Bye!
<!-- Search Google -->
输入您的搜索字词 提交搜索表单
|
|
<!--
google_ad_client = "pub-7330597899926046";
google_ad_format = "350x30_sdo";
google_link_target = 2;
google_color_bg = "ffffff";
google_color_link = "000000";
google_encoding = "GB2312";
//-->
|
<!-- Search Google --> <!--
google_ad_client = "pub-7330597899926046";
google_ad_slot = "8791774696";
google_ad_width = 468;
google_ad_height = 60;
//-->
分享到:
相关推荐
本书旨在揭示VC++编程中的高级技术和内部机制,帮助读者提升对C++语言的理解,以及在实际项目中更高效地运用MFC(Microsoft Foundation Classes)库。 首先,C++是一种静态类型的、编译式的、通用的、大小写敏感的...
总的来说,创建一个如“用VC++.NET实现的MAYA插件”这样的项目,需要深入理解Maya的API,掌握C++编程,以及对三维模型数据结构的深刻认识。一旦完成,这样的插件将极大地提高工作效率,使用户能够轻松地导出和处理...
8. **实例应用**:可能涵盖了一些实际场景的应用,如DLL用于实现插件系统、通信协议解析、图形界面扩展等,这些实例将加深你对DLL编程的理解。 9. **调试技巧**:学习如何在Visual Studio中调试DLL,包括设置调试...
VC++实现Hook编程是一种在Windows环境下对特定函数调用进行拦截和修改的技术,它允许开发者在不修改目标程序源码的情况下,对系统或应用程序的行为进行动态监控和改变。Hook技术在逆向工程、调试、系统监控、插件...
总之,VC++ 6.0插件是开发者优化经典IDE功能的有效手段,它们通过扩展和改进原始软件,使用户能够在保持对老版本的熟悉度的同时,享受更现代化的编程环境。对于那些依然坚守在VC6.0阵线的程序员而言,这些插件无疑是...
本书主要从程序内部运行的机制和MFC程序的组织脉络入手,使读者在学习VC++编程知识时,既能够知其然,又能知其所以然,从而帮助读者从根本上理解和掌握Windows的程序设计。另外,全书还贯穿作者多年来学习编程的一些...
它允许对象的使用者无需了解对象的内部实现即可调用其方法。在开发PowerPoint插件时,COM使得我们可以创建独立于具体实现的组件,这些组件可以被PowerPoint识别并调用。 2. **ATL详解**:ATL是为了简化COM对象的...
"Wordpad VC++"是一个基于...通过学习和实践Wordpad VC++项目,开发者不仅可以掌握Windows桌面应用开发的基本技术,还能深入了解文本编辑器的内部工作原理,对于提升C++编程技能和理解操作系统层面的编程有极大的帮助。
【VC++源码(notepad++6.3)】是一个基于C++编程语言的源代码项目,主要用于学习和参考,尤其是对于那些想要深入了解编辑器开发的程序员。Notepad++是著名的开源文本编辑器,以其轻量级、高效以及对多种编程语言的...
- **封装**: 将数据和操作这些数据的方法绑定在一起,形成一个整体,对外隐藏内部实现细节。 - **继承**: 一种类之间共享属性和行为的机制,子类可以从父类继承属性和方法,并可以对其进行扩展。 - **多态**: 同一个...
4. **事件处理**:在VC++中,需要理解和实现事件驱动编程,以便响应AutoCAD中的用户操作或系统事件。 5. **编译和调试**:VC++ IDE提供了强大的编译和调试工具,如调试器,这对于识别和修复代码中的问题至关重要。 ...
这个插件包含源程序,这意味着用户不仅可以直接使用,还可以学习其内部实现机制,甚至根据自己的需求进行二次开发。源代码通常以C++语言编写,遵循VC++6.0的编程规范和API调用。通过分析和修改源代码,开发者可以...
由于是用VC++编写,开发者可以深入研究其内部机制,理解如何在Windows环境中实现高性能的图形渲染和交互。 3. **VC%2B%2B开发的CAD绘图软件EastDraw源代码.rar**:这个文件提供的可能是名为“EastDraw”的CAD软件的...
《VC++深入详解源代码》是一本专注于微软Visual C++编程技术的深度解析书籍,它涵盖了从基础到高级的各种主题,旨在帮助读者深入理解VC++的内部工作机制和编程技巧。通过对源代码的详细分析,本书提供了丰富的实践...
【VC++动态链接库(DLL)编程深入浅出】这篇文档深入探讨了VC++中动态链接库(DLL)的编程技术。DLL是一种可共享代码的仓库,它包含可供其他程序使用的函数、变量或类。与静态链接库不同,DLL不包含在最终的EXE文件中...
在"PowerPoint2000/XP内部COM插件VC源代码"中,开发者可能使用了MFC的COleObjectFactory和COleServerDoc等类来实现COM服务器的部分。COleObjectFactory用于创建和注册COM对象,而COleServerDoc则处理服务器文档,...
MapWinGis v5.2.4.0是该控件的一个特定版本,它包含了源代码,并且附带了第三方库,这意味着开发者不仅可以使用这个控件,还可以深入研究其内部实现,进行定制化开发或优化。这个版本支持扩展到如百度、高德等常见的...
总的来说,使用VC++进行Office开发是一项高级技能,它需要对Windows API、COM组件、.NET框架以及Office应用程序的内部工作原理有深入理解。通过这种方式,开发者可以构建出强大且定制化的办公解决方案,极大地提升...