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. SQL Server 表字段值转换成字段名称(二)

    上次写了个比较简单的只有两个字段的例子,经要求在写个  3 个字段的示例 ,贴上来与大家共勉一下   如果你们有更好的方法,提供一下, 感激不尽. 示例如下: /*--drop table temp_ ...

  2. eclipse中更改默认编码格式

    更改过程如下: (1)window->preferences->general->content Types, 选中java class file修改default encoding ...

  3. NSDate,NSCalendar,NSTimer,NSTimeZone

      NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间 Dates NSDate类提供了创建date,比较date以及计算两个date之间间隔的功能.Date对象是不可改变的. ...

  4. JavaScript HTML DOM

    JavaScript HTML DOM 通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素. HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象 ...

  5. 微信公众平台开发(免费云BAE+高效优雅的Python+网站开放的API)

    虽然校园App是个我认为的绝对的好主意,但最近有个也不错的营销+开发的模式出现:微信平台+固定域名服务器. 微信公众平台的运行模式不外两个: 一.机器人模式或称转发模式,将说话内容转发到服务器上完成, ...

  6. Leetcode: Reverse Integer 正确的思路下-要考虑代码简化

    题目: Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 Have ...

  7. Fiddle的应用

    在Composer中输入测试的网址: 可能会发生一下情况,这意味着需要在左侧面板中选择一项,来看回应:   选择一个请求后,选择TextView,看原生的回应(Response)内容

  8. GO:格式化代码

    http://www.ituring.com.cn/article/39380 Go 开发团队不想要 Go 语言像许多其它语言那样总是在为代码风格而引发无休止的争论,浪费大量宝贵的开发时间,因此他们制 ...

  9. 关于pcre正则表达式库libpcre

    gcc 4.8中已经包含了std regex的头文件 可是没有实现,所以链接是失败的 gcc 4.9完整的支持了c++ 11的regex. 在4.9以前,可以寻求boost的regex. 不过,我更熟 ...

  10. 架设wordpress再vps上的 一些感想总结

    日本vps.樱花系列 配置: 2cpu+1G内存+100G硬盘 系统 第一次我把默认的centos 给换了..原因就是,不会linux.而且我主要用.net  感觉 mono也行.但是linux不会. ...