快捷功能表處理程式,也稱為上下文功能表處理程式或 verb 處理程式,是檔案類型處理程式的一種。 這些處理程式可以以某種方式實作,使它們在自己的進程、檔案總管或其他第三方進程中載入。 在建立同進程處理程式時,請小心,因為它們可能會對載入它們的進程造成傷害。
64 位元版本的 Windows 在註冊於 32 位元應用程式上下文中運作的處理程式時有特殊考量:當在不同位元應用程式的上下文中被調用時,WOW64 子系統會將文件系統的存取重新導向至某些路徑。 如果您的.exe處理程序儲存在其中一個路徑裡,則無法在此內容中存取。 因此,作為解決方法,請將您的.exe儲存在未重新導向的路徑中,或儲存啟動實際版本的.exe存根版本。
本主題的組織方式如下:
僅供程式化存取的動詞
使用靜態動詞自定義快捷方式功能表
使用 IDropTarget 介面啟用您的處理程序
指定靜態動詞的位置和順序
將動詞排列在選單的頂端或底部
建立靜態級聯功能表
使用進階查詢語法取得靜態動詞的動態行為
已淘汰:將動詞與動態數據交換命令產生關聯
完成實作 Verb 工作
自訂預先定義 Shell 物件的快捷方式功能表
擴充新的子功能表
隱藏動詞和控制可見性
Verb採用選取模型
使用項目屬性
透過 Desktop.ini 實作資料夾的自定義動詞
應用程式通常會負責為所定義的動詞提供本地化的顯示字串。 不過,為了提供一定程度的語言獨立性,系統會定義一組常用的動詞,稱為規範動詞。
verb標準永遠不會向用戶顯示,而且可以搭配任何UI語言使用。 系統會使用標準名稱自動產生正確本地化的顯示字串。 例如,開啟顯示字串會在英文系統上設定為
Open
,而在德文系統上則設定為德文的對應字串。
規範 verb
Printto
verb 也是標準的,但從不顯示。 這項功能允許使用者將檔案拖曳至印表機物件來列印檔案。
快捷功能表處理程式可以透過
IContextMenu::GetCommandString
搭配
GCS_VERBW
或
GCS_VERBA
提供自己的標準動詞。 系統會使用標準動詞作為傳遞至
ShellExecute
的第二個參數 (
lpOperation
),而 是
CMINVOKECOMMANDINFO。
傳遞至 IContextMenu::InvokeCommand
方法的
lpVerb 成員。
當使用者以滑鼠右鍵按下物件時,快捷方式功能表會顯示預設動詞。 您可能想要在某些並未顯示於所有捷徑選單的選單上新增並支援命令。 例如,您可以有一些不常使用或適用於有經驗使用者的命令。 基於這個理由,您也可以定義一或多個擴充動詞。 這些動詞類似於一般動詞,但它們是根據登記方式與一般動詞有所區別。 若要能夠存取擴充動詞,用戶必須在按下 SHIFT 鍵時,以滑鼠右鍵按兩下物件。 當使用者這樣做時,除了默認動詞之外,也會顯示擴充動詞。
您可以使用登錄來定義一或多個擴充動詞。 只有當使用者以滑鼠右鍵按下,同時按下SHIFT鍵時,才會顯示相關聯的命令。 若要將 verb 定義為「擴充」,請將「擴充」
REG_SZ
值新增至 verb 的子機碼。 值不應該有任何與其相關聯的數據。
僅能透過程式化方式存取的動詞
這些動詞永遠不會顯示在操作功能表中。 您可以使用
ShellExecuteEx
並指定
pExecInfo
參數的
lpVerb
欄位來存取這些欄位(
SHELLEXECUTEINFO
物件)。 若要將verb定義為僅限程序性存取,請將「ProgrammaticAccessOnly」
REG_SZ
值新增至verb的子機碼。 值不應該有任何與其相關聯的數據。
您可以使用登錄來定義一或多個擴充動詞。 只有當使用者以滑鼠右鍵按下,同時按下SHIFT鍵時,才會顯示相關聯的命令。 若要將 verb 定義為擴充,請將「擴充」
REG_SZ
值新增至 verb 的子機碼。 值不應該有任何與其相關聯的數據。
為快捷方式選單選擇靜態或動態Verb
之後,您可以註冊檔類型的靜態verb來擴充檔類型的快捷方式功能表。 若要這樣做,請在與文件類型相關聯之應用程式的 ProgID 子機碼下方新增
Shell
子機碼。 您可以選擇性地為檔案類型定義預設值 verb ,方法是將其設為分項密鑰的預設值
Shell
。
預設值 verb 會先顯示在快捷方式功能表上。 其目的是在呼叫
ShellExecuteEx 函數
時,提供Shellverb可以使用的verb,但未指定。
Shell在此方式中使用
ShellExecuteEx
時,不一定選取預設值verb。
會依照下列順序使用第一個可用的 verb:
預設值 verb
如果verb指定順序,則為登錄中的第一個verb
這
Open
verb
這
Open With
verb
如果未列出任何動詞,則作業會失敗。
為每個您想要新增到 Shell 子機碼下的 verb 建立一個子機碼。 每個子機碼都必須將
REG_SZ
值設定為 verb的顯示字串(當地語系化字串)。 針對每個 verb 子機碼,建立命令子機碼,並將預設值設定為命令行以啟動專案。 對於標準動詞,例如
Open
和
Print
,您可以省略顯示字串,因為系統會自動顯示正確本地化的字串。 若為非規範動詞,如果您省略顯示字串,則會顯示verb字串。
在下列登錄範例中,請注意:
因為
Doit
不是標準 , verb所以會指派顯示名稱,可按 D 鍵加以選取。
Printto
verb 不會出現在快捷方式功能表上。 不過,其包含在登錄中可讓使用者將檔案拖放到印表機圖示上來列印。
每個 verb都會顯示一個子機碼。
%1
代表檔名和
%2
印表機名稱。
HKEY_CLASSES_ROOT
.myp-ms
(Default) = MyProgram.1
MyProgram.1
(Default) = My Program Application
Shell
(Default) = doit
(Default) = &Do It
command
(Default) = c:\MyDir\MyProgram.exe /d "%1"
command
(Default) = c:\MyDir\MyProgram.exe /d "%1"
print
command
(Default) = c:\MyDir\MyProgram.exe /p "%1"
printto
command
(Default) = c:\MyDir\MyProgram.exe /p "%1" "%2"
下圖說明捷徑功能表的延伸,根據上述登錄項目。 此捷徑選單在其選單上具有Open、Do It 及 Print 動詞,並以 Do It 作為預設 verb。
使用 IDropTarget 介面來啟用您的處理程式
動態數據交換 (DDE) 已被取代;請改用 IDropTarget。
IDropTarget 更加穩固,且具有更好的啟用支援,因為它使用處理程式的 COM 啟用。 在多個項目選取的情況下,IDropTarget 不會受限於 DDE 和 CreateProcess 中找到的緩衝區大小限制。 此外,項目會作為可以轉換成項目陣列的數據物件傳送到應用程式,可以使用 SHCreateShellItemArrayFromDataObject 函式。 這樣做會比較簡單,而且當項目轉換成命令行或 DDE 通訊協定的路徑時,不會遺失命名空間資訊。
如需 IDropTarget 和 Shell 檔案關聯屬性查詢的詳細資訊,請參閱 感知的類型和應用程式註冊。
指定靜態動詞的位置和順序
通常來說,動詞會根據捷徑功能表上的列舉方式排序;列舉首先根據關聯陣列的順序,再根據關聯陣列中專案的順序,具體排序方式由註冊表的排序順序決定。
動詞可以藉由指定關聯項目中的子機碼 Shell 的預設值來排序。 這個預設值可以包含單一項目,這將顯示在快捷方式功能表頂端位置,或是空白鍵或逗號分隔的項目清單。 在後一種情況下,清單中的第一個項目是預設項目,而其他動詞會按照指定的順序緊接在它的下方。
例如,下列登錄項目會依照下列順序產生快捷功能表命令:
HKEY_CLASSES_ROOT
DesktopBackground
Shell
Display
Gadgets
Personalization
同樣地,下列登錄項目會依下列順序產生捷徑選單動詞:
HKEY_CLASSES_ROOT
DesktopBackground
Shell = "Personalization,Gadgets"
Display
下列登錄屬性可用來將 verb 放置在功能表的最上方或最下方。 如果有多個動詞指定此屬性,則最後一個要執行此動作的動詞會取得優先順序:
Position=Top | Bottom
在 Windows 7 和之後的版本中,透過登錄設定支援級聯選單的實作。 在 Windows 7 之前,僅能透過 IContextMenu 介面的實作來建立級聯功能表。 在 Windows 7 和更新版本中,只有當靜態方法不足時,才應該使用 COM 程式代碼型解決方案。
下列螢幕快照提供級聯功能表的範例。
使用 SubCommands 項目建立級聯功能表
於HKEY_CLASSES_ROOT\ProgID\shell下建立一個子機碼,以代表您的級聯選單。 在此範例中,我們將此子機碼命名為 CascadeTest。 確定 CascadeTest 子機碼的預設值是空的,並顯示為 [未設定的值]。
HKEY_CLASSES_ROOT
shell
CascadeTest
(Default)
在 CascadeTest 子機碼中,新增一個類型為 REG_SZ 的 MUIVerb 項目,並為其指派一個名稱,該名稱將會在捷徑選單中顯示為其文字。 在此範例中,我們會將其指派為「測試層疊選單」。
HKEY_CLASSES_ROOT
shell
CascadeTest
(Default)
MUIVerb = Test Cascade Menu
在您的 CascadeTest 子機碼中,新增一個類型為 REG_SZ 的 SubCommands 項目,該項目是一個以分號分隔的清單,清單中的指令動詞應按出現順序顯示在功能表上。 例如,我們在這裡指派一些系統提供的動詞:
HKEY_CLASSES_ROOT
Shell
CascadeTest
SubCommands
Windows.delete;Windows.properties;Windows.rename;Windows.cut;Windows.copy;Windows.paste
如果是自定義動詞,請使用任何靜態 verb 實作方法來實作它們,並在 CommandStore 子機碼下列出它們,如下列範例所示,例如虛構 verb的 VerbName:
HKEY_LOCAL_MACHINE
Software
Microsoft
Windows
CurrentVersion
Explorer
CommandStore
Shell
VerbName
command
(Default) = notepad.exe %1
這個方法的優點是,自定義動詞可以註冊一次,並藉由在 SubCommands 項目下列出 verb 名稱來重複使用。 不過,它要求應用程式具有在 HKEY_LOCAL_MACHINE 下修改登錄的許可權。
使用 ExtendedSubCommandsKey 註冊表項建立級聯功能表
在 Windows 7 和之後的版本中,您可以使用 ExtendedSubCommandKey 項目來創建擴展級聯功能表:在級聯功能表中嵌套的級聯功能表。
下列螢幕快照是延伸下拉選單的範例。
由於HKEY_CLASSES_ROOT是HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE的組合,因此您可以在HKEY_CURRENT_USER\Software\Classes子機碼下註冊任何自定義動詞。 這樣做的主要優點是無需取得高權限。 此外,其他檔案關聯也可以藉由指定相同的 ExtendedSubCommandsKey 子機碼,重複使用這組整個動詞。 如果您不需要重複使用這組動詞,則可以列出父代底下的動詞,但請確定父系的預設值是空的。
使用 ExtendedSubCommandsKey 項目建立級聯功能表
在 HKEY_CLASSES_ROOT\ProgID\shell 下建立子鍵,以代表您的階層式功能表。 在此範例中,我們將此子機碼命名為 CascadeTest2。 確定 CascadeTest 子機碼的預設值是空的,並顯示為 [未設定的值]。
HKEY_CLASSES_ROOT
shell
CascadeTest2
(Default)
在 CascadeTest 子機碼中,新增一個類型為 REG_SZ 的 MUIVerb 項目,並為其指派一個名稱,該名稱將會在捷徑選單中顯示為其文字。 在此範例中,我們會將其指派為「測試層疊選單」。
HKEY_CLASSES_ROOT
shell
CascadeTest
(Default)
MUIVerb = Test Cascade Menu 2
在您建立的 CascadeTest 子機碼底下,新增 ExtendedSubCommandsKey 子機碼,然後新增文件子命令(REG_SZ 類型);例如:
HKEY_CLASSES_ROOT
txtfile
Shell
Test Cascade Menu 2
(Default)
ExtendedSubCommandsKey
Layout
Properties
Select all
確認 測試串聯功能表 2 子機碼的預設值為空,並顯示為 (未設定值)。
使用下列任一靜態 verb 實作來填入子動詞。 請注意,CommandFlags 子機碼代表 EXPCMDFLAGS 值。 如果您想要在串聯功能表項前後新增分隔符,請使用ECF_SEPARATORBEFORE (0x20) 或 ECF_SEPARATORAFTER (0x40)。 如需這些 Windows 7 和更新版本旗標的描述,請參閱 IExplorerCommand::GetFlags。 ECF_SEPARATORBEFORE僅作用於頂層選單項目。 MUIVerb 的類型 為 REG_SZ,而 CommandFlags 的類型 為 REG_DWORD。
HKEY_CLASSES_ROOT
txtile
Shell
Test Cascade Menu 2
(Default)
ExtendedSubCommandsKey
Shell
MUIVerb = Notepad
command
(Default) = %SystemRoot%\system32\notepad.exe %1
MUIVerb = Wordpad
CommandFlags = 0x20
command
(Default) = "C:\Program Files\Windows NT\Accessories\wordpad.exe" %1
下列螢幕快照是之前登錄機碼項目範例的說明。
使用 IExplorerCommand 介面建立級聯功能表
將動詞新增至級聯功能表的另一個選項是透過IExplorerCommand::EnumSubCommands。 這個方法可讓數據源透過 IExplorerCommandProvider 提供其命令模組命令,以在快捷方式功能表上將這些命令當做動詞命令。 在 Windows 7 和更新版本中,您可以使用 IExplorerCommand 提供與 IContextMenu 相同的verb實作。
下列兩個螢幕快照說明如何在 [裝置] 資料夾中使用級聯功能表。
使用進階查詢語法取得靜態動詞的動態行為
進階查詢語法(AQS)可以表達一個條件,此條件將使用為 verb 實例化的項目的屬性來進行評估。 此系統僅適用於快速屬性。 這些屬性會被Shell數據源報告為快速,因為它們在IShellFolder2::GetDefaultColumnState中沒有傳回SHCOLSTATE_SLOW。
Windows 7 和更新版本支持標準值,以避免當地語系化組建發生問題。 當地語系化組建需要下列標準語法,才能利用此 Windows 7 增強功能。
System.StructuredQueryType.Boolean#True
在下列例子註冊表項中:
AppliesTo 值控制verb的顯示或隱藏。
DefaultAppliesTo 值會決定哪一個 verb 為預設。
HasLUAShield 值會控制是否顯示使用者帳戶控制(UAC)盾牌符號。
在此範例中, DefaultAppliesTo 值會將其檔名中的 「exampleText1」 字組設為 verb 任何檔案的預設值。
AppliesTo 值會針對名稱中包含 「exampleText1」 的任何檔案啟用 verb 。
HasLUAShield 值會顯示名稱中有 「exampleText2」 之檔案的盾牌。
HKEY_CLASSES_ROOT
txtile
shell
test.verb
DefaultAppliesTo = System.ItemName:"exampleText1"
HasLUAShield = System.ItemName:"exampleText2"
AppliesTo = System.ItemName:"exampleText1"
新增 Command 子機碼,並新增一個值:
HKEY_CLASSES_ROOT
txtile
shell
test.verb
Command
(Default) = %SystemRoot%\system32\notepad.exe %1
在 Windows 7 登錄中,請參閱 HKEY_CLASSES_ROOT\磁碟 作為採用下列方法的 BitLocker 動詞範例:
AppliesTo = System.Volume.BitlockerProtection:=2
System.Volume.BitlockerRequiresAdmin:=System.StructuredQueryType.Boolean#True
如需 AQS 的詳細資訊,請參閱 進階查詢語法。
已淘汰:將動詞與動態數據交換命令產生關聯
DDE 已被取代;請改用 IDropTarget。 DDE 已被廢棄,因為它依賴於廣播窗口消息來識別 DDE 伺服器。 DDE 伺服器停止回應會導致廣播視窗訊息延遲,因此會造成其他應用程式的 DDE 對話停止。 單一卡住的應用程式通常會影響用戶的系統運行,造成接下來的所有卡住現象。
IDropTarget 方法更健全,而且具有更佳的啟用支持,因為它使用處理程式的 COM 啟用。 在多個項目選取的情況下,IDropTarget 不會受限於 DDE 和 CreateProcess 中找到的緩衝區大小限制。 此外,項目會作為可以轉換成項目陣列的數據物件傳送到應用程式,可以使用 SHCreateShellItemArrayFromDataObject 函式。 這樣做會比較簡單,而且當項目轉換成命令行或 DDE 通訊協定的路徑時,不會遺失命名空間資訊。
如需 IDropTarget 和 Shell 檔案關聯屬性查詢的詳細資訊,請參閱 感知的類型和應用程式註冊。
完成執行 Verb 任務
與實作動詞相關的下列任務適用於靜態和動態 verb 實作。 如需動態動詞的詳細資訊,請參閱 使用動態動詞自定義快捷方式功能表。
許多預先定義的 Shell 物件都有可自定義的快捷功能表。 以您註冊一般檔類型的方式註冊命令,但使用預先定義的物件名稱做為檔類型名稱。
預先定義的物件清單位於建立Shell延伸模塊處理程式的 [預先定義Shell的物件] 區段中。 這些預先定義的 Shell 物件,其快捷功能表可以透過在登錄中新增動詞來自訂,其在數據表中會以 Verb 標記。
當使用者在 Windows 檔案總管中開啟 [檔案 ] 功能表時,顯示的其中一個命令是 [新增]。 選取此命令會顯示子功能表。 根據預設,子功能表包含兩個命令 Folder 和 Shortcut,可讓使用者建立子資料夾和快捷方式。 您可以擴充此子功能表,以包含任何文件類型的檔案建立命令。
若要將檔案建立命令新增至 [新增 ] 子功能表,您的應用程式檔案必須具有相關聯的檔類型。 在檔名下新增一個名為 ShellNew 的子機碼。 選取 [ 檔案 ] 功能表的 [ 新增 ] 命令時,會將 Shell 文件類型新增至 [新增 ] 子功能表。 命令的顯示字串是指派給程式 ProgID 的描述性字串。
若要指定檔案建立方法,請將一或多個數據值指派給 ShellNew 子機碼。 下表列出可用的值。
ShellNew 子機碼值
建立拖放處理程式
實作拖放處理程式的基本程式,與傳統快捷方式功能表處理程式相同。 不過,快捷方式功能表處理程式通常只使用傳遞至處理程式的 IShellExtInit::Initialize 方法的 IDataObject 指標來擷取物件的名稱。 拖放處理程式可以實作更複雜的數據處理程式,以修改拖曳對象的行為。
當使用者以滑鼠右鍵按下 Shell 物件以拖曳物件時,當使用者嘗試卸除物件時,就會顯示快捷方式功能表。 下列螢幕快照說明一般拖放快捷功能表。
DragDropHandlers
在針對拖放處理程式命名的 DragDropHandlers 子機碼下新增子機碼,並將子機碼的預設值設定為處理程式類別標識元 (CLSID) GUID 的字串形式。 下列範例會啟用 MyDD 拖放處理程式。
HKEY_CLASSES_ROOT
Directory
shellex
DragDropHandlers
(Default) = {MyDD CLSID GUID}
隱藏動詞和控制可見性
您可以使用 Windows 原則設定來控制 verb 可見度。 動詞可透過原則設定隱藏,方法是將 SuppressPolicy 值或 SuppressPolicyEx GUID 值新增至 verb的登錄子機碼。 將SuppressionPolicy子機碼的值設定為策略識別碼。 如果原則已開啟,verb 和其相關的捷徑選單項目會被隱藏。 如需可能的原則標識碼值,請參閱 RESTRICTIONS 列舉。
Verb採用選擇模型
必須為動作設定登錄數值,以處理使用者可以選取單一項目、多個項目或從中選擇的情況。
verb需要為verb所支援的這三種情況,各建立個別的登錄值。
verb 選取模型的可能值如下所示。
為所有動詞指定 MultiSelectModel 值。 如果未指定 MultiSelectModel 值,則會從您選擇的實作 verb 類型推斷。 如果是基於 COM 的方法(例如 DropTarget 和 ExecuteCommand),則假設為Player;對於其他方法,則假設為Document。
指定Single給只支援單一選取的動詞。
如果動詞支援任意數量的項目,請指定Player。
請為那些會為每個項目建立最上層視窗的動詞指定Document。 這樣做會限制啟動的項目數目,並協助避免用戶開啟太多視窗時耗盡系統資源。
當選取的項目數目不符合 verb 選取模型,或大於下表中所述的預設限制時, verb 將無法顯示。
實作 verb 類型
AttributeMask 值會 指定要測試遮罩之位值的 SFGAO 值。
AttributeValue 值會 指定所測試位的 SFGAO 值。
ImpliedSelectionModel 會對項目中的動詞指定為零,或對背景快捷功能表中的動詞指定為非零。
在下列範例登錄專案中,AttributeMask 會設定為 SFGAO_READONLY (0x40000)。
HKEY_CLASSES_ROOT
txtfile
Shell
test.verb2
AttributeMask = 0x40000
AttributeValue = 0x0
ImpliedSelectionModel = 0x0
command
(Default) = %SystemRoot%\system32\notepad.exe %1
透過 Desktop.ini 實現資料夾的自定義動詞
在 Windows 7 和更新版本中,您可以透過 Desktop.ini 將動詞新增至資料夾。 如需Desktop.ini檔案的詳細資訊,請參閱 如何使用 Desktop.ini 自定義資料夾。
Desktop.ini檔案應一律標示為系統 + 隱藏,因此不會向用戶顯示。
若要透過Desktop.ini檔案新增資料夾的自訂動詞,請執行下列步驟:
建立標示 為唯讀 或 系統的資料夾。
建立一個包含 [.ShellClassInfo] 及 DirectoryClass=Folder ProgID 的 Desktop.ini 檔案。
在登錄中,建立 HKEY_CLASSES_ROOT\Folder ProgID,值為 CanUseForDirectory。 CanUseForDirectory 值可避免錯誤使用那些被設置為不參與透過 Desktop.ini 實作自定義資料夾動詞的 ProgID。
在FolderProgID 子機碼下,新增動詞,例如:
HKEY_CLASSES_ROOT
CustomFolderType
Shell
MyVerb
command
(Default) = %SystemRoot%\system32\notepad.exe %1\desktop.ini