写在前面
VS2015开始就已经不支持Addin插件了,替代的是VSPackage插件;也许是因为这个原因网上关于Addin的中文资料比较少。可是并不想学VSPackage开发,还是弄一个简单的吧。还是一点点的收集到了一些资料,真心觉得学习新知识不痛苦,痛苦的是没人请教,寻找资料的过程。
关于使用C#语言开发VS Addin插件还是有一些的;不过都是在“Tools”菜单下添加一个命令,而不是如下图所示的新增菜单。
上图为VS2010开发了一个Addin类型的插件,该插件添加了一个顶级菜单“testMyAddin”,该菜单下添加了2个命令。
请点击源代码
Addin插件的实现
那么下面将会从C++视角开发一个如上图所示的插件。毫无疑问Addin插件开发不需要下载VS SDK,而且我们应该创建外接程序;语言选择C++/ATL,听说C++/CLR不怎么用。
- 添加菜单
我们将菜单添加到“Tools”之后,所以需要先找到“Tools”的位置。
//在菜单项里查找“工具”菜单
IfFailGoCheck(pMenuBarControls->get_Item(CComVariant(L"Tools"), &pToolsCommandBarControl), pToolsCommandBarControl);
pToolsPopup = pToolsCommandBarControl;
//并通过Tools的面板指针,找到其在菜单栏上的位置
int nToolPos = 0;
pToolsPopup->get_Index(&nToolPos);
//创建的顶级菜单
nToolPos++;
//创建顶级菜单POPUP将TestAddin顶级菜单加入到菜单栏的nToolPos++的位置
pMenuBarControls->Add(CComVariant(msoControlPopup),CComVariant(1),CComVariant( static_cast<LPCWSTR>(nullptr)),CComVariant(nToolPos),
CComVariant(true),&pTestCommandBarControl);
pTestPopup = pTestCommandBarControl;
pTestPopup->get_CommandBar(&pTestCommandBar);//取得第一个bar
pTestPopup->put_Caption(CComBSTR("testMyAddin"));
pTestCommandBar->get_Controls(&pTestBarControls);
- 添加命令
//得到所有VS所有命令对象
IfFailGoCheck(m_pDTE->get_Commands(&pCommands), pCommands);
pCommands2 = pCommands;
//创建新命令1
pCommands2->AddNamedCommand2(m_pAddInInstance,CComBSTR("CMD_ONE")
, CComBSTR("Update MyAddin"), CComBSTR("Executes the command")
, VARIANT_TRUE, CComVariant(59), NULL
, vsCommandStatusSupported+vsCommandStatusEnabled
, vsCommandStylePictAndText, vsCommandControlTypeButton
, &pCreatedCommand);
//将新命令1加到命令对象中
pDisp = NULL;
HRESULT nRet = pCreatedCommand->AddControl(pTestCommandBar,nCount+1, &pDisp);
pCreatedCommand =NULL;
//创建新命令2
pCommands2->AddNamedCommand2(m_pAddInInstance,CComBSTR("CMD_TWO")
, CComBSTR("For Test MyAddin"), CComBSTR("Executes the command")
, VARIANT_TRUE, CComVariant(59), NULL
, vsCommandStatusSupported+vsCommandStatusEnabled
, vsCommandStylePictAndText, vsCommandControlTypeButton
, &pCreatedCommand);
//将新命令2加到命令对象中
pTestBarControls->get_Count(&nCount);
pDisp = NULL;
HRESULT nRet = pCreatedCommand->AddControl(pTestCommandBar,nCount+1, &pDisp);
启动时加载
根据ext_ConnectMode ConnectMode
确定是否是启动还是安装
if(ConnectMode == ext_cm_Startup) //5 == ext_cm_UISetup
{
由于上一次已经将命令写入注册表中,但每一次运行都是重新创建菜单,重新添加命令,如果没有反注册,重新添加命令会失败。
//"MyAddin1.Connect.CMD_ONE"为命令的完整标识。
UnregisterCommand(pCommands,CComVariant(L"MyAddin1.Connect.CMD_ONE"));
UnregisterCommand(pCommands,CComVariant(L"MyAddin1.Connect.CMD_TWO"));
命令的响应
CConnect::Exec
方法是鼠标点击后的响应函数,在该函数创建一个对话框,并显示
,(对话框是ATL对话框)。
if(ExecuteOption == vsCommandExecOptionDoDefault)
{
if(!_wcsicmp(bstrCmdName, L"MyAddin1.Connect.CMD_ONE"))
{
*pvbHandled = VARIANT_TRUE;
CtestUi testDlg;
INT_PTR nResponse = testDlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
return S_OK;
}
最后请查看源代码