自己动手编写一个VS插件(二)——理解OnConnection函数

作者:朱金灿

来源:http://blog.csdn.net/clever101

 

 

         继续开发一个VS插件。首先认识一下通过插件向导生成的类和函数,大致弄清一下它们的含义。创建一个基于ATL的插件工程,都生成了一个CConnect类。现在我们看看CConnect类的一些重要接口:

 

CConnect::OnConnection:这个接口可以说是插件的入口函数。只是这个入口函数会被调用几次,至于何时调用取决于这个函数的ConnectMode参数。

    

     一个插件有下面几种加载模式:

  • 在VS启动时,并且该插件并标记为随同VS启动时启动(所谓随同VS启动时启动请见图一),这时ConnectMode参数的值为ext_ConnectMode.ext_cm_Startup。

                  

                                                              

            • 图一

  • 在用户需要时时被调用,就是说该插件并没有被标记为VS启动时启动但用户手动在外接程序管理器上给启动一栏打上勾上时,这时ConnectMode参数的值为ext_ConnectMode.ext_cm_AfterStartup。
  • 从命令行启动(使用devenv.exe去生成一个解决方案),这时ConnectMode参数的值为ext_ConnectMode.ext_cm_CommandLine。请注意这种情况在一些旧版本的Visual Studio会有一些bug并且看来只有在Visual Studio 2008才会正确运行(比VS 2008高的版本应该也可以)。
  • 当插件使用常驻的工具栏、命令栏和按钮(常驻意味着即使插件没有加载用户界面也会出现)同时Visual Studio要求插件去初始化常驻用户界面,这时ConnectMode参数的值为ext_ConnectMode.ext_cm_UISetup。这种连接模式必须不同于ext_ConnectMode.ext_cm_Startup和ext_ConnectMode.ext_cm_AfterStartup的情况下。
  • 假如你建的插件不是一个一般插件,而是一个和特定的解决方案相关的插件,当这个解决方案被加载时,这时ConnectMode参数的值为ext_ConnectMode.ext_cm_AfterStartup。

        所以,存在两种模式:ext_ConnectMode.ext_cm_Startup和ext_ConnectMode.ext_cm_AfterStartup。这意味着它们都以相同的方式处理因为在一般情况下插件在VS启动时自动加载还是过了一些时候手动加载它们并没有什么不同。所以你可以使用下面的代码:

STDMETHODIMP CConnect::OnConnection(IDispatch *pApplication, ext_ConnectMode ConnectMode, IDispatch *pAddInInst, SAFEARRAY ** /*自定义*/ )
{
	HRESULT hr = S_OK;
	pApplication->QueryInterface(__uuidof(DTE2), (LPVOID*)&m_pDTE);
	pAddInInst->QueryInterface(__uuidof(AddIn), (LPVOID*)&m_pAddInInstance);
	
	switch(ConnectMode)
	{
	case ext_cm_Startup:
	case ext_cm_AfterStartup:
		{
			// 初始化你的插件

			break;
		}
	default:
		break;
	}
	return hr;
}

        然而当插件在ext_ConnectMode.ext_cm_Startup模式加载(也就是在Visual Studio启动时加载),VisualStudio并没有完全初始化。所以这是很多插件可以正确初始化,但一些却会失败。比如当你的插件加载时需要显示一个工具窗口,当插件在VS启动时加载工具窗口却并不会显示,但在外接程序管理器手动加载这个插件时可以显示这个工具窗口。


       所以在VisualStudioz完全初始化之后再调用OnConnection函数会比较好。IDTExtensibility2接口提供了一个在VisualStudioz完全初始化后会被调用的叫OnStartupComplete的方法。所以正确的代码如下:

STDMETHODIMP CConnect::OnStartupComplete (SAFEARRAY ** /*自定义*/ )
{
	// 初始化你的插件

	return S_OK;
}

// CConnect
STDMETHODIMP CConnect::OnConnection(IDispatch *pApplication, ext_ConnectMode ConnectMode, IDispatch *pAddInInst, SAFEARRAY ** /*自定义*/ )
{
	HRESULT hr = S_OK;
	pApplication->QueryInterface(__uuidof(DTE2), (LPVOID*)&m_pDTE);
	pAddInInst->QueryInterface(__uuidof(AddIn), (LPVOID*)&m_pAddInInstance);
	
	switch(ConnectMode)
	{
	case ext_cm_Startup:
		// 什么也不做,因为Visual Studio并没有完全初始化
		break;
	case ext_cm_AfterStartup:
		{
            OnStartupComplete(NULL);
			break;
		}
	default:
		break;
	}
	return hr;
}


参考文献:

  1. HOWTO: Use correctly the OnConnection method of a Visual Studio add-in,Author:Carlos J. Quintero (Microsoft MVP)









转载于:https://www.cnblogs.com/lanzhi/archive/2013/04/05/6470590.html

你可能感兴趣的:(自己动手编写一个VS插件(二)——理解OnConnection函数)