• 自己动手编写一个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)









  • 相关阅读:
    codeforces1068——D.Array Without Local Maximums(计数DP+前缀和优化)
    codeforces1253——D. Harmonious Graph(并查集)
    LDUOJ——I. 买汽水(折半搜索+双指针)
    洛谷P3360 ——偷天换日(dfs读入+树形DP+01背包)
    洛谷P1270 ——“访问”美术馆(dfs读入+树形DP)
    LDUOJ——最小生成树(欧拉函数+思维)
    [LeetCode] 1551. Minimum Operations to Make Array Equal
    [LeetCode] 1553. Minimum Number of Days to Eat N Oranges
    [LeetCode] 161. One Edit Distance
    [LeetCode] 1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470590.html
Copyright © 2020-2023  润新知