http://msdn.microsoft.com/en-us/library/windows/desktop/hh127443(v=vs.85).aspx

IContextMenu is the most powerful but also the most complicated interface to implement. We strongly recommend that you implement a verb by using one of the static verb methods. For more information, see Choosing a Static or Dynamic Shortcut Menu MethodIContextMenu has three methods,GetCommandStringInvokeCommand, and QueryContextMenu, which are discussed here in detail.

What you need to know

Technologies

  • C++

Prerequisites

  • Static Verb
  • Shortcut Menu

Instructions

IContextMenu::GetCommandString Method

The handler's IContextMenu::GetCommandString method is used to return the canonical name for a verb. This method is optional. In Windows XP and earlier versions of Windows, when Windows Explorer has a Status bar, this method is used to retrieve the help text that is displayed in the Status bar for a menu item.

The idCmd parameter holds the identifier offset of the command that was defined whenIContextMenu::QueryContextMenu was called. If a help string is requested, uFlags will be set toGCS_HELPTEXTW. Copy the help string to the pszName buffer, casting it to a PWSTR. The verb string is requested by setting uFlags to GCS_VERBW. Copy the appropriate string to pszName, just as with the help string. The GCS_VALIDATEA and GCS_VALIDATEW flags are not used by shortcut menu handlers.

The following example shows a simple implementation of GetCommandString that corresponds to theQueryContextMenu example given in the IContextMenu::QueryContextMenu Method section of this topic. Because the handler adds only one menu item, there is only one set of strings that can be returned. The method tests whether idCmd is valid and, if it is, returns the requested string.

The StringCchCopy function is used to copy the requested string to pszName to ensure that the copied string does not exceed the size of the buffer specified by cchName. This example implements support only for the Unicode values of uFlags, because only those have been used in Windows Explorer since Windows 2000.

 
 
IFACEMETHODIMP CMenuExtension::GetCommandString(UINT idCommand,
UINT uFlags,
UINT *pReserved,
PSTR pszName,
UINT cchName)
{
HRESULT hr = E_INVALIDARG; if (idCommand == IDM_DISPLAY)
{
switch (uFlags)
{
case GCS_HELPTEXTW:
// Only useful for pre-Vista versions of Windows that
// have a Status bar.
hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
cchName,
L"Display File Name");
break; case GCS_VERBW:
// GCS_VERBW is an optional feature that enables a caller
// to discover the canonical name for the verb that is passed in
// through idCommand.
hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
cchName,
L"DisplayFileName");
break;
}
}
return hr;
}

IContextMenu::InvokeCommand Method

This method is called when a user clicks a menu item to tell the handler to run the associated command. The pici parameter points to a structure that contains the information required to run the command.

Although pici is declared in Shlobj.h as a CMINVOKECOMMANDINFO structure, in practice it often points to a CMINVOKECOMMANDINFOEX structure. This structure is an extended version ofCMINVOKECOMMANDINFO and has several additional members that make it possible to pass Unicode strings.

Check the cbSize member of pici to determine which structure was passed in. If it is aCMINVOKECOMMANDINFOEX structure and the fMask member has the CMIC_MASK_UNICODEflag set, cast pici to CMINVOKECOMMANDINFOEX. This enables your application to use the Unicode information that is contained in the last five members of the structure.

The structure's lpVerb or lpVerbW member is used to identify the command to be executed. Commands are identified in one of the following two ways:

  • By the command's verb string
  • By the command's identifier offset

To distinguish between these two cases, check the high-order word of lpVerb for the ANSI case orlpVerbW for the Unicode case. If the high-order word is nonzero, lpVerb or lpVerbW holds a verb string. If the high-order word is zero, the command offset is in the low-order word of lpVerb.

The following example shows a simple implementation of IContextMenu::InvokeCommand that corresponds to the IContextMenu::QueryContextMenu and IContextMenu::GetCommandStringexamples given before and after this section. The method first determines which structure is being passed in. It then determines whether the command is identified by its offset or its verb. If lpVerb orlpVerbW holds a valid verb or offset, the method displays a message box.

 
 
STDMETHODIMP CShellExtension::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
BOOL fEx = FALSE;
BOOL fUnicode = FALSE; if(lpcmi->cbSize == sizeof(CMINVOKECOMMANDINFOEX))
{
fEx = TRUE;
if((lpcmi->fMask & CMIC_MASK_UNICODE))
{
fUnicode = TRUE;
}
} if( !fUnicode && HIWORD(lpcmi->lpVerb))
{
if(StrCmpIA(lpcmi->lpVerb, m_pszVerb))
{
return E_FAIL;
}
} else if( fUnicode && HIWORD(((CMINVOKECOMMANDINFOEX *) lpcmi)->lpVerbW))
{
if(StrCmpIW(((CMINVOKECOMMANDINFOEX *)lpcmi)->lpVerbW, m_pwszVerb))
{
return E_FAIL;
}
} else if(LOWORD(lpcmi->lpVerb) != IDM_DISPLAY)
{
return E_FAIL;
} else
{
MessageBox(lpcmi->hwnd,
"The File Name",
"File Name",
MB_OK|MB_ICONINFORMATION);
} return S_OK;
}

IContextMenu::QueryContextMenu Method

The Shell calls IContextMenu::QueryContextMenu to enable the shortcut menu handler to add its menu items to the menu. It passes in the HMENU handle in the hmenu parameter. The indexMenuparameter is set to the index to be used for the first menu item that is to be added.

Any menu items that are added by the handler must have identifiers that fall between the values in theidCmdFirst and idCmdLast parameters. Typically, the first command identifier is set to idCmdFirst, which is incremented by one (1) for each additional command. This practice helps you to avoid exceedingidCmdLast and maximizes the number of available identifiers in case the Shell calls more than one handler.

An item identifier's command offset is the difference between the identifier and the value in idCmdFirst. Store the offset of each item that your handler adds to the shortcut menu, because the Shell might use the offset to identify the item if it subsequently calls IContextMenu::GetCommandString orIContextMenu::InvokeCommand.

You should also assign a verb to each command that you add. A verb is a string that can be used instead of the offset to identify the command when InvokeCommand is called. It is also used by functions such as ShellExecuteEx to execute shortcut menu commands.

There are three flags that can be passed in through the uFlags parameter that are relevant to shortcut menu handlers. They are described in the following table.

Flag Description
CMF_DEFAULTONLY The user has selected the default command, usually by double-clicking the object. IContextMenu::QueryContextMenu should return control to the Shell without modifying the menu.
CMF_NODEFAULT No item in the menu should be the default item. The method should add its commands to the menu.
CMF_NORMAL The shortcut menu will be displayed normally. The method should add its commands to the menu.

Use either InsertMenu or InsertMenuItem to add menu items to the list. Then return an HRESULTvalue with the severity set to SEVERITY_SUCCESS. Set the code value to the offset of the largest command identifier that was assigned, plus one (1). For example, assume that idCmdFirst is set to 5 and you add three items to the menu with command identifiers of 5, 7, and 8. The return value should be MAKE_HRESULT(SEVERITY_SUCCESS, 0, 8 + 1).

The following example shows a simple implementation of QueryContextMenu that inserts a single command. The identifier offset for the command is IDM_DISPLAY, which is set to zero. The m_pszVerband m_pwszVerb variables are private variables that are used to store the associated language-independent verb string in both ANSI and Unicode formats.

 
 
#define IDM_DISPLAY 0

STDMETHODIMP CMenuExtension::QueryContextMenu(HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
HRESULT hr; if(!(CMF_DEFAULTONLY & uFlags))
{
InsertMenu(hMenu,
indexMenu,
MF_STRING | MF_BYPOSITION,
idCmdFirst + IDM_DISPLAY,
"&Display File Name"); hr = StringCbCopyA(m_pszVerb, sizeof(m_pszVerb), "display");
hr = StringCbCopyW(m_pwszVerb, sizeof(m_pwszVerb), L"display"); return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_DISPLAY + 1));
} return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));}

Remarks

For other verb implementation tasks, see Creating Shortcut Menu Handlers.

Build date: 11/16/2013

How to Implement the IContextMenu Interface的更多相关文章

  1. How to: Implement a Windows Communication Foundation Service Contract

    This is the second of six tasks required to create a basic Windows Communication Foundation (WCF) se ...

  2. Effective Java Chapter4 Classes and Interface

    MInimize the accessibility of classes and members 这个叫做所谓的 information hiding ,这么做在于让程序耦合度更低,增加程序的健壮性 ...

  3. [18/12/05]接口(interface)

    一.定义(类之上的公共标准) 一个特殊的类,用interface关键字来表示.只有全局变量和抽象方法.解决Java中子类只能单继承的问题 [语法] [访问修饰符:public 或 default]  ...

  4. Step2 - How to: Implement a Windows Communication Foundation Service Contract

    This is the second of six tasks required to create a basic Windows Communication Foundation (WCF) se ...

  5. Writing a Windows Shell Extension(marco cantu的博客)

    Writing a Windows Shell Extension This is a technical article covering the content of my last week s ...

  6. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  7. MapReduce

    2016-12-21  16:53:49 mapred-default.xml mapreduce.input.fileinputformat.split.minsize 0 The minimum ...

  8. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  9. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

随机推荐

  1. vs中debug和release版本的区别(转)

    vs中的程序有debug和release两个版本,Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发 人员提供强大的应用程序调试能力.而Rel ...

  2. wpf 调用线程必须为sta 因为许多ui组件都需要

    解决 办法 public void SomeMethod() { var task = System.Windows.Application.Current.Dispatcher.BeginInvok ...

  3. winows8.1或winows7 64bit 安装Itunes 64bit 11.1.3 无法打开一直停止工作的解决办法

    winows8.1或winows7 64bit 安装Itunes 64bit 11.1.3 无法打开一直停止工作的解决办法 系统环境变量里的Path追加 ;C:\program files (x86) ...

  4. 关于 ASP.NET 验证码

    Session["CheckCode"] 这个..不懂神马意思.. .创建一个用户控件 用户名:TextBox 密码: TextBox 验证码:TextBox 验证码图片 < ...

  5. php利用smtp类轻松的发送电子邮件

    当你还在纠结php内置的mail()函数不能发送邮件时,那么你现在很幸运,此时的这篇文章可以帮助到你! php利用smtp类来发邮件真是屡试不爽,我用过很久了,基本上没出过问题.本博客后台,当博主回复 ...

  6. ETLLib库走读

    以前从来也没想过要去看库里的代码,咱想,那怎么也是很底层的代码,居然发现库里的代码也可以这样写,那就先读懂这个ETLLib(跨windows与Linux平台,封装了一些基本的系统调用函数,然后实现定制 ...

  7. 子元素的margin-top影响父元素原因和解决办法

    这个问题会出现在所有浏览器当中,原因是css2.1盒子模型中规定, In this specification, the expression collapsing margins means tha ...

  8. 基于jQuery选择器的整理集合

    jquery对象访问1.each(callback):以每个匹配的元素作为上下文来执行一个函数,return false;停止循环;return true;跳至下一个循环. 来个实例 : 代码如下: ...

  9. web字体格式转换

    @font-face { font-family: 'emotion'; src: url('emotion.eot'); /* IE9*/ src: url('emotion.eot?#iefix' ...

  10. Java高阶面试问题合集

    下面总结一下在Java面试中常用的一些问题,不具体解答,我只附上一些精彩的博文链接. Spring IOC AOP 底层原理 JAVA的反射机制和动态代理 Java反射机制和动态代理 多线程 Spri ...