sfvmenu.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 14k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //*******************************************************************************************
  2. //
  3. // Filename : SFVMenu.cpp
  4. //
  5. // Implementation file for CSFView menu related methods
  6. //
  7. // Copyright (c) 1994 - 1996 Microsoft Corporation. All rights reserved
  8. //
  9. //*******************************************************************************************
  10. #include "Pch.H"
  11. #include "SFView.H"
  12. #include "SFVWnd.H"
  13. #include "Resource.H"
  14. enum
  15. {
  16. SUBMENU_EDIT,
  17. SUBMENU_VIEW,
  18. } ;
  19. enum
  20. {
  21. SUBMENUNF_EDIT,
  22. SUBMENUNF_VIEW,
  23. } ;
  24. static HMENU _GetMenuFromID(HMENU hmMain, UINT uID)
  25. {
  26. MENUITEMINFO miiSubMenu;
  27. miiSubMenu.cbSize = sizeof(MENUITEMINFO);
  28. miiSubMenu.fMask  = MIIM_SUBMENU;
  29. miiSubMenu.cch = 0;     // just in case
  30. if (!GetMenuItemInfo(hmMain, uID, FALSE, &miiSubMenu))
  31. {
  32. return NULL;
  33. }
  34. return(miiSubMenu.hSubMenu);
  35. }
  36. static int _GetOffsetFromID(HMENU hmMain, UINT uID)
  37. {
  38. int index;
  39. for (index = GetMenuItemCount(hmMain)-1; index>=0; index--)
  40. {
  41. MENUITEMINFO mii;
  42. mii.cbSize = sizeof(MENUITEMINFO);
  43. mii.fMask = MIIM_ID;
  44. mii.cch = 0; // just in case
  45. if (GetMenuItemInfo(hmMain, (UINT)index, TRUE, &mii)
  46. && (mii.wID == FCIDM_MENU_VIEW_SEP_OPTIONS))
  47. {
  48. // merge it right above the separator.
  49. break;
  50. }
  51. }
  52. return(index);
  53. }
  54. int CSFView::GetMenuIDFromViewMode()
  55. {
  56. switch (m_fs.ViewMode)
  57. {
  58. case FVM_SMALLICON:
  59. return(IDC_VIEW_SMALLICON);
  60. case FVM_LIST:
  61. return(IDC_VIEW_LIST);
  62. case FVM_DETAILS:
  63. return(IDC_VIEW_DETAILS);
  64. default:
  65. return(IDC_VIEW_ICON);
  66. }
  67. }
  68. BOOL CSFView::GetArrangeText(int iCol, UINT idFmt, LPSTR pszText, UINT cText)
  69. {
  70. char szFormat[200];
  71. LoadString(g_ThisDll.GetInstance(), idFmt, szFormat, sizeof(szFormat));
  72. LV_COLUMN col;
  73. char szText[80];
  74. col.mask = LVCF_TEXT;
  75. col.pszText = szText;
  76. col.cchTextMax = sizeof(szText);
  77. if (!m_cView.GetColumn(iCol, &col))
  78. {
  79. return(FALSE);
  80. }
  81. char szCommand[sizeof(szFormat)+sizeof(szText)];
  82. wsprintf(szCommand, szFormat, szText);
  83. lstrcpyn(pszText, szCommand, cText);
  84. return(TRUE);
  85. }
  86. void CSFView::MergeArrangeMenu(HMENU hmView)
  87. {
  88. // Now add the sorting menu items
  89. for (int i=0; i<MAX_COL; ++i)
  90. {
  91. MENUITEMINFO mii;
  92. mii.cbSize = sizeof(mii);
  93. char szCommand[100];
  94. if (!GetArrangeText(i, IDS_BYCOL_FMT, szCommand, sizeof(szCommand)))
  95. {
  96. mii.fMask = MIIM_TYPE;
  97. mii.fType = MFT_SEPARATOR;
  98. InsertMenuItem(hmView, IDC_ARRANGE_AUTO, FALSE, &mii);
  99. break;
  100. }
  101. mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
  102. mii.fType = MFT_STRING;
  103. mii.fState = MF_ENABLED;
  104. mii.wID = IDC_ARRANGE_BY + i;
  105. mii.dwTypeData = szCommand;
  106. InsertMenuItem(hmView, IDC_ARRANGE_AUTO, FALSE, &mii);
  107. }
  108. }
  109. void CSFView::MergeViewMenu(HMENU hmenu, HMENU hmMerge)
  110. {
  111. HMENU hmView = _GetMenuFromID(hmenu, FCIDM_MENU_VIEW);
  112. if (!hmView)
  113. {
  114. return;
  115. }
  116. int iOptions = _GetOffsetFromID(hmView, FCIDM_MENU_VIEW_SEP_OPTIONS);
  117. Cab_MergeMenus(hmView, hmMerge, (UINT)iOptions, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
  118. MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR);
  119. MergeArrangeMenu(hmView);
  120. }
  121. //*****************************************************************************
  122. //
  123. // CSFView::OnActivate
  124. //
  125. // Purpose:
  126. //
  127. //        handles the UIActivate call by ShellBrowser
  128. //
  129. // Parameters:
  130. //
  131. //    UINT  uState    -    UIActivate flag
  132. //
  133. // Comments:
  134. //
  135. //*****************************************************************************
  136. BOOL CSFView::OnActivate(UINT uState)
  137. {
  138. if (m_uState == uState)
  139. {
  140. return(TRUE);
  141. }
  142. OnDeactivate();
  143. {
  144. // Scope cMenu
  145. CMenuTemp cMenu(CreateMenu());
  146. if (!((HMENU)cMenu))
  147. {
  148. return(TRUE);
  149. }
  150. OLEMENUGROUPWIDTHS mwidth = { { 0, 0, 0, 0, 0, 0 } };
  151.         
  152. // insert menus into the shell browser
  153. // Explorer returns the wrong value so don't check
  154. m_psb->InsertMenusSB(cMenu, &mwidth);
  155.         
  156. // store this current menu 
  157. m_cmCur.Attach(cMenu.Detach());
  158. }
  159. // Get the edit menu in the browser
  160. HMENU hmEdit = _GetMenuFromID(m_cmCur, FCIDM_MENU_EDIT);
  161. if (uState == SVUIA_ACTIVATE_FOCUS)
  162. {
  163. // load the menu resource
  164. CMenuTemp cmMerge(LoadMenu(g_ThisDll.GetInstance(),
  165. MAKEINTRESOURCE(MENU_SFV_MAINMERGE)));
  166. if ((HMENU)cmMerge)
  167. {
  168. // merge it with Edit submenu
  169. Cab_MergeMenus(hmEdit, GetSubMenu(cmMerge, SUBMENU_EDIT), (UINT)-1,
  170. FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, MM_ADDSEPARATOR | MM_SUBMENUSHAVEIDS);
  171. // add the view menu
  172. MergeViewMenu(m_cmCur, GetSubMenu(cmMerge, SUBMENU_VIEW));
  173. }
  174. }
  175. else
  176. {
  177. CMenuTemp cmMerge(LoadMenu(g_ThisDll.GetInstance(),
  178. MAKEINTRESOURCE(MENU_SFV_MAINMERGENF)));
  179. if ((HMENU)cmMerge)
  180. {
  181. Cab_MergeMenus(hmEdit, GetSubMenu(cmMerge, SUBMENUNF_EDIT), (UINT)-1,
  182. FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, MM_ADDSEPARATOR | MM_SUBMENUSHAVEIDS);
  183. // view menu
  184. MergeViewMenu(m_cmCur, GetSubMenu(cmMerge, SUBMENUNF_VIEW));
  185. }
  186. }
  187. // install the composite menu into the shell browser
  188. m_psb->SetMenuSB(m_cmCur, NULL, m_cView);
  189. m_uState = uState;
  190. return TRUE;
  191. }
  192. BOOL CSFView::OnDeactivate()
  193. {
  194. if (m_uState != SVUIA_DEACTIVATE)
  195. {
  196. m_psb->SetMenuSB(NULL, NULL, NULL);
  197. m_psb->RemoveMenusSB(m_cmCur);
  198. DestroyMenu(m_cmCur.Detach());
  199. m_uState = SVUIA_DEACTIVATE;
  200. }
  201. return TRUE;
  202. }
  203. //*****************************************************************************
  204. //
  205. // CSFView::OnCommand
  206. //
  207. // Purpose:
  208. //
  209. //       handle the WM_COMMAND sent by the explorer to the view
  210. //
  211. // Comments:
  212. //
  213. //*****************************************************************************
  214. void CSFView::OnCommand(IContextMenu *pcm, WPARAM wParam, LPARAM lParam)
  215. {
  216. if (!pcm)
  217. {
  218. pcm = m_pcmSel;
  219. }
  220. if (pcm)
  221. {
  222. pcm->AddRef();
  223. }
  224. CEnsureRelease erContext(pcm);
  225. int idCmd = GET_WM_COMMAND_ID(wParam, lParam);
  226. DWORD dwStyle;
  227. switch (idCmd)
  228. {
  229.     // Set the FOLDERSETTINGS for this view
  230. case IDC_VIEW_ICON + FCIDM_SHVIEWFIRST:
  231. dwStyle = LVS_ICON;
  232. m_fs.ViewMode = FVM_ICON;
  233. goto SetStyle;
  234. case IDC_VIEW_SMALLICON + FCIDM_SHVIEWFIRST:
  235. dwStyle = LVS_SMALLICON;
  236. m_fs.ViewMode = FVM_SMALLICON;
  237. goto SetStyle;
  238. case IDC_VIEW_LIST + FCIDM_SHVIEWFIRST:
  239. dwStyle = LVS_LIST;
  240. m_fs.ViewMode = FVM_LIST;
  241. goto SetStyle;
  242. case IDC_VIEW_DETAILS + FCIDM_SHVIEWFIRST:
  243. dwStyle = LVS_REPORT;
  244. m_fs.ViewMode = FVM_DETAILS;
  245. goto SetStyle;
  246. // set the style of the Listview accordingly
  247. SetStyle:
  248. m_cView.SetStyle(dwStyle, LVS_TYPEMASK);
  249. CheckToolbar();
  250. break;
  251. // handle the Copy operation
  252. case IDC_EDIT_COPY + FCIDM_SHVIEWFIRST:
  253. {
  254. LPDATAOBJECT pdtobj;
  255. if (!m_cView.OleInited()
  256. || FAILED(m_cView.GetUIObjectFromItem(IID_IDataObject, (LPVOID*)&pdtobj,
  257. SVGIO_SELECTION)))
  258. {
  259. MessageBeep(0);
  260. break;
  261. }
  262. CEnsureRelease erData(pdtobj);
  263. OleSetClipboard(pdtobj);
  264. break;
  265. }
  266.     // handle selection of items
  267. case IDC_EDIT_SELALL + FCIDM_SHVIEWFIRST:
  268. SetFocus(m_cView);
  269. m_cView.SelAll();
  270. break;
  271. case IDC_EDIT_INVSEL + FCIDM_SHVIEWFIRST:
  272. SetFocus(m_cView);
  273. m_cView.InvSel();
  274. break;
  275. default:
  276. if (idCmd>=IDC_ARRANGE_BY && idCmd<IDC_ARRANGE_BY+MAX_COL)
  277. {
  278. ColumnClick(idCmd - IDC_ARRANGE_BY);
  279. }
  280. else if (pcm && idCmd>=SFV_CONTEXT_FIRST && idCmd<=SFV_CONTEXT_LAST)
  281. {
  282. // invoke the context menu
  283. CMINVOKECOMMANDINFO ici;
  284. ici.cbSize = sizeof(ici);
  285. ici.fMask = 0;
  286. ici.hwnd = m_hwndMain;
  287. ici.lpVerb = MAKEINTRESOURCE(idCmd - SFV_CONTEXT_FIRST);
  288. ici.lpParameters = NULL;
  289. ici.lpDirectory = NULL;
  290. ici.nShow = SW_SHOWNORMAL;
  291. pcm->InvokeCommand(&ici);
  292. }
  293. break;
  294. }
  295. }
  296. IContextMenu * CSFView::GetSelContextMenu()
  297. {
  298. if (!m_pcmSel)
  299. {
  300. if (FAILED(m_cView.GetUIObjectFromItem(IID_IContextMenu, (LPVOID *)&m_pcmSel,
  301. SVGIO_SELECTION)))
  302. {
  303. m_pcmSel = NULL;
  304. return(m_pcmSel);
  305. }
  306. }
  307. m_pcmSel->AddRef();
  308. return(m_pcmSel);
  309. }
  310. void CSFView::ReleaseSelContextMenu()
  311. {
  312. if (m_pcmSel)
  313. {
  314. m_pcmSel->Release();
  315. m_pcmSel = NULL;
  316. }
  317. }
  318. void CSFView::InitFileMenu(HMENU hmInit)
  319. {
  320. //
  321. // Don't touch the file menu unless we have the focus.
  322. //
  323. if (m_uState != SVUIA_ACTIVATE_FOCUS)
  324. {
  325. return;
  326. }
  327. BOOL bDeleteItems = FALSE;
  328. int i;
  329. // Remove all the menu items we've added.
  330. for (i = GetMenuItemCount(hmInit) - 1; i >= 0; --i)
  331. {
  332. if (!bDeleteItems)
  333. {
  334. MENUITEMINFO mii;
  335. mii.cbSize = sizeof(mii);
  336. mii.fMask = MIIM_ID;
  337. mii.cch = 0;     // just in case
  338. if (GetMenuItemInfo(hmInit, i, TRUE, &mii))
  339. {
  340. if (mii.wID>=SFV_CONTEXT_FIRST && mii.wID<=SFV_CONTEXT_LAST)
  341. {
  342. bDeleteItems = TRUE;
  343. }
  344. }
  345. }
  346. if (bDeleteItems)
  347. {
  348. DeleteMenu(hmInit, i, MF_BYPOSITION);
  349. }
  350. }
  351. // Let the object add the separator.
  352. if (CSFViewDlg::IsMenuSeparator(hmInit, 0))
  353. {
  354. DeleteMenu(hmInit, 0, MF_BYPOSITION);
  355. }
  356. //
  357. // Now add item specific commands to the menu
  358. // This is done by seeing if we already have a context menu
  359. // object for our selection.  If not we generate it now.
  360. //
  361. IContextMenu *pcmSel = GetSelContextMenu();
  362. if (pcmSel)
  363. {
  364. pcmSel->QueryContextMenu(hmInit, 0, SFV_CONTEXT_FIRST,
  365. SFV_CONTEXT_LAST, CMF_DVFILE);
  366. pcmSel->Release();
  367. }
  368. // Note that the SelContextMenu stays around until the selection changes or we
  369. // close the window, but it doesn't really matter that much
  370. }
  371. void CSFView::InitEditMenu(HMENU hmInit)
  372. {
  373. ULONG dwAttr = SFGAO_CANCOPY;
  374. UINT uFlags = (m_cView.OleInited()
  375. && SUCCEEDED(m_cView.GetAttributesFromItem(&dwAttr, SVGIO_SELECTION))
  376. && (dwAttr & SFGAO_CANCOPY)) ? MF_ENABLED : MF_GRAYED;
  377. EnableMenuItem(hmInit, IDC_EDIT_COPY + FCIDM_SHVIEWFIRST, uFlags | MF_BYCOMMAND);
  378. }
  379. void CSFView::InitViewMenu(HMENU hmInit)
  380. {
  381. int iCurViewMenuItem = GetMenuIDFromViewMode() + FCIDM_SHVIEWFIRST;
  382. UINT uEnable;
  383. CheckMenuRadioItem(hmInit, IDC_VIEW_ICON, IDC_VIEW_DETAILS,
  384. iCurViewMenuItem, MF_BYCOMMAND | MF_CHECKED);
  385. uEnable = (iCurViewMenuItem==IDC_VIEW_LIST+FCIDM_SHVIEWFIRST 
  386. || iCurViewMenuItem==IDC_VIEW_DETAILS+FCIDM_SHVIEWFIRST) ?
  387. (MF_GRAYED | MF_BYCOMMAND)  :  (MF_ENABLED | MF_BYCOMMAND);
  388. uEnable = MF_GRAYED | MF_BYCOMMAND;
  389. EnableMenuItem(hmInit, IDC_ARRANGE_GRID + FCIDM_SHVIEWFIRST, uEnable);
  390. EnableMenuItem(hmInit, IDC_ARRANGE_AUTO + FCIDM_SHVIEWFIRST, uEnable);
  391. CheckMenuItem(hmInit, IDC_ARRANGE_AUTO + FCIDM_SHVIEWFIRST,
  392. ((uEnable == (MF_ENABLED | MF_BYCOMMAND)) && (m_fs.fFlags & FWF_AUTOARRANGE))
  393. ? MF_CHECKED : MF_UNCHECKED);
  394. }
  395. //*****************************************************************************
  396. //
  397. // CSFView::OnInitMenuPopup
  398. //
  399. // Purpose:
  400. //
  401. //    handle the WM_INITMENUPOPUP message received by CSFViewDlg
  402. //
  403. //
  404. //*****************************************************************************
  405. BOOL CSFView::OnInitMenuPopup(HMENU hmInit, int nIndex, BOOL fSystemMenu)
  406. {
  407. if (!(HMENU)m_cmCur)
  408. {
  409. return(TRUE);
  410. }
  411. MENUITEMINFO mii;
  412. mii.cbSize = sizeof(MENUITEMINFO);
  413. mii.fMask = MIIM_SUBMENU|MIIM_ID;
  414. mii.cch = 0;     // just in case
  415. if (!GetMenuItemInfo(m_cmCur, nIndex, TRUE, &mii) || mii.hSubMenu!=hmInit)
  416. {
  417. return(TRUE);
  418. }
  419. switch (mii.wID)
  420. {
  421. case FCIDM_MENU_FILE:
  422. InitFileMenu(hmInit);
  423. break;
  424. case FCIDM_MENU_EDIT:
  425. InitEditMenu(hmInit);
  426. break;
  427. case FCIDM_MENU_VIEW:
  428. InitViewMenu(hmInit);
  429. break;
  430. default:
  431. return 1L;
  432. }
  433. return 0L;
  434. }
  435. int _FindIt(const UINT *puFirst, UINT uFind, UINT uStep, int cCount)
  436. {
  437. LPBYTE pbFirst = (LPBYTE)puFirst;
  438. for (--cCount, pbFirst+=cCount*uStep; cCount>=0; --cCount, pbFirst-=uStep)
  439. {
  440. if (*(UINT *)pbFirst == uFind)
  441. {
  442. break;
  443. }
  444. }
  445. return(cCount);
  446. }
  447. const struct
  448. {
  449. UINT idCmd;
  450. UINT idStr;
  451. UINT idTT;
  452. } c_idTbl[] =
  453. {
  454. IDC_VIEW_ICON, IDS_VIEW_ICON, IDS_TT_VIEW_ICON,
  455. IDC_VIEW_SMALLICON, IDS_VIEW_SMALLICON, IDS_TT_VIEW_SMALLICON,
  456. IDC_VIEW_LIST, IDS_VIEW_LIST, IDS_TT_VIEW_LIST,
  457. IDC_VIEW_DETAILS, IDS_VIEW_DETAILS, IDS_TT_VIEW_DETAILS,
  458. IDC_EDIT_COPY, IDS_EDIT_COPY, IDS_TT_EDIT_COPY,
  459. IDC_EDIT_SELALL, IDS_EDIT_SELALL, 0,
  460. IDC_EDIT_INVSEL, IDS_EDIT_INVSEL, 0,
  461. IDC_ARRANGE_GRID, IDS_ARRANGE_GRID, 0,
  462. IDC_ARRANGE_AUTO, IDS_ARRANGE_AUTO, 0,
  463. } ;
  464. void CSFView::GetCommandHelpText(UINT idCmd, LPSTR pszText, UINT cchText, BOOL bToolTip)
  465. {
  466. *pszText = 0;
  467. if (idCmd>=SFV_CONTEXT_FIRST && idCmd<=SFV_CONTEXT_LAST && m_pcmSel)
  468. {
  469. if (bToolTip)
  470. {
  471. return;
  472. }
  473. m_pcmSel->GetCommandString(idCmd - SFV_CONTEXT_FIRST, GCS_HELPTEXT, NULL,
  474. pszText, cchText);
  475. }
  476. else if (idCmd>=IDC_ARRANGE_BY && idCmd<IDC_ARRANGE_BY+MAX_COL)
  477. {
  478. if (bToolTip)
  479. {
  480. return;
  481. }
  482. GetArrangeText(idCmd-IDC_ARRANGE_BY, IDS_BYCOL_HELP_FMT, pszText, cchText);
  483. }
  484. else
  485. {
  486. int iid = _FindIt(&c_idTbl[0].idCmd, idCmd-FCIDM_SHVIEWFIRST, sizeof(c_idTbl[0]),
  487. ARRAYSIZE(c_idTbl));
  488. if (iid >= 0)
  489. {
  490. LoadString(g_ThisDll.GetInstance(),
  491. bToolTip ? c_idTbl[iid].idTT : c_idTbl[iid].idStr, pszText, cchText);
  492. }
  493. }
  494. }
  495. LRESULT CSFView::OnMenuSelect(UINT idCmd, UINT uFlags, HMENU hmenu)
  496. {
  497. // If we dismissed the menu restore our status bar...
  498. if (!hmenu && LOWORD(uFlags)==0xffff)
  499. {
  500. m_psb->SendControlMsg(FCW_STATUS, SB_SIMPLE, 0, 0L, NULL);
  501. return 0L;
  502. }
  503. if (uFlags & (MF_SYSMENU | MF_SEPARATOR))
  504. {
  505. return 0L;
  506. }
  507. char szHelpText[80 + 2*MAX_PATH];
  508. szHelpText[0] = 0;   // in case of failures below
  509. if (uFlags & MF_POPUP)
  510. {
  511. MENUITEMINFO miiSubMenu;
  512. miiSubMenu.cbSize = sizeof(MENUITEMINFO);
  513. miiSubMenu.fMask = MIIM_ID;
  514. miiSubMenu.cch = 0;     // just in case
  515. if (!GetMenuItemInfo(hmenu, idCmd, TRUE, &miiSubMenu))
  516. {
  517. return 0;
  518. }
  519. // Change the parameters to simulate a "normal" menu item
  520. idCmd = miiSubMenu.wID;
  521. uFlags &= ~MF_POPUP;
  522. }
  523. GetCommandHelpText(idCmd, szHelpText, sizeof(szHelpText), FALSE);
  524. m_psb->SendControlMsg(FCW_STATUS, SB_SETTEXT, SBT_NOBORDERS | 255,
  525. (LPARAM)szHelpText, NULL);
  526. m_psb->SendControlMsg(FCW_STATUS, SB_SIMPLE, 1, 0L, NULL);
  527. return 0;
  528. }