WM5 SDK Sample InboxMenuExtensibility的一个BUG
来源:互联网 发布:有道云协作下载 mac 编辑:程序博客网 时间:2024/06/07 02:45
http://www.niuray.com/develop/windows-mobile/inboxmenuextensibility-bug-fix/
$(Windows Mobile 5.0 Pocket PC SDK)/Samples/CPP/Win32/Inboxmenuextensibility是一个演示如何在系统收件箱中插入用户菜单和上下文菜单的程序。程序的核心是实现IContextMenu接口,很不幸的是这个例子中QueryContextMenu的返回值是错误的。
咱们先来看看这个接口函数的定义:
HRESULT QueryContextMenu ( HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags );
每个参数的具体含义可以参考MSDN,这里不再详述。例子返回的是一个真实的HRESULT,成功返回S_OK,失败返回对应的错误代码如E_INVALIDARG等。
1: ///////////////////////////////////////////////////////////////////////////////
2: // QueryContextMenu - IContextMenu interface Method
3: //
4: // Adds the extra menu items to the context menu. This method is called when
5: // the menu which our menu extension is extended is being created
6: //
7: // Arguments:
8: // [IN] HMENU hmenu - a handle the menu to insert into
9: // [IN] UINT indexMenu - the position the item will be inserted after
10: // [IN] UINT idCmdFirst - the lowest possible ID for a new command to use
11: // [IN] UINT idCmdLast - the highest possible ID for a new command to use
12: // [IN] LPCTSTR szText - the menu text of the new item
13: // [IN] UINT uFlags - a set of flags indicating what type of insertion and
14: // extension is allowed. Please see the QueryContextMenu topic in the
15: // the SDK documentation for a complete list of these flags
16: // NOTE: The inbox application will only ever send CMF_NORMAL
17: //
18: //
19: // Return Values:
20: // HRESULT - S_OK on success else E_FAIL
21: //
22: HRESULT STDMETHODCALLTYPE MenuExtension::QueryContextMenu(HMENU hmenu,
23: UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
24: {
25: HRESULT hr = S_OK;
26:
27: m_idc1 = idCmdFirst;
28: m_idc2 = idCmdFirst + 1;
29:
30: CBR(m_idc2 <= idCmdLast);
31:
32: BOOL fEnableItem;
33: TCHAR szItemName[30];
34: switch(m_ExtensionType)
35: {
36: case Context:
37: // Get item text
38: hr = GetCommandStringHelper(m_idc1, szItemName, ARRAYSIZE(szItemName));
39: CHR(hr);
40:
41: // Insert the item
42: hr = InsertMenuItem(hmenu, indexMenu, m_idc1, szItemName);
43: CHR(hr);
44:
45: // Determine if we are in an appropriate folder and
46: // have only a SINGLE item selected
47: // if NOT - then gray out this menu option
48: fEnableItem = EnableAddSenderToContacts();
49: ::EnableMenuItem(hmenu, m_idc1, fEnableItem ? MF_ENABLED : MF_GRAYED);
50:
51: break;
52:
53: case Softkey:
54:
55: // Get item text
56: hr = GetCommandStringHelper(m_idc1, szItemName, ARRAYSIZE(szItemName));
57: CHR(hr);
58:
59: // Insert the item
60: hr = InsertMenuItem(hmenu, indexMenu, m_idc1, szItemName);
61: CHR(hr);
62:
63: // Get item text
64: hr = GetCommandStringHelper(m_idc2, szItemName, ARRAYSIZE(szItemName));
65: CHR(hr);
66:
67: // Insert the item
68: hr = InsertMenuItem(hmenu, indexMenu, m_idc2, szItemName);
69: CHR(hr);
70:
71: // Determine if there are items in the ListView
72: // if there are no items - then gray out these menu options
73: fEnableItem = AreThereMessagesInFolder();
74: ::EnableMenuItem(hmenu, m_idc1, fEnableItem ? MF_ENABLED : MF_GRAYED);
75: ::EnableMenuItem(hmenu, m_idc2, fEnableItem ? MF_ENABLED : MF_GRAYED);
76: break;
77:
78: }
79:
80:
81: Error:
82: return(hr);
83: }
但看MSDN实际要求的返回值是这样描述的:
Return Value
QueryContextMenu returns the number of items that were added to the context menu. The number of items added is also the maximum menu item ID offset (USHORT) in the code field (LOWORD) of the scode.
Note:
If there are gaps between menu items, the number is provided as if there were no gaps.
Remarks
The QueryContextMenu method can insert one or more new menu items into the specified menu hmenu, at the specified location indexMenu, with the IDs of those menu items. IDs must be in the range specified from idCmdFirst to idCmdLast. The QueryContextMenu method returns the maximum menu item ID offset (USHORT) in the code field (LOWORD) of the scode. The HIWORD is reserved for context specific communications, and the LOWORD is reserved for system use.
也就是说QueryContextMenu实际应该返回添加到context menu的个数,当然这个说法也并不准确,准确的说法应该是你添加菜单项的最大ID-idCmdFirst+1。 对于这个例子来说,应该做如下修改:
1: ///////////////////////////////////////////////////////////////////////////////
2: // QueryContextMenu - IContextMenu interface Method
3: //
4: // Adds the extra menu items to the context menu. This method is called when
5: // the menu which our menu extension is extended is being created
6: //
7: // Arguments:
8: // [IN] HMENU hmenu - a handle the menu to insert into
9: // [IN] UINT indexMenu - the position the item will be inserted after
10: // [IN] UINT idCmdFirst - the lowest possible ID for a new command to use
11: // [IN] UINT idCmdLast - the highest possible ID for a new command to use
12: // [IN] LPCTSTR szText - the menu text of the new item
13: // [IN] UINT uFlags - a set of flags indicating what type of insertion and
14: // extension is allowed. Please see the QueryContextMenu topic in the
15: // the SDK documentation for a complete list of these flags
16: // NOTE: The inbox application will only ever send CMF_NORMAL
17: //
18: //
19: // Return Values:
20: // HRESULT - S_OK on success else E_FAIL
21: //
22: HRESULT STDMETHODCALLTYPE MenuExtension::QueryContextMenu(HMENU hmenu,
23: UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
24: {
25: HRESULT hr = S_OK;
26: int nMaxId = 0;
27:
28: m_idc1 = idCmdFirst;
29: m_idc2 = idCmdFirst + 1;
30:
31: CBR(m_idc2 <= idCmdLast);
32:
33: BOOL fEnableItem;
34: TCHAR szItemName[30];
35: switch(m_ExtensionType)
36: {
37: case Context:
38: // Get item text
39: hr = GetCommandStringHelper(m_idc1, szItemName, ARRAYSIZE(szItemName));
40: CHR(hr);
41:
42: // Insert the item
43: hr = InsertMenuItem(hmenu, indexMenu, m_idc1, szItemName);
44: CHR(hr);
45:
46: // Determine if we are in an appropriate folder and
47: // have only a SINGLE item selected
48: // if NOT - then gray out this menu option
49: fEnableItem = EnableAddSenderToContacts();
50: ::EnableMenuItem(hmenu, m_idc1, fEnableItem ? MF_ENABLED : MF_GRAYED);
51: nMaxId = m_idc1;
52:
53: break;
54:
55: case Softkey:
56:
57: // Get item text
58: hr = GetCommandStringHelper(m_idc1, szItemName, ARRAYSIZE(szItemName));
59: CHR(hr);
60:
61: // Insert the item
62: hr = InsertMenuItem(hmenu, indexMenu, m_idc1, szItemName);
63: CHR(hr);
64:
65: // Get item text
66: hr = GetCommandStringHelper(m_idc2, szItemName, ARRAYSIZE(szItemName));
67: CHR(hr);
68:
69: // Insert the item
70: hr = InsertMenuItem(hmenu, indexMenu, m_idc2, szItemName);
71: CHR(hr);
72:
73: // Determine if there are items in the ListView
74: // if there are no items - then gray out these menu options
75: fEnableItem = AreThereMessagesInFolder();
76: ::EnableMenuItem(hmenu, m_idc1, fEnableItem ? MF_ENABLED : MF_GRAYED);
77: ::EnableMenuItem(hmenu, m_idc2, fEnableItem ? MF_ENABLED : MF_GRAYED);
78: nMaxId = m_idc2;
79: break;
80:
81: }
82:
83:
84: Error:
85: //Return max item offset inserted.
86: if(nMaxId == 0)
87: return 0;
88: else
89: return (nMaxId - idCmdFirst + 1);
90: // return(hr);
91: }
以下是我设想的系统实现原理:
1. 系统收件箱(tmail.exe)遍历注册表中所有的插件,获得所有的插件全路径。然后按照顺序访问插件。
2. tmail.exe查询插件1的IContextMenu接口,创建IContextMenu接口实例。
3.tmail.exe调用IContextMenu::QueryContextMenu接口,idCmdFirst和idCmdLast为预设值。设返回值为N,tmail.exe会将idCmdFirst~idCmdFirst+N-1分配给插件1。下次调插件2时的idCmdFirst=idCmdFirst(插件1)+N。
4. 当菜单选项被触发时,tmail.exe会根据触发的菜单ID找到对应的插件,然后调用该插件的IContextMenu::InvokeCommand接口。
几点说明:
1. 如果只有一个插件,那么不管QueryContextMenu返回任何值,只要是选择自定义的菜单,这个插件的InvokeCommand一定会被触发。
2. 如果同时挂多个插件同时其中一个插件的QueryContextMenu返回值是0,那么后面的插件会覆盖前一个的菜单项,前一个插件永远不会被调用InvokeCommand。
- WM5 SDK Sample InboxMenuExtensibility的一个BUG
- cuda的sdk sample中的一个低级错误
- 百度地图android sdk的一个bug
- directshow的"hello world"(from sdk sample)
- Android sdk下的sample应用学习
- SDK的vlan bug
- 一个Android Sample的总结
- Series 60 SDK for Symbian OS Nokia Edition SDK v1.2 的一个BUG
- mobile Wm5.0 6.0 SDK 及模拟器
- docset文件,aviary sdk,一个bug
- @微信SDK开发者,发现一个BUG~
- DirectX SDK Sample编译
- android SDK sample说明
- Android SDK Sample
- 运行SDK中带的sample的简单方法
- 如何把一个ppc2003的project移植到wm5.0/wm.6.0下
- Shadow Map在DirectX9.0 SDK Sample 的实现方法
- Shadow Map在DirectX9.0 SDK Sample 的实现方法
- 《Android Property>>
- C8051F930 SmartRTC使用
- The Twin Towers
- Vector容器
- 在CStatic静态文本框中,显示位图,控制位图大小
- WM5 SDK Sample InboxMenuExtensibility的一个BUG
- SQL Server Compact Edition 与SQL Server 2005数据同步之发布和订阅
- 运用RUP 4+1视图方法进行软件架构设计
- 抽象类和接口的比较
- Fzu 1683
- MFC中易混淆的字符串指针
- 表单上传文件时,不能获取表单中字段解决方法
- [转]: 读者写者问题(读写锁问题)
- 4*4的键盘矩阵