共用方式為


How to: 建立和處理命令,在 VSPackages (C#)

將命令加入至 VSPackage 是兩個步驟的程序。 首先,指令被定義為.vsct 檔案中的 XML 項目。 然後它會實作在程式碼中。 .Vsct 檔案中所輸入的資訊會決定指令的外觀、 整合式的開發環境 (IDE),並的行為中的位置。 命令然後定義程式碼中,通常為MenuCommandOleMenuCommand物件和它的事件處理常式實作。

可見且已啟用使用者之前,必須是 VSPackage,使得 ide,您可以使用的指令可以使用它們。 當使用 Visual Studio 的套件] 專案範本,命令會建立.vsct 檔案中時,它們是可見且已啟用,預設情況下。 例如,設定某些命令旗標, DynamicItemStart,可以變更預設行為。 可視性、 啟用的狀態及其他屬性的命令也可以變更在程式碼在執行階段藉由存取OleMenuCommand與指令相關聯的物件。

建立命令

.Vsct 檔案中定義所有的命令、 命令群組、 功能表、 工具列和工具視窗。 如果您的 VSPackage,並沒有.vsct 檔案,您必須新增一個。 如需詳細資訊,請參閱 Visual Studio 命令表裡 (。Vsct) 檔案

如果您正在使用封裝範本建立的 VSPackage,選取 [ 功能表命令來建立.vsct 檔案,並定義預設的功能表命令。 如需詳細資訊,請參閱 逐步解說: 使用 Visual Studio 的封裝範本建立功能表命令

若要在 IDE 中加入命令

  1. 開啟.vsct 檔案。

  2. 在Symbols區段中,找出 GuidSymbol 所在的群組和命令的項目。

  3. 建立 IDSymbol ,如下列範例所示,您想要新增每個功能表、 群組或命令的項目。

    <GuidSymbol name="guidButtonGroupCmdSet" value="{f69209e9-975a-4543-821d-1f4a2c52d737}">
      <IDSymbol name="MyMenuGroup" value="0x1020" />
      <IDSymbol name="cmdidMyCommand" value="0x0100" />
    </GuidSymbol>
    

    name屬性的GuidSymbol和IDSymbol元素提供 GUID:ID 對每個新的功能表、 群組或命令。 guid代表一組係專為您 VSPackage 的命令。 您可以定義多個命令集。 每個 GUID:ID 配對必須是唯一的。

  4. 按鈕 區段中,建立 按鈕來定義] 命令,如下列範例所示的項目。

    <Button guid="guidButtonGroupCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
      <Parent guid="guidButtonGroupCmdSet" id="MyMenuGroup" />
      <Icon guid="guidImages" id="bmpPic1" />
      <Strings>
        <CommandName>cmdidMyCommand</CommandName>
        <ButtonText>My Command name</ButtonText>
      </Strings>
    </Button>
    
    1. 設定guid和id欄位,以符合新命令的 GUID:ID。

    2. 設定 priority 屬性。

      priority .vsct 會使用屬性來判斷按鈕在其父群組中其他物件之間的位置。

      具有較低的優先順序值的命令會顯示上方或左邊,有較高的優先權值的命令。 允許重複的優先順序值,但具有相同優先順序的指令的相對位置由 VSPackages 處理執行階段的順序,該順序無法預先決定。

      省略priority屬性設定其值為 0。

    3. 設定 type 屬性。 在大部分的情況下,它的值會是 "Button"。 如需其他有效的按鈕類型的說明,請參閱Button 項目

  5. 在按鈕定義中,建立字串 項目,包含 項目來包含功能表的名稱,在 IDE 中,所顯示的樣子和 CommandName 項目來包含用來存取功能表命令名稱命令視窗。

    如果按鈕的文字字串包含 '&' 字元,使用者可以開啟功能表,按下 alt 鍵加上字元也會緊隨 「 & 」。

    新增Tooltip項目將會造成所包含的文字,使用者將滑鼠指標停留在按鈕上時,會出現。

  6. 新增圖示項目以指定圖示,如果有的話,要顯示的命令。 圖示是必要的輸入] 工具列上的按鈕,而不是用於功能表項目。 guid和id的Icon項目必須符合點陣圖中所定義的項目Bitmaps一節。

  7. 請將命令旗標,視需要來變更按鈕的行為和外觀。 若要這樣做,請將 CommandFlag 在功能表定義中的項目。

  8. 設定父群組的命令。 父群組可以是您所建立之群組、 一組與另一個套件,或是來自於 IDE 的群組。 例如,若要將命令加入至 Visual Studio 編輯工具列,旁邊註解移除註解按鈕設定為 guidStdEditor:IDG_VS_EDITTOOLBAR_COMMENT 的父代。 如果父代是使用者定義的群組時,它必須是功能表、 工具列或工具視窗都會出現在 IDE 中的子系。

    您可以執行下列其中一種方式,取決於您的設計:

    • 在Button項目,建立項目並設定其guid和id欄位的 Guid 及識別碼的群組,將用來架設命令,也就是主要父群組。

      下列範例會定義使用者定義的功能表上會出現的命令。

      <Button guid="guidTopLevelMenuCmdSet" id="cmdidTestCommand" priority="0x0100" type="Button">
        <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" />
        <Icon guid="guidImages" id="bmpPic1" />
        <Strings>
          <CommandName>cmdidTestCommand</CommandName>
          <ButtonText>Test Command</ButtonText>
        </Strings>
      </Button>
      
    • 您可以省略Parent如果命令是藉由使用命令位置置放的項目。 建立 CommandPlacements 之前的項目Symbols區段,然後新增 CommandPlacement 項目具有guid和id的命令, priority,又是個父親,如下列範例所示。

      <CommandPlacements>
        <CommandPlacement guid="guidButtonGroupCmdSet" id="cmdidMyCommand" priority="0x105">
          <Parent guid="guidButtonGroupCmdSet" id="MyMenuGroup" />
        </CommandPlacement>
      </CommandPlacements>
      

      建立多個有相同的 GUID:ID 而有不同的父項的指令定位時,會造成功能表會出現在多個位置。 如需詳細資訊,請參閱 CommandPlacements 項目。

    如需有關命令群組和父的詳細資訊,請參閱How to: 建立可重複使用的按鈕群組

