亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

SSMS2008插件開發(fā)(4)--自定義菜單

系統(tǒng) 1870 0
原文: SSMS2008插件開發(fā)(4)--自定義菜單

  打開上次的項(xiàng)目MySSMSAddin中的Connect類,發(fā)現(xiàn)該類繼于了兩個(gè)接口: IDTExtensibility2 IDTCommandTarget ,關(guān)于這兩個(gè)接口的詳細(xì)說明,請(qǐng)點(diǎn)擊這兩個(gè)接口轉(zhuǎn)到MSDN。

  IDTExtensibility2接口有2個(gè)重要的方法:OnConnection和OnDisconnection。OnConnection表示當(dāng)(宿主)SSMS加載外接程序的時(shí)候調(diào)用此接口,可以在此方法中做些初始化的工作,如加載菜單等;OnDisconnection方法表示當(dāng)SSMS卸載外接程序的時(shí)候調(diào)用此方法,可以在此方法中做些清理工作。

  OnConnection方法的代碼如下:

    		/// <summary>

            /// 實(shí)現(xiàn) IDTExtensibility2 接口的 OnConnection 方法。接收正在加載外接程序的通知。

            /// </summary>

		/// <param term='application'>宿主應(yīng)用程序的根對(duì)象。</param>

		/// <param term='connectMode'>描述外接程序的加載方式。</param>

		/// <param term='addInInst'>表示此外接程序的對(duì)象。</param>

		/// <seealso class='IDTExtensibility2' />

		public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)

		{

            _applicationObject = (DTE2)ServiceCache.ExtensibilityModel;

			_addInInstance = (AddIn)addInInst;

            if (connectMode == ext_ConnectMode.ext_cm_Startup)

			{

				object []contextGUIDS = new object[] { };

				Commands2 commands = (Commands2)_applicationObject.Commands;

				string toolsMenuName;

                

				try

				{

					string resourceName;

					ResourceManager resourceManager = new ResourceManager("MySSMSAddin.CommandBar", Assembly.GetExecutingAssembly());

					CultureInfo cultureInfo = new CultureInfo(_applicationObject.LocaleID);

					

					if(cultureInfo.TwoLetterISOLanguageName == "zh")

					{

						System.Globalization.CultureInfo parentCultureInfo = cultureInfo.Parent;

						resourceName = String.Concat(parentCultureInfo.Name, "Tools");

					}

					else

					{

						resourceName = String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools");

					}



					toolsMenuName = resourceManager.GetString(resourceName);

				}

				catch

				{

					toolsMenuName = "Tools";

				}



				Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];



				CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];

				CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;



				try

				{

					Command command = commands.AddNamedCommand2(_addInInstance, "MySSMSAddin", "Test Menu", "Executes the command for MySSMSAddin", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);



					if((command != null) && (toolsPopup != null))

					{

						command.AddControl(toolsPopup.CommandBar, 1);

					}

				}

				catch(System.ArgumentException)

				{

					//如果出現(xiàn)此異常,原因很可能是由于具有該名稱的命令

					//  已存在。如果確實(shí)如此,則無需重新創(chuàng)建此命令,并且

                    //  可以放心忽略此異常。

				}

			}

		}
  
  該方法有4個(gè)參數(shù):application表示宿主對(duì)象,這里指SSMS本身(在VS2008中表示DTE);connectMode表示外接程序的加載方式,在SSMS中此值總是ext_cm_Startup;addInInst表示插件本身,這里指我們的MySSMSAddin.Connect;custom 不知道什么作用(MSDN中的解釋是 一個(gè)空數(shù)組,可用來傳遞在外接程序中使用的特定于主機(jī)的數(shù)據(jù))。

  DTE對(duì)象是操作SSMS的核心對(duì)象,包括菜單、工具欄、文檔、工具箱、錯(cuò)誤列表等都通過該對(duì)象獲取。所以,在OnConnect方法的一開始,就取得DTE對(duì)象,代碼如下:

    _applicationObject = (DTE2)ServiceCache.ExtensibilityModel;

