【问题标题】:Determine if shell extension is called as a context menu handler or a drag-n-drop handler确定外壳扩展是作为上下文菜单处理程序还是拖放处理程序调用
【发布时间】:2014-03-07 03:39:30
【问题描述】:

我想以编程方式确定我的 shell 扩展是作为 上下文菜单处理程序 还是 拖放处理程序。我已经使用相同的 CLSID 在适当的位置注册了我的 shell 扩展。

注册表:

[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\{E991C840-C1EB-455C-AD64-282473005C58}]
@="Test Context Menu"

[HKEY_CLASSES_ROOT\Directory\shellex\DragDropHandlers\TestDragDrop]
@="{E991C840-C1EB-455C-AD64-282473005C58}"

我的注册表没有问题,我的扩展已加载。

我认为最好的检查位置是 DllGetClassObjectIShellExtInit::Initialize

【问题讨论】:

  • "我已经在正确的位置使用相同的 CLSID 注册了我的 shell 扩展。" - 这意味着什么?那是什么位置(发布注册表项路径)。
  • 另外,发布一些代码。你想从哪里确定?从哪个入口点?你的意思是来自IContextMenu::InvokeCommand
  • "我有两家公司,一家比萨店和一家美发店。我把它们放在电话簿中,电话号码相同。当有人拨打该号码时,我如何知道他们是否打电话订购吃披萨还是安排理发?”答:获取两个电话号码。一个用于比萨店,一个用于美发沙龙。翻译:注册两个 CLSID,一个用于上下文菜单,一个用于拖放处理程序。
  • @RaymondChen:谢谢,你已经知道微软在自己的产品中使用了这种行为:SendTo 是上下文菜单+拖放,具有相同的 CLSID,.LNK 处理程序具有相同的上下文菜单+拖动的 CLSID然后放下。
  • "我想将我的比萨店和美发沙龙合并为一个业务。当我接电话时,我只是等待来电者说“我想点比萨”或“我“想安排一次理发”,一些来电者甚至说“我想两者都做”。没关系,因为我的生意可以两者兼得。”这就是 SendTo 所做的。它不知道它是作为上下文菜单还是作为放置目标创建的。但是如果有人要求上下文菜单,它会提供上下文菜单。如果有人要求放置目标,它会提供放置目标。如果有人要求两者,两者都做

标签: c windows winapi windows-shell shell-extensions


【解决方案1】:

您只能在 IShellExtInit.Initialize 中检测 shell 想要使用的扩展类型。对于上下文菜单处理程序 pidlFolder 为零,对于拖放处理程序 pidlFolder 是文件夹的 PIDL。

【讨论】:

  • 不完全正确,因为背景上下文菜单也设置了 pidlFolder。
  • 我同意你的观点,但如果出现@user2120666 的问题,这并不重要,因为当用户调用文件夹背景的上下文菜单时,不会调用在 * 键下注册的上下文菜单。
  • 不要试图根据间接证据来预测未来。
  • @RaymondChen:你能解释一下吗?
  • 好吧,例如,pidlFolder 为空也可能意味着它是一个属性表处理程序。仅当您需要区分的两件事是非文件夹上下文菜单和非默认拖放处理程序时,您的答案才有效。它没有一概而论。
【解决方案2】:

如果您对多个扩展使用相同的 CLSID,则它不知道正在实例化哪个扩展,除非系统查询 IContextMenu 时可能在 QueryInterface() 中。如果你真的需要区分,最好只使用单独的 CLSID,就像 Raymond Chen 说的那样。它们可以映射到同一个 DLL,但这让您的代码有机会知道正在实例化哪个 CLSID。

【讨论】:

    猜你喜欢
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多