VC6插件开发应用实例
来源:互联网 发布:淘宝生活服务类目 编辑:程序博客网 时间:2024/05/29 08:36
一、背景
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插件开发应用实例
- jQuery插件应用实例
- jquery插件开发实例
- jQuery插件开发实例
- Openfire插件开发实例
- VC6插件
- jquery插件tooltip应用实例[实例]
- Portlet应用开发实例
- openfire插件开发简单实例
- openfire插件开发简单实例
- Discuz! 插件开发实例讲解
- C# 插件开发学习实例
- Discuz! 插件开发实例讲解
- 织梦dedecms插件开发实例
- MS IDE RAD技术入门----VC6插件开发介绍
- vc6单片机开发插件 HU51 版本:1.0.1
- Android应用插件化开发
- Android应用插件式开发
- 【C++的探索路9】<<、>>、++、--与 强制类型转换运算符
- 对Java Serializable(序列化)的理解和总结
- mac 安装虚拟机win系统
- QPainter学习(一)——绘制函数记录
- Vue基础(模板语法)
- VC6插件开发应用实例
- Windows Service服务 附加到进程调试
- 时间序列(四)ARIMA模型与差分
- c语言指针详解
- MongoDB GUI( Robo 3T) Shell使用及操作
- openvirtualpn
- map容器的黑科技
- 图论的第一步
- JZOJ3501. 【NOIP2013模拟联考15】消息传递