_addInInstance = (AddIn)addInInst;
  
  上面代碼的第2句獲取插件的實(shí)例。

  _applicationObject.Commands(DTE.Commands)表示SSMS中所有的命令項(xiàng);而_applicationObject.CommandBars(DTE.CommandBars)包含所有的菜單項(xiàng),例如文件菜單、工具菜單以及快捷菜單。要想在“工具”菜單中增加一個(gè)命令,必須先找到“工具”菜單,由于不同語(yǔ)言版本菜單的名稱不一樣,所以首先通過資源文件(CommandBar.resx)找到工具菜單的名稱,然后通過名稱在主菜單(MenuBar)中找到“工具”菜單,再在“工具”菜單中增加菜單項(xiàng)。

    //獲取所有的菜單命令

Commands2 commands = (Commands2)_applicationObject.Commands;
  

  在資源文件中查找“工具”菜單的名稱:

    try

{

    string resourceName;

    ResourceManager resourceManager = new ResourceManager("MySSMSAddin.CommandBar", Assembly.GetExecutingAssembly());

    CultureInfo cultureInfo = new CultureInfo(_applicationObject.LocaleID);



    if (cultureInfo.TwoLetterISOLanguageName == "zh")

    {

        System.Globalization.CultureInfo parentCultureInfo = cultureInfo.Parent;

        resourceName = String.Concat(parentCultureInfo.Name, "Tools");

    }

    else

    {

        resourceName = String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools");

    }



    toolsMenuName = resourceManager.GetString(resourceName);

}

catch

{

    toolsMenuName = "Tools";

}
  

  獲取主菜單,并在主菜單中獲取“工具”菜單的引用:

    Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];

CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];

CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
  

  通過 Commands.AddNamedCommand2 增加一個(gè)菜單命令:

    Command command = commands.AddNamedCommand2(_addInInstance

    , "MySSMSAddin"

    , "Test Menu"

    , "Executes the command for MySSMSAddin"

    , true

    , 59

    , 

    ref contextGUIDS

    , (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled

    , (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton

    );
  
  第1個(gè)參數(shù)為要添加菜單命令的插件;
  第2個(gè)參數(shù)為菜單命令的名稱, 該方法會(huì)自動(dòng)在給定的名稱前加上Progid前綴,在這里這個(gè)前綴為命名空間.類名(MySSMSAddin.Connect)
  第3個(gè)參數(shù)為菜單顯示的文本;
  第4個(gè)參數(shù)為菜單的提示信息;
  第5個(gè)參數(shù)為true表示使用Office圖標(biāo),false表示使用其他來源的圖標(biāo);怎么使用自定義圖標(biāo),以后再說。
  第6個(gè)參數(shù)圖標(biāo)ID;
  第7個(gè)參數(shù)確定哪些環(huán)境上下文(即調(diào)試模式、設(shè)計(jì)模式等)啟用此命令;
  第8個(gè)參數(shù)指示當(dāng)指定上下文不存在時(shí),此命令是不可見還是禁用狀態(tài)等信息;
  第9個(gè)參數(shù)確定菜單的顯示風(fēng)格,例如是光文字還是光圖標(biāo),或者兩者都顯示。

  將新增的菜單加入到“工具”菜單中,作為“工具”菜單的子菜單:

    command.AddControl(toolsPopup.CommandBar, 1);
  

  以上步驟僅僅在“工具”菜單中增加了一個(gè)菜單命令,但是單擊該命令并沒有任何響應(yīng),要響應(yīng)自定義菜單,還需要實(shí)現(xiàn)IDTCommandTarget接口的兩個(gè)方法:QueryStatus和Exec。QueryStatus方法 返回指定命名命令的當(dāng)前狀態(tài)(啟用、禁用、隱藏等) ;Exec方法用于 執(zhí)行指定的命名命令

  返回命令狀態(tài):

    /// <summary>

/// 實(shí)現(xiàn) IDTCommandTarget 接口的 QueryStatus 方法。此方法在更新該命令的可用性時(shí)調(diào)用

/// </summary>

/// <param term='commandName'>要確定其狀態(tài)的命令的名稱。</param>

/// <param term='neededText'>該命令所需的文本。</param>

/// <param term='status'>該命令在用戶界面中的狀態(tài)。</param>

/// <param term='commandText'>neededText 參數(shù)所要求的文本。</param>

/// <seealso class='Exec' />

public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)

{

    if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)

    {

        if (commandName == "MySSMSAddin.Connect.MySSMSAddin")

        {

            status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;

            return;

        }

    }

}
  
  注意上述代碼中的命令名稱 MySSMSAddin.Connect.MySSMSAddin ,我們?cè)谥付蠲Q的時(shí)候,只指定為MySSMSAddin,怎么這里的內(nèi)容變多了呢?因?yàn)榍懊嬲f過,使用Commands.AddNamedCommand2方法時(shí),會(huì)在名稱前面自動(dòng)加上Progid。

  響應(yīng)菜單事件:

    /// <summary>