接下來命令,便會顯示在 IDE 中,但會有任何功能。 如果命令由封裝範本建立的預設情況下會有 click 處理常式會顯示一則訊息。

處理新的命令

大部分的命令,在 managed 程式碼可以加上使用的指令處理管理套件架構 (MPF) 的MenuCommand物件或OleMenuCommand物件,並實作其事件處理常式。

使用程式碼的IOleCommandTarget介面直接對命令處理,您就必須實作IOleCommandTarget介面和方法。 兩種最重要的方法是QueryStatusExec

若要使用 MPF 來處理新的命令

  1. 取得OleMenuCommandService執行個體,如下列範例所示。

    OleMenuCommandService mcs = 
        GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
    
  2. 建立CommandID物件做為其參數的 GUID 及識別碼的命令來處理,如下列範例所示。

    CommandID menuCommandID = 
        new CommandID(GuidList.guidButtonGroupCmdSet, 
            (int)PkgCmdIDList.cmdidMyCommand);
    

    Visual Studio 的封裝範本提供兩個集合, GuidList和PkgCmdIDList,而保留的 Guid 及識別碼的命令。 這些命令所加入範本中,會自動填入,但您以手動方式加入的命令,您也必須將 ID 項目,以PkgCmdIdList類別。

    或者,您可以在其中填入CommandID使用 GUID 的未經處理的字串值和 ID 的整數值的物件

  3. 具現化其中一個MenuCommandOleMenuCommand物件,指定處理加上命令的方法CommandID,如下列範例所示。

    MenuCommand menuItem = 
        new MenuCommand(MenuItemCallback, menuCommandID);
    

    MenuCommand適用於靜態的指令。 動態功能表項目顯示需要 QueryStatus 事件處理常式。 OleMenuCommand新增BeforeQueryStatus事件,就會發生當主應用程式功能表命令的已開啟,及其他屬性,例如Text

    封裝範本所建立的指令會傳遞預設情況下, OleMenuCommand物件在Initialize()套件類別的方法。

  4. MenuCommand適用於靜態的指令。 動態功能表項目顯示需要 QueryStatus 事件處理常式。 OleMenuCommand新增BeforeQueryStatus事件,就會發生當主應用程式功能表命令的已開啟,及其他屬性,例如Text

    封裝範本所建立的指令會傳遞預設情況下, OleMenuCommand物件在Initialize()套件類別的方法。 Visual Studio 精靈可實作Initialize方法,藉由使用MenuCommand。 動態功能表項目會顯示,您必須變更此選項可OleMenuCommand、 下一個步驟所示。 此外,若要變更的功能表項目文字,您必須將文字變更命令旗標加入功能表命令按鈕,在.vsct 檔案中,如下列範例所示

    <Button guid="guidMenuTextCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
      <Parent guid="guidMenuTextCmdSet" id="MyMenuGroup" />
      <Icon guid="guidImages" id="bmpPic1" />
      <CommandFlag>TextChanges</CommandFlag>
      <Strings>
        <CommandName>cmdidMyCommand</CommandName>
        <ButtonText>My Command name</ButtonText>
      </Strings>
    </Button>
    
  5. 傳遞至新的功能表命令AddCommand中的方法IMenuCommandService介面。 這可以藉由 [套件] 範本所建立的指令的預設值如以下範例所示

    mcs.AddCommand( menuItem );
    
  6. 實作處理命令的方法。

若要實作使用 MPF 類別的 QueryStatus

  1. 顯示命令之前,就會發生 QueryStatus 事件。 這可讓設定在事件處理常式之前到達使用者該命令的屬性。 新增為的命令OleMenuCommand物件可以存取這個方法。

    新增EventHandler物件到BeforeQueryStatus事件OleMenuCommand建立來處理命令,如下列範例所示的物件 (menuItem是OleMenuCommand執行個體)。

    Dim menuCommandID As CommandID = New CommandID(GuidList.guidMenuTextCmdSet, CInt(PkgCmdIDList.cmdidMyTextCommand))
    Dim menuItem As OleMenuCommand = New OleMenuCommand(New EventHandler(AddressOf MenuItemCallback), menuCommandID)
    AddHandler menuItem.BeforeQueryStatus, AddressOf OnBeforeQueryStatus
    mcs.AddCommand(menuItem)
    
    // Create the command for the menu item.
    CommandID menuCommandID = new CommandID(GuidList.guidMenuTextCmdSet, (int)PkgCmdIDList.cmdidMyCommand);
    OleMenuCommand menuItem = new OleMenuCommand(MenuItemCallback, menuCommandID );
    menuItem.BeforeQueryStatus +=
        new EventHandler(OnBeforeQueryStatus);
    mcs.AddCommand(menuItem);
    

    EventHandler物件都可以在查詢的功能表指令的狀態時,會呼叫方法的名稱。

  2. 實作查詢狀態處理常式方法的指令。 objectsender參數就可以轉換成OleMenuCommand物件,它用來設定不同的功能表指令,包括文字屬性。  下表顯示的屬性,在MenuCommand類別 (其中 MPF 類別OleMenuCommand是衍生自),相對於OLECMDF旗標。

    MenuCommand 屬性

    OLECMDF 旗標

    Checked = true

    OLECMDF_LATCHED

    Visible = false

    OLECMDF_INVISIBLE

    Enabled = true

    OLECMDF_ENABLED

    若要變更的功能表命令的文字,請使用Text屬性在OleMenuCommand物件,如下列範例所示。

    Private Sub OnBeforeQueryStatus(ByVal sender As Object, ByVal e As EventArgs)
        Dim myCommand As OleMenuCommand = TryCast(sender, OleMenuCommand)
        If myCommand IsNot Nothing Then
            myCommand.Text = "New Text" 
        End If 
    End Sub
    
    private void OnBeforeQueryStatus(object sender, EventArgs e)
    {
        var myCommand = sender as OleMenuCommand;
        if (null != myCommand)
        {
            myCommand.Text = "New Text";
        }
    }
    

MPF 會自動處理不支援或未知的群組的大小寫。 除非命令已新增至OleMenuCommandService藉由使用AddCommand不支援該命令的方法。

使用 IOleCommandTarget 介面來處理命令

使用程式碼的IOleCommandTarget介面直接、 VSPackage 必須實作兩個QueryStatusExec的方法IOleCommandTarget介面。 如果 VSPackage 實作專案階層架構中, QueryStatusCommandExecCommand的方法IVsUIHierarchy而是應該實作介面。

這兩個QueryStatusExec方法設計用來接收一組單一命令GUID和命令 Id 的陣列做為輸入。 我們建議您 VSPackages 完全透過一通電話支援多個識別碼的這個概念。 不過,只要從其他的 VSPackages 不呼叫 VSPackage 時,您可以假設命令陣列會包含只有一個命令 ID,因為QueryStatusExec會以完整定義的順序執行方法。 如需路由的詳細資訊,請參閱 Command Routing in VSPackages

使用程式碼的IOleCommandTarget介面直接對命令處理,您就必須實作QueryStatus VSPackage,以下列方式來處理命令中的方法。

若要實作的 QueryStatus 方法

  1. 傳回S_OK為有效的命令。

  2. 設定cmdf中的項目prgCmds參數。

    值為cmdf項目是從值的邏輯聯集OLECMDF列舉型別,使用邏輯 OR 組合|) 運算子。

    請使用適當的列舉型別,依據命令的狀態:

    • 如果支援該命令:

      prgCmds[0].cmdf = OLECMDF_SUPPORTED;

    • 如果當時,命令應該是不可見的:

      prgCmds[0].cmdf |= OLECMDF_INVISIBLE;

    • 如果命令上切換,而且看起來似乎被按下:

      prgCmds[0].cmdf |= OLECMDF_LATCHED;

      正在處理裝載類型的功能表的命令的情況下MenuControllerLatched,標記的程式碼的第一個指令OLECMDF_LATCHED旗標會隨即出現在 [啟動功能表的 [預設] 指令。 如需有關MenuController功能表類型,請參閱Menu 項目

    • 如果目前已啟用的命令:

      prgCmds[0].cmdf |= OLECMDF_ENABLED;

    • 如果位於快顯功能表的命令,且預設為隱藏:

      prgCmds[0] cmdf |= OLECMDF_DEFHIDEONCTXMENU

    • 如果本指令會使用TEXTCHANGES加上旗標,請將rgwz中的項目pCmdText參數的命令,並設定新的文字以cwActual中的項目pCmdText參數的指令字串的大小。

    錯誤狀況, QueryStatus方法必須處理下列的錯誤情況:

    • 如果 GUID 是未知或不受支援,會傳回OLECMDERR_E_UNKNOWNGROUP。

    • 如果已知 GUID,但命令 ID 是未知或不受支援,會傳回OLECMDERR_E_NOTSUPPORTED。

VSPackage 實作的Exec方法也必須傳回特定的錯誤碼,取決於是否支援該命令和命令是否成功地處理。

若要實作的 Exec 方法

  • 如果命令GUID不明,傳回OLECMDERR_E_UNKNOWNGROUP。

  • 如果GUID是已知但命令 ID 為未知,傳回OLECMDERR_E_NOTSUPPORTED。

  • 如果GUID和命令 ID 相符的命令,在.vsct 檔案中使用的 GUID:ID 組、 執行命令,並傳回相關聯的程式碼S_OK

請參閱

概念

VSCT XML 結構描述參考

其他資源

一般工作的命令、 功能表和工具列

Walkthrough: Adding a Command to a Visual Studio Menu