How to Implement the IContextMenu Interface
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 Method. IContextMenu has three methods,GetCommandString, InvokeCommand, 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的更多相关文章
- 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 ...
- Effective Java Chapter4 Classes and Interface
MInimize the accessibility of classes and members 这个叫做所谓的 information hiding ,这么做在于让程序耦合度更低,增加程序的健壮性 ...
- [18/12/05]接口(interface)
一.定义(类之上的公共标准) 一个特殊的类,用interface关键字来表示.只有全局变量和抽象方法.解决Java中子类只能单继承的问题 [语法] [访问修饰符:public 或 default] ...
- 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 ...
- 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 ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- MapReduce
2016-12-21 16:53:49 mapred-default.xml mapreduce.input.fileinputformat.split.minsize 0 The minimum ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
随机推荐
- Win10安卓模拟器Visual Studio Emulator for Android使用简介(转)
Visual Studio Emulator for Android是微软官方发布的独立版本的安卓模拟器,这款软件可以让安卓应用开发者更加轻松的用Visual Studio编写Android应用,据说 ...
- STL库list::sort()实现深度解析
原创,转载请注明出处:STL库list::sort()实现深度解析 list模板的定义以及一些基本成员函数的实现这里我就不赘述了,还不清楚的同学可以到网上查找相关资料或者直接查看侯捷翻译的<ST ...
- PHPCMS V9 学习总结(转)
转自:http://www.cnblogs.com/Braveliu/p/5074930.html 在实现PHPCMS网站过程中,根据业务需求,我们遇到很多问题,特此总结如下,以便大家参考学习. [1 ...
- dedecms设置文章分页后,标题会带有序号的解决方法
至于删除分页后标题后面的序号,找到include/arc.archives.class.php 打开,找到 if($i>1) $this->Fields['title'] = $this- ...
- ecshop后台根据条件查询后不填充table 返回的json数据,content为空?
做ecshop后台开发的时,根据条件查询后,利用ajax返回的content json数据内容为空,没有填充table 效果 预期效果 问题: make_json_result($smarty -&g ...
- getJSON回调函数不执行问题?
利用getJSON异步请求时,回调函数不执行,不知道是什么问题? php 返回数据 header("Content-type:text/json"); echo json_enco ...
- nginx 一般配置实例 静态页面
# 使用的用户和组 user www www; # 指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍,例如两个四核CPU,则总核数为8) worker_processes 8; # 指定错误日 ...
- linux配置记录
今天想把开发环境都配置到linux环境来,所以用wubi挂载了个ubuntu系统(64位),因为不常使用linux所以把今天学到的一些 东西记下来以做备查. #1. java环境配置 到oracl ...
- android 开源项目学习
1.Android团队提供的示例项目 如果不是从学习Android SDK中提供的那些样例代码开始,可能没有更好的方法来掌握在Android这个框架上开发.由Android的核心开发团队提供了15个优 ...
- 屏蔽手势UIGestureRecognizer 先后响应
在iOS5一下对于手势的识别能力并不强,比如iOS6上面按钮的一个tap事件,最先接收的是uiview,并相应,而不是最上面的button,这时候就需要判断手势所在的位置和手势所在的控制器了 如下例子 ...