/// 實(shí)現(xiàn) IDTCommandTarget 接口的 Exec 方法。此方法在調(diào)用該命令時(shí)調(diào)用。

/// </summary>

/// <param term='commandName'>要執(zhí)行的命令的名稱。</param>

/// <param term='executeOption'>描述該命令應(yīng)如何運(yùn)行。</param>

/// <param term='varIn'>從調(diào)用方傳遞到命令處理程序的參數(shù)。</param>

/// <param term='varOut'>從命令處理程序傳遞到調(diào)用方的參數(shù)。</param>

/// <param term='handled'>通知調(diào)用方此命令是否已被處理。</param>

/// <seealso class='Exec' />

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)

{

    handled = false;

    if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)

    {

        if (commandName == "MySSMSAddin.Connect.MySSMSAddin")

        {

            System.Windows.Forms.MessageBox.Show("Hello World");

            handled = true;

            return;

        }

    }

}
  

  以上添加菜單的方法比較復(fù)雜,而且是COM時(shí)代的用法,下面的方法也許更適合C#, 可以參考這里
    /// <summary>

/// 實(shí)現(xiàn) IDTExtensibility2 接口的 OnConnection 方法。接收正在加載外接程序的通知。

/// </summary>

/// <param term='application'>宿主應(yīng)用程序的根對(duì)象。</param>

/// <param term='connectMode'>描述外接程序的加載方式。</param>

/// <param term='addInInst'>表示此外接程序的對(duì)象。</param>

/// <seealso class='IDTExtensibility2' />

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)

{

    _applicationObject = (DTE2)ServiceCache.ExtensibilityModel;

    _addInInstance = (AddIn)addInInst;

    if (connectMode == ext_ConnectMode.ext_cm_Startup)

    {

        object[] contextGUIDS = new object[] { };

        Commands2 commands = (Commands2)_applicationObject.Commands;

        string toolsMenuName;



        try

        {

            string resourceName;

            ResourceManager resourceManager = new ResourceManager("MySSMSAddin.CommandBar", Assembly.GetExecutingAssembly());

            CultureInfo cultureInfo = new CultureInfo(_applicationObject.LocaleID);



            if (cultureInfo.TwoLetterISOLanguageName == "zh")

            {

                System.Globalization.CultureInfo parentCultureInfo = cultureInfo.Parent;

                resourceName = String.Concat(parentCultureInfo.Name, "Tools");

            }

            else

            {

                resourceName = String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools");

            }



            toolsMenuName = resourceManager.GetString(resourceName);

        }

        catch

        {

            toolsMenuName = "Tools";

        }



        Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];

        CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];

        CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;



        try

        {

            //例如 CommandBarPopup 來添加菜單

            CommandBarControl command = toolsPopup.Controls.Add(MsoControlType.msoControlButton, 1, "", 1, true);

            command.Tag = "測(cè)試";

            command.Caption = "另一種菜單";     //菜單標(biāo)題

            command.TooltipText = "測(cè)試另一種添加菜單的方法";  //提示



            //獲取 command 的事件,注意:commandHandler不能在方法中定義,如果這樣就不能響應(yīng)事件

            //  必須要定義為類級(jí)變量,不知道為什么必須這樣。而且VSTO編程中也是這樣。

            commandHandler = (CommandBarEvents)_applicationObject.DTE.Events.get_CommandBarEvents(command);

            commandHandler.Click += new _dispCommandBarControlEvents_ClickEventHandler(commandHandler_Click);

        }

        catch (System.ArgumentException)

        {

        }

    }

}



//添加菜單的事件對(duì)象

CommandBarEvents commandHandler;



/// <summary>

/// 菜單響應(yīng)事件

/// </summary>

/// <param name="CommandBarControl"></param>

/// <param name="Handled"></param>

/// <param name="CancelDefault"></param>

void commandHandler_Click(object CommandBarControl, ref bool Handled, ref bool CancelDefault)

{

    MessageBox.Show("hello");

}
  

還有另外一種綁定菜單事件的方法,核心代碼如下
    public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)

{

    _applicationObject = (DTE2)ServiceCache.ExtensibilityModel;

    _addInInstance = (AddIn)addInInst;

    if (connectMode == ext_ConnectMode.ext_cm_Startup)

    {

        ...



        try

        {

            ...

        }

        catch

        {

            toolsMenuName = "Tools";

        }



        ...



        try

        {

            //利用 CommandBarPopup 來添加菜單,

            //  相對(duì)于類型為 MsoControlType.msoControlButton 的菜單,其類型為CommandBarButton

            //  利用 CommandBarButton 的Click事件,來響應(yīng)命令

            command = toolsPopup.Controls.Add(MsoControlType.msoControlButton, 1, "", 1, true) as CommandBarButton;

            command.Tag = "測(cè)試";

            command.Caption = "另一種菜單";     //菜單標(biāo)題

            command.TooltipText = "測(cè)試另一種添加菜單的方法";  //提示

            command.Click += new _CommandBarButtonEvents_ClickEventHandler(command_Click);

        }

        catch (System.ArgumentException)

        {

        }

    }

}

//必須定義為類級(jí)變量

CommandBarButton command;

//響應(yīng)命令

void command_Click(CommandBarButton Ctrl, ref bool CancelDefault)

{

    MessageBox.Show("Hello");

}
  
  后兩種增加菜單的方法都有一個(gè)共同缺點(diǎn),一個(gè)是菜單本身要定義為類級(jí),另一個(gè)是響應(yīng)事件對(duì)象要定義為類級(jí),而且都不知道怎么查詢命令的可用狀態(tài)。
  下一次介紹SSMS及DTE對(duì)象模型。


SSMS2008插件開發(fā)(4)--自定義菜單


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 99热热久久这里只有精品166 | 久久欧美久久欧美精品 | 99中文字幕在线 | 男人的天堂在线免费视频 | 九九久久免费视频 | 夜夜骑加勒比 | 国产伦理久久精品久久久久 | 国产精品香蕉一区二区三区 | 国产精品91在线 | 色偷偷亚洲女性天堂 | 香蕉视频成人 | 97视频在线视频 | 亚洲精品自产拍在线观看 | 99视频免费在线观看 | 日韩一区二区在线免费观看 | 日本精品视频在线 | 97精品视频共享总站 | 国产91在线精品 | 免费女人18毛片a级毛片视频 | 久久2017| 神马影院在线观看我不卡 | 欧美亚洲国产视频 | 性欧美一级毛片欧美片 | 日韩精品欧美亚洲高清有无 | 精品成人久久 | 在线播放ww | 亚洲香蕉在线视频 | 久草视频免费播放 | 欧美三级在线观看不卡视频 | 日本高清视频www夜色资源网 | 九九精品视频一区二区三区 | 国产午夜亚洲精品第一区 | 91网站国产 | 6080欧美一区二区三区四区 | 国产一区中文字幕 | 日韩成人精品在线 | 天天草天天射 | 91精品啪在线观看国产色 | 国产未成女年一区二区 | 一级片播放| 久久加勒比|