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. Android开发手记(29) 基于Http的LaTeX数学公式转换器

    本文将讲解如何通过codecogs.com和Google.com提供的API接口来将LaTeX数学函数表达式转化为图片形式.具体思路如下: (1)通过EditText获取用户输入的LaTeX数学表达式 ...

  2. 转-SecureCRT设置

    原帖地址:http://www.2cto.com/os/201410/341569.html 一.基本设置 1.修改设置 为了SecureCRT用起来更方便,需要做一些设置,需要修改的有如下几处: 1 ...

  3. iOS 百度地图监听地图状态

    百度地图提供了地图状态的对象BMKMapStatus ///此类表示地图状态信息 @interface BMKMapStatus : NSObject { float _fLevel; // 缩放比例 ...

  4. JavaScript HTML DOM - 改变CSS

    JavaScript HTML DOM - 改变CSS HTML DOM 允许 JavaScript 改变 HTML 元素的样式. 改变 HTML 样式 如需改变 HTML 元素的样式,请使用这个语法 ...

  5. wpf 窗体中显示当前系统时间

    先看一下效果: 这其实是我放置了两个TextBlock,上面显示当前的日期,下面显示时间. 接下来展示一下代码: 在XAML中: <StackPanel Width="205" ...

  6. Java线程(学习整理)--2---加入另一个线程join

    1.join简介: 今天刚学的,这里我简单总结一下,join本身就是“加入”的意思,那么在线程中是什么意思呢?是在一个线程的run方法执行过程中,当特殊情况下需要执行一些其他的操作的时候,我们会用到j ...

  7. 【vc】6_菜 单

    1.菜单命令响应函数: 提示:MFC都是采用大写字母来标识资源ID号的:为了区分资源类型,一般遵循这样一个原则:在“ID”字符串后加上一个标识资源类型的字母.例:菜单资源(Menu):ID_Mxxx: ...

  8. pthread_rwlock_t读写锁函数说明

    读写锁 索引: 初始化一个读写锁pthread_rwlock_init 读锁定读写锁      pthread_rwlock_rdlock 非阻塞读锁定 pthread_rwlock_tryrdloc ...

  9. 升级10.10 Yosemite 后,cocoapods 出现错误(解决方案)

    RSMacBook-Pro:~ RS$ pod search jsonkit /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/li ...

  10. python3 遍历文件

    程序很简单,parent,dirnames,filenames分别表明当前目录下的文件夹数及文件数,然后通过os.wolk向深入遍历.   import os import os.path # thi ...