Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

389 lines
8.9 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. SakMenu.cpp
  5. Abstract:
  6. Implements all the context menu interface to the individual nodes,
  7. including getting menu resources and turning into MMC menus, and
  8. forwarding on command messages.
  9. Author:
  10. Rohde Wakefield [rohde] 09-Dec-1996
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "CSakData.h"
  15. #include "CSakSnap.h"
  16. //
  17. // Mask for a long value out of a short value's range
  18. //
  19. #define SHORT_VALUE_RANGE (MAXULONG ^ ((unsigned short)MAXSHORT))
  20. static HRESULT
  21. AddMmcMenuItems (
  22. IN CMenu * pMenu,
  23. IN LONG lInsertionPointID,
  24. IN ISakNode * pNode,
  25. IN IContextMenuCallback * pContextMenuCallback
  26. )
  27. /*++
  28. Routine Description:
  29. Called for any node clicked on with right mouse. Goes to the
  30. node object to construct the MMC menu.
  31. Arguments:
  32. pDataObject - identifies the node to be worked on.
  33. pContextMenuCallback - The MMC menu interface to use.
  34. Return Value:
  35. S_OK - All added fine - continue.
  36. E_UNEXPECTED - Some error occurred.
  37. --*/
  38. {
  39. WsbTraceIn( L"AddMmcMenuItems", L"lInsertionPointID = <0x%p>, pNode = <0x%p>", lInsertionPointID, pNode );
  40. HRESULT hr = S_OK;
  41. try {
  42. //
  43. // It is ok to pass a NULL pMenu - means do not add
  44. // any entries
  45. //
  46. if ( 0 != pMenu ) {
  47. CString menuText;
  48. CString statusText;
  49. BSTR bstr;
  50. CONTEXTMENUITEM menuItem;
  51. memset ( (void*)&menuItem, 0, sizeof ( menuItem ) );
  52. menuItem.lInsertionPointID = lInsertionPointID;
  53. UINT menuCount = pMenu->GetMenuItemCount ( );
  54. for ( UINT index = 0; index < menuCount; index++ ) {
  55. //
  56. // For each menu item, fill out MMC's CONTEXTMENUITEM struct
  57. // appropriately and call AddItem
  58. //
  59. menuItem.lCommandID = pMenu->GetMenuItemID ( index );
  60. pMenu->GetMenuString ( index, menuText, MF_BYPOSITION );
  61. menuItem.strName = (LPTSTR)(LPCTSTR)menuText;
  62. WsbAffirmHr ( pNode->GetMenuHelp ( menuItem.lCommandID, &bstr ) );
  63. if ( 0 != bstr ) {
  64. statusText = bstr;
  65. SysFreeString ( bstr );
  66. menuItem.strStatusBarText = (LPTSTR)(LPCTSTR)statusText;
  67. } else {
  68. menuItem.strStatusBarText = 0;
  69. }
  70. menuItem.fFlags = pMenu->GetMenuState ( index, MF_BYPOSITION );
  71. menuItem.fSpecialFlags = 0;
  72. //
  73. // Since AppStudio does not make available the MFS_DEFUALT flag,
  74. // we will use the MF_HELP flag for default entry.
  75. //
  76. if ( 0 != ( menuItem.fFlags & MF_HELP ) ) {
  77. menuItem.fFlags &= ~MF_HELP;
  78. menuItem.fSpecialFlags |= CCM_SPECIAL_DEFAULT_ITEM;
  79. }
  80. pContextMenuCallback->AddItem ( &menuItem );
  81. }
  82. }
  83. } WsbCatch ( hr );
  84. WsbTraceOut( L"AddMmcMenuItems", L"hr = <%ls>", WsbHrAsString( hr ) );
  85. return ( hr );
  86. }
  87. STDMETHODIMP
  88. CSakData::AddMenuItems (
  89. IN LPDATAOBJECT pDataObject,
  90. IN LPCONTEXTMENUCALLBACK pContextMenuCallback,
  91. OUT LONG* pInsertionAllowed
  92. )
  93. /*++
  94. Routine Description:
  95. Called for any node clicked on with right mouse. Goes to the
  96. node object to construct the MMC menu.
  97. Arguments:
  98. pDataObject - identifies the node to be worked on.
  99. pContextMenuCallback - The MMC menu interface to use.
  100. Return Value:
  101. S_OK - All added fine - continue.
  102. E_UNEXPECTED - Some error occurred.
  103. --*/
  104. {
  105. WsbTraceIn( L"CSakData::AddMenuItems", L"pDataObject = <0x%p>", pDataObject );
  106. HRESULT hr = S_OK;
  107. BOOL bMultiSelect;
  108. try {
  109. //
  110. // Note - snap-ins need to look at the data object and determine
  111. // in what context, menu items need to be added.
  112. // We should be expecting either single data object or Multi-Select
  113. // data object. Not Object Types data object.
  114. //
  115. CComPtr<ISakNode> pNode;
  116. CComPtr<IEnumGUID> pEnumObjectId;
  117. WsbAffirmHr( GetBaseHsmFromDataObject( pDataObject, &pNode, &pEnumObjectId ) );
  118. bMultiSelect = pEnumObjectId ? TRUE : FALSE;
  119. CMenu menu;
  120. HMENU hMenu;
  121. WsbAffirmHr( pNode->GetContextMenu ( bMultiSelect, &hMenu ) );
  122. menu.Attach( hMenu );
  123. //
  124. // Any menu returned by GetContextMenu should have three
  125. // top-level popups for the following portions of the
  126. // MMC context menu:
  127. //
  128. // 1. Root (Above all other items)
  129. // 2. Create New
  130. // 3. Task
  131. //
  132. // If any of these should not have any items added for them,
  133. // the top-level item should not be a pop (sans MF_POPUP)
  134. //
  135. if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TOP ) {
  136. WsbAffirmHr ( AddMmcMenuItems ( menu.GetSubMenu ( MENU_INDEX_ROOT ),
  137. CCM_INSERTIONPOINTID_PRIMARY_TOP, pNode, pContextMenuCallback ) );
  138. }
  139. if( *pInsertionAllowed & CCM_INSERTIONALLOWED_NEW ) {
  140. WsbAffirmHr ( AddMmcMenuItems ( menu.GetSubMenu ( MENU_INDEX_NEW ),
  141. CCM_INSERTIONPOINTID_PRIMARY_NEW, pNode, pContextMenuCallback ) );
  142. }
  143. if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TASK ) {
  144. WsbAffirmHr ( AddMmcMenuItems ( menu.GetSubMenu ( MENU_INDEX_TASK ),
  145. CCM_INSERTIONPOINTID_PRIMARY_TASK, pNode, pContextMenuCallback ) );
  146. }
  147. } WsbCatch ( hr );
  148. WsbTraceOut( L"CSakData::AddMenuItems", L"hr = <%ls>", WsbHrAsString( hr ) );
  149. return ( hr );
  150. }
  151. STDMETHODIMP
  152. CSakData::Command (
  153. IN long nCommandID,
  154. IN LPDATAOBJECT pDataObject
  155. )
  156. /*++
  157. Routine Description:
  158. Called for any node receiving a menu command. Goes to the
  159. node object to handle the command, and allows general
  160. (not node-specific) commands to be handled centrally.
  161. Arguments:
  162. nCommandID - ID of command.
  163. pDataObject - Data object representing the node.
  164. Return Value:
  165. S_OK - Handled.
  166. E_UNEXPECTED - Some error occurred.
  167. --*/
  168. {
  169. WsbTraceIn( L"CSakData::Command", L"nCommandID = <%ld>, pDataObject = <0x%p>", nCommandID, pDataObject );
  170. HRESULT hr = S_OK;
  171. try {
  172. HRESULT resultCommand = S_FALSE;
  173. //
  174. // All node commands are SHORT values. Check range first.
  175. //
  176. if ( 0 == ( nCommandID & SHORT_VALUE_RANGE ) ) {
  177. //
  178. // We start by getting the corresponding ISakNode interface
  179. // to the node
  180. //
  181. CComPtr<ISakNode> pNode;
  182. CComPtr<IEnumGUID> pEnumObjectId;
  183. WsbAffirmHr( GetBaseHsmFromDataObject ( pDataObject, &pNode, &pEnumObjectId ) );
  184. //
  185. // Then see if it wants to handle the command
  186. //
  187. WsbAffirmHr( ( resultCommand = pNode->InvokeCommand ( (SHORT)nCommandID, pDataObject ) ) );
  188. }
  189. } WsbCatch ( hr )
  190. WsbTraceOut( L"CSakData::Command", L"hr = <%ls>", WsbHrAsString( hr ) );
  191. return ( hr );
  192. }
  193. STDMETHODIMP
  194. CSakSnap::AddMenuItems (
  195. IN LPDATAOBJECT pDataObject,
  196. IN LPCONTEXTMENUCALLBACK pContextMenuCallback,
  197. OUT LONG* pInsertionAllowed
  198. )
  199. /*++
  200. Routine Description:
  201. Called for any node clicked on with right mouse in result pane.
  202. Delegates to CSakData.
  203. Arguments:
  204. pDataObject - identifies the node to be worked on.
  205. pContextMenuCallback - The MMC menu interface to use.
  206. Return Value:
  207. S_OK - All added fine - continue.
  208. E_UNEXPECTED - Some error occurred.
  209. --*/
  210. {
  211. WsbTraceIn( L"CSakSnap::AddMenuItems", L"pDataObject = <0x%p>", pDataObject );
  212. HRESULT hr = S_OK;
  213. try {
  214. WsbAffirmHr( m_pSakData->AddMenuItems( pDataObject, pContextMenuCallback, pInsertionAllowed ) );
  215. } WsbCatch( hr );
  216. WsbTraceOut( L"CSakSnap::AddMenuItems", L"hr = <%ls>", WsbHrAsString( hr ) );
  217. return( hr );
  218. }
  219. STDMETHODIMP
  220. CSakSnap::Command (
  221. IN long nCommandID,
  222. IN LPDATAOBJECT pDataObject
  223. )
  224. /*++
  225. Routine Description:
  226. Called for any node receiving a menu command.
  227. Delegated to CSakData.
  228. Arguments:
  229. nCommandID - ID of command.
  230. pDataObject - Data object representing the node.
  231. Return Value:
  232. S_OK - Handled.
  233. E_UNEXPECTED - Some error occurred.
  234. --*/
  235. {
  236. WsbTraceIn( L"CSakSnap::Command", L"nCommandID = <%ld>, pDataObject = <0x%p>", nCommandID, pDataObject );
  237. HRESULT hr;
  238. try {
  239. hr = m_pSakData->Command( nCommandID, pDataObject );
  240. } WsbCatch( hr );
  241. WsbTraceOut( L"CSakSnap::Command", L"hr = <%ls>", WsbHrAsString( hr ) );
  242. return( hr );
  243. }