一、背景

Eclipse中,对于JAVA项目,可在项目或者文件上的右键菜单Show in ->System Explorer中,直接在资源管理器中显示当前项目或当前文件所在文件夹,以便于在Windows资源管理器中对文件的操作管理。同样的,在Visual Studio 2010、2013、2015、2017等版本也有类似功能,VC6为早期版本,并无相应功能。本文通过对VC6 IDE插件的开发,实现了在VC6环境中直接打开资源管理器至当前项目所在文件夹,也可以打开命令行窗口,且路径直接切换至当前工作目录。先看效果:

二、实现过程

1、VC6中新建“DevStudio Add-in Wizard”插件工程。工程名为“OpenInExplorer”,插件项目向导中均使用默认选项,点击完成。向导完成后,生成的项目代码实际上为一COM组件。

2、生成项目中各类简要介绍(略),详见Microsoft参考文档

各个文件和类的解释参考微软Understanding the Results of the Add-in Wizard

3、在ResourceView视图中修改Bitmap资源:IDR_TOOLBAR_LARGE和IDR_TOOLBAR_MEDIUM文件。

4、在ResourceView视图中修改字串表,如下表所示:

ID

标题
IDS_CMD_STRING   \n在Windows资源管理器中打开-1\n在Windows资源浏览器中打开工程-2\n在Windows资源管理器中打开
IDS_CMD_STRING2   \n使用记事本打开1\n使用记事本打开2 \n使用记事本打开
IDS_CMD_STRING3   \n打开命令窗口1\n打开CMD窗口2\n打开命令窗口

5、在CDSAddin类的OnConnection函数中添加自己的工具栏按钮及要执行的命令,完整函数如下所示:

STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime,long dwCookie, VARIANT_BOOL* OnConnection)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());// Store info passed to usIApplication* pApplication = NULL;if (FAILED(pApp->QueryInterface(IID_IApplication, (void**) &pApplication))|| pApplication == NULL){*OnConnection = VARIANT_FALSE;return S_OK;}m_dwCookie = dwCookie;// Create command dispatch, send info back to DevStudioCCommandsObj::CreateInstance(&m_pCommands);m_pCommands->AddRef();// The QueryInterface above AddRef'd the Application object.  It will//  be Release'd in CCommand's destructor.m_pCommands->SetApplicationObject(pApplication);// (see stdafx.h for the definition of VERIFY_OK)VERIFY_OK(pApplication->SetAddInInfo((long) AfxGetInstanceHandle(),(LPDISPATCH) m_pCommands, IDR_TOOLBAR_MEDIUM, IDR_TOOLBAR_LARGE, m_dwCookie));// Inform DevStudio of the commands we implement// TODO: Replace the AddCommand call below with a series of calls,//  one for each command your add-in will add.// The command name should not be localized to other languages.  The //  tooltip, command description, and other strings related to this//  command are stored in the string table (IDS_CMD_STRING) and should//  be localized.LPCTSTR szCommand = _T("OpenInExplorerCommand");VARIANT_BOOL bRet;CString strCmdString;strCmdString.LoadString(IDS_CMD_STRING);strCmdString = szCommand + strCmdString;CComBSTR bszCmdString(strCmdString);CComBSTR bszMethod(_T("OpenInExplorerCommandMethod"));CComBSTR bszCmdName(szCommand);VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 0, m_dwCookie, &bRet));if (bRet == VARIANT_FALSE){// AddCommand failed because a command with this name already//  exists.  You may try adding your command under a different name.//  Or, you can fail to load as we will do here.*OnConnection = VARIANT_FALSE;return S_OK;}// Add toolbar buttons only if this is the first time the add-in//  is being loaded.  Toolbar buttons are automatically remembered//  by Developer Studio from session to session, so we should only//  add the toolbar buttons once.if (bFirstTime == VARIANT_TRUE){VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));}/******添加自定义工具栏按钮 Start************************************************************/// 添加第二个工具栏按钮LPCTSTR szOpenNotepadCommand = _T("OpenInNotepad");CString strOpenNotepadCmdString;strOpenNotepadCmdString.LoadString(IDS_CMD_STRING2);strOpenNotepadCmdString = szOpenNotepadCommand + strOpenNotepadCmdString;CComBSTR bszOpenNotepadCmdString(strOpenNotepadCmdString);CComBSTR bszOpenNotepadMethod(_T("OpenInNotepad"));CComBSTR bszOpenNotepadCmdName(szOpenNotepadCommand);VERIFY_OK(pApplication->AddCommand(bszOpenNotepadCmdString, bszOpenNotepadMethod, 1, m_dwCookie, &bRet));if (bRet == VARIANT_FALSE){*OnConnection = VARIANT_FALSE;return S_OK;}if (bFirstTime == VARIANT_TRUE){VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszOpenNotepadCmdName, m_dwCookie));}// 添加第三个工具栏按钮LPCTSTR szConsoleCommand = _T("OpenInCommand");CComBSTR bszConsoleCmdName(szConsoleCommand);CString strConsoleCmdString;strConsoleCmdString.LoadString(IDS_CMD_STRING3);strConsoleCmdString = szConsoleCommand + strConsoleCmdString;CComBSTR bszConsoleCmdString(strConsoleCmdString);CComBSTR bszConsoleMethod(_T("OpenInCommand"));VERIFY_OK(pApplication->AddCommand(bszConsoleCmdString, bszConsoleMethod, 4, m_dwCookie, &bRet));if (bRet == VARIANT_FALSE){*OnConnection = VARIANT_FALSE;return S_OK;}if (bFirstTime == VARIANT_TRUE){VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszConsoleCmdName, m_dwCookie));}/**********添加自定义工具栏按钮 End*************************************************************/*OnConnection = VARIANT_TRUE;return S_OK;
}

6、ClassView视图中,在CCommands类的接口上添加方法OpenInNotepad()和OpenInCommand()。并分别在CCommands类中实现这些方法。具体代码如下:

STDMETHODIMP CCommands::OpenInExplorerCommandMethod()
{AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: Replace this with the actual code to execute this command//  Use m_pApplication to access the Developer Studio Application object,//  and VERIFY_OK to see error strings in DEBUG builds of your add-in//  (see stdafx.h)VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));//获得DevStudio当前工作目录BSTR bstrCurrentDirectory;m_pApplication->get_CurrentDirectory(&bstrCurrentDirectory);char* lpszDir = _com_util::ConvertBSTRToString(bstrCurrentDirectory);// operation params:"open", "runas", "print", "edit", "explorer", "find"::ShellExecute(NULL,"open",lpszDir,NULL,lpszDir,SW_SHOWNORMAL);//释放资源::SysFreeString(bstrCurrentDirectory);delete[] lpszDir;VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));return S_OK;
}

以上使用了com工具,故需要引入相应头文件和依赖库文件。

//_com_util::ConvertBSTRToString()函数将要用到的头文件和库依赖文件
#include "comutil.h"
#pragma comment(lib, "comsupp.lib")

OpenInNotepad()

STDMETHODIMP CCommands::OpenInNotepad()
{AFX_MANAGE_STATE(AfxGetStaticModuleState())VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));CHAR path[MAX_PATH] = {NULL};::GetSystemDirectory(path,MAX_PATH);HINSTANCE hinst = NULL;// hinst = ::ShellExecute(NULL, NULL, "notepad.exe", NULL, path, SW_SHOWNORMAL);// hinst = ::ShellExecute(NULL,"open","C:\\Windows\\System32\\notepad.exe",NULL,NULL,SW_SHOWNORMAL);UINT ret = ::WinExec("notepad.exe", SW_SHOWNORMAL);if( SE_ERR_NOASSOC == (int)hinst){::MessageBox(NULL, "Call notepad.exe Exception!", "OpenInNotepad", MB_OK | MB_ICONWARNING);}VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));return S_OK;
}

OpenInCommand()

STDMETHODIMP CCommands::OpenInCommand()
{AFX_MANAGE_STATE(AfxGetStaticModuleState())VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));HINSTANCE hinst = NULL;// 执行外部命令的几个函数:WinExec(), ShellExecute(), system(), CreateProcess()// 打开IDE当前项目路径hinst = ::ShellExecute(NULL,"open","c:\\windows\\system32\\cmd.exe",NULL,NULL,SW_SHOWNORMAL);// 打开IDE当前项目路径// hinst = ::ShellExecute(NULL,"open","cmd.exe",NULL,NULL,SW_SHOWNORMAL);// 打开C:\Windows\System32目录// hinst = ::ShellExecute(NULL, NULL, "cmd.exe", NULL, "C:\\Windows\\System32\\", SW_SHOWNORMAL);//::WinExec("cmd.exe", SW_SHOWNORMAL);// system("c:\\windows\\system32\\cmd.exe");// system("notepad.exe");// 使用浏览器打开网页// hinst = ::ShellExecute(NULL,"open","http://localhost",NULL,NULL,SW_SHOWNORMAL);// 使用邮件工具编辑邮件// hinst = ::ShellExecute(NULL,"open","mailto:who@mail.example.com?subject=Hello&Body=this is a test",NULL,NULL,SW_SHOWNORMAL);if( SE_ERR_NOASSOC == (int)hinst){::MessageBox(NULL, "Call cmd.exe Exception!", "OpenInNotepad", MB_OK | MB_ICONWARNING);}VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));return S_OK;
}

7、编译链接完成后实现自动注册组件。VC6IDE中->菜单“工程”->设置->Post-Build步骤,新增命令,命令行如下

regsvr32.exe $(OutDir)\OpenInExplorer.dll /s

/s参数表示 无声,不显示注册成功与否的消息框。

7、编译、注册组件后,VC6IDE中->菜单“工具”->定制->附加项和宏文件,点击该界面的“浏览”按钮,选中本项目的OpenInExplorer.dll文件。选中插件“OpenInExplorer Developer Studio Add-in”。关闭后弹出工具栏对话框。具体也可参考CmdWnd: Issue IDE Command in a Command Window

然后IDE可增加带3个命令按钮的工具栏对话框。在任意打开的项目中点击自定义的工具栏按钮,发现已经实现目标。直接点击按钮1,可在打开的资源管理器中直接浏览本项目文件或对项目文件进行IDE之外的操作。

三、参考文档

Visual C++ Developer Studio Add-in Samples

Overview: Add-ins for the Visual C++ Developer Studio

How to: Create Add-in

微软实现步骤示例Creating Add-ins Using Visual C++

四、注意事项

如果在windows 7以上编译,请使用管理员权限打开vc6,否则因权限不足,会导致组件注册失败。

五、完整源代码下载:OpenInExplorer

VC6插件开发应用实例相关推荐

  1. 制作npm插件vue-toast-m实例练习

    制作npm插件vue-toast-m实例练习(消息弹窗) 一.使用npm插件 import VueToast from 'vue-toast-demo-cc'Vue.use(VueToast)this ...

  2. (笔记)VC6插件安装(VC6LineNumberAddin)

    VC6插件安装步骤如下: 1.下载VC6LineNumberAddin插件及注册文件.(以下是参考链接:) http://files.cnblogs.com/files/tdyizhen1314/VC ...

  3. 页面打印插件 jquery.jqprint.js 插件使用实例

    页面打印插件 jquery.jqprint.js 插件使用实例 jquery.jqprint.js 插件下载 jqprint 是一个基于jQuery编写的页面打印的一个小插件,可以对页面指定元素的内容 ...

  4. eclipse3.4+对的处理插件(附SVN插件安装实例)

    Eclipse 3.4以前安装插件无非有两种方式, 直接copy插件到features/plugins目录或者在links目录下创建链接文件. Eclipse 3.4又推出另一种新的安装途径, 更加灵 ...

  5. php 插件 代码架构,php反射机制详以及插件架构实例详解

    1.用途: 该扩展分析php程序,导出或提取出关于类.方法.属性.参数等的详细信息,包括注释. Reflection可以说是对php库函数:"Classes/Objects 类/对象函数&q ...

  6. vue 高德地图 定位插件 地图实例插件 获取点击的地方的经纬度和具体地址

    npm 安装 推荐 npm 安装. npm install vue-amap --saveimport VueAMap from 'vue-amap';Vue.use(VueAMap); VueAMa ...

  7. svga插件_SVGA实例讲解

    从发了一篇<使用SVGA优化礼物动画>之后, 很多小伙伴一直在问我相关实现的问题.以及碰到了一些问题怎么解决? 趁现在时间上比较富裕的时候写一篇关于SVGA的实例 使用SVGA实现上图效果 ...

  8. svga插件_SVGA实例讲解|UI|教程|xinjiebi - 原创文章 - 站酷 (ZCOOL)

    至从发了一篇<使用SVGA优化礼物动画>之后, 很多小伙伴一直在问我相关实现的问题.以及碰到了一些问题怎么解决? 趁现在时间上比较富裕的时候写一篇关于SVGA的实例 使用SVGA实现上图效 ...

  9. datetimepicker 插件使用实例及参数说明

    借鉴于 https://www.bootcss.com/p/bootstrap-datetimepicker/ 本文根据个人在项目使用过程中的经验进行一些总结,比较浅显,暂时不做深入分析. datet ...

最新文章

  1. 【Android View绘制之旅】Draw过程
  2. 解决计算机名修改或作业移植导致的服务器名问题.sql
  3. 2021-05-08 docker save与docker export的镜像区别
  4. fs.readfile 显示html,从fs.readFile获取数据
  5. 小米2怎样启动ANdroid?,小米2S如何打开后盖? 小米手机开盖技巧介绍(小米手机通用)...
  6. 每天学一点flash(67) 上传图片
  7. 7.卷1(套接字联网API)---套接字选项
  8. java socket 连接原理_Java socket通信基本原理介绍
  9. android安卓源码海量项目合集大全打包6000套-2续
  10. 139邮件服务器怎么设置,139手机邮箱的设置
  11. 电梯服务器系统,OTS电梯服务器TT使用说明.pdf
  12. CEVA-DSP构成
  13. 职称英语计算机考试取消,2020年职称英语考试取消了吗
  14. python文件重命名加日期_Python文件创建日期和Critiqu的重命名请求
  15. 感谢一路上有你们的陪伴
  16. 格式化数据#1:数据存储|Database
  17. jquery获取span标签下的第一个span子标签内容
  18. 【解决】Keil中创建工程时出现-arm_math.h(xxx): warning: #xxxx-D: unrecognized GCC pragma错误
  19. php数组合并多维,PHP合并多维数组
  20. 了不起的女性开发者:90后误选专业入对行,酷女孩霸榜开源NO.1

热门文章

  1. 线性反馈移位寄存器(LFSR)和 Berlekamp-Massey 算法
  2. java第三方包_java第三方包学习之lombok
  3. (74)项目中的亮点是什么?
  4. 鸿蒙系统魅族,魅族宣布接入鸿蒙系统
  5. QQ名称花体英文(可复制)
  6. 用华为模拟器ENSP编写一个电子信息学院数据中心网络及机房规划设计(路由毕业设计)(思科配置电子信息学院数据中心网络及机房规划设计也有)
  7. Project-iHome_review
  8. 【STL】C++ STL之array详解
  9. Go语言头秃之路(五)
  10. 博客添加人体时钟效果