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多线程系 ...
随机推荐
- eclipse下:selenium+python自动化之Chrome driver
1.下载chromedriver.exe文件: 2.下载的chromedriver.exe文件放置在chrome的安装目录下XXX\Chrome\Application\ ; 3.设置path环境变量 ...
- iis6 下发布MVC2项目的方法
1.安装MVC2运行库,否则会出现错误 [以下转载]http://blog.csdn.net/xw13106209/article/details/6323695 错误:”未能加载文件或程序集“Sys ...
- ActionScript:Resampling PCM data
使用基于flash的麦克风录音,如果想在获取完PCM采样数据后,通过Sound马上回放,必须经过resampling.(注意:如果录音是采用的44KHz的话,则不需要) 因此,需要as实现一个简便的函 ...
- IOS开发网络篇之──ASIHTTPRequest详解
目录 目录 发起一个同步请求 创建一个异步请求 队列请求 请求队列上下文 ASINetworkQueues, 它的delegate提供更为丰富的功能 取消异步请求 安全的内存回收建议 向服务器端上传数 ...
- OC - 31.通过封装的自定义布局快速实现商品展示
概述 实现效果 设计思路 采用MVC架构,即模型—视图-控制器架构 使用MJExtension框架实现字典转模型 使用MJRefresh框架实现上拉和下拉刷新 上拉刷新,加载新的数据 下拉刷新,加载更 ...
- java通过移位转16进制
public class Main { public static void main(String []args) { Main main = new Main(); System.out.prin ...
- ktv
自制KTV点歌系统经验 Windows Media Player控件播放 Windows Media Player控件的简单使用 1.播放一首歌曲的方法 Windows Media Pla ...
- IO流基础
IO流,也称为数据流,用于处理设备之间的数据传输. JAVA对数据的操作就是通过流的方式,而流分为两种:字符流,字节流 字符流: 可以内部制定码表,处理文字很方便,字符流里的基类是Reader,Wri ...
- 关掉PUTTY后,进程仍可以运行。
如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令.该命令可以在你退出帐户之后继续运行相应的进程.no hup就是不挂起的意思( no hang up).该命令 ...
- date日期比较和格式化方法
时间的比较 var now = new Date();//现在时间 var setDate = new Date(2017,0,5,17,55,55);//设定的时间 laert(now < s ...