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.

13328 lines
372 KiB

  1. // AMCView.cpp : implementation of the CAMCView class
  2. //
  3. //+-------------------------------------------------------------------------
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1999
  7. //
  8. // File: amcview.cpp
  9. //
  10. // Contents: Base view implementation for all console views
  11. // Also include splitter window implementation (Horizontal Splitter)
  12. //
  13. // History: 01-Jan-96 TRomano Created
  14. // 16-Jul-96 WayneSc Added code to switch views and split them
  15. //
  16. //--------------------------------------------------------------------------
  17. // NOTE:
  18. // MMC starting from version 1.1 had a code which allowed to copy the view
  19. // settings from one view to another and thus the created view would look
  20. // the same. AMCDoc was used as temporary storage for those settings.
  21. // But the code was NEVER used; hence was not tested and not up-to-date.
  22. // Switching to XML persistence would require essential changes to that code,
  23. // and at this time we cannot afford using it.
  24. // If in the future we decide to support the feature, someone needs to look at
  25. // MMC 1.2 sources and bring the code back. Today the code is removed from
  26. // active sources.
  27. // audriusz. 3/29/2000
  28. //--------------------------------------------------------------------------
  29. #include "stdafx.h"
  30. #include "AMC.h"
  31. #include "Mainfrm.h"
  32. #include "HtmlHelp.h"
  33. #include "websnk.h"
  34. #include "WebCtrl.h" // AMC Private implementation of the web view control
  35. #include "CClvCtl.h" // List view control
  36. #include "ocxview.h"
  37. #include "histlist.h" // history list
  38. #include "AMCDoc.h" // AMC Console Document
  39. #include "AMCView.h"
  40. #include "childfrm.h"
  41. #include "TreeCtrl.h" // AMC Implementation of the Tree Control
  42. #include "TaskHost.h"
  43. #include "util.h" // GUIDFromString, GUIDToString
  44. #include "AMCPriv.h"
  45. #include "guidhelp.h" // ExtractObjectTypeGUID
  46. #include "amcmsgid.h"
  47. #include "cclvctl.h"
  48. #include "vwtrack.h"
  49. #include "cmenuinfo.h"
  50. #ifdef IMPLEMENT_LIST_SAVE // See nodemgr.idl (t-dmarm)
  51. #include "svfildlg.h" // Save File Dialog
  52. #endif
  53. #include "macros.h"
  54. #include <mapi.h>
  55. #include <mbstring.h> // for _mbslen
  56. #include "favorite.h"
  57. #include "favui.h"
  58. #include "ftab.h"
  59. #include "toolbar.h"
  60. #include "menubtns.h" // UpdateFavorites menu.
  61. #include "stdbar.h" // Standard toolbar.
  62. #include "variant.h"
  63. #include "rsltitem.h"
  64. #include "scriptevents.h" // for IMenuItemEvents
  65. extern "C" UINT dbg_count = 0;
  66. enum
  67. {
  68. ITEM_IS_PARENT_OF_ROOT,
  69. ITEM_NOT_IN_VIEW,
  70. ITEM_IS_IN_VIEW,
  71. };
  72. enum EIndex
  73. {
  74. INDEX_INVALID = -1,
  75. INDEX_BACKGROUND = -2,
  76. INDEX_MULTISELECTION = -3,
  77. INDEX_OCXPANE = -4,
  78. INDEX_WEBPANE = -5,
  79. };
  80. enum ScopeFolderItems
  81. {
  82. SFI_TREE_TAB = 1,
  83. SFI_FAVORITES_TAB = 2
  84. };
  85. const UINT CAMCView::m_nShowWebContextMenuMsg = ::RegisterWindowMessage (_T("CAMCView::ShowWebContextMenu"));
  86. const UINT CAMCView::m_nProcessMultiSelectionChangesMsg = ::RegisterWindowMessage (_T("CAMCView::OnProcessMultiSelectionChanges"));
  87. const UINT CAMCView::m_nAddPageBreakAndNavigateMsg = ::RegisterWindowMessage (_T("CAMCView::AddPageBreakAndNavigate"));
  88. const UINT CAMCView::m_nJiggleListViewFocusMsg = ::RegisterWindowMessage (_T("CAMCView::JiggleListViewFocus"));
  89. const UINT CAMCView::m_nDeferRecalcLayoutMsg = ::RegisterWindowMessage (_T("CAMCView::DeferRecalcLayout"));
  90. void CALLBACK TrackerCallback(TRACKER_INFO& info, bool bAcceptChange, bool bSyncLayout);
  91. void GetFullPath(CAMCTreeView &ctc, HTREEITEM hti, CString &strPath);
  92. BOOL PtInWindow(CWnd* pWnd, CPoint pt);
  93. #ifdef DBG
  94. CTraceTag tagLayout (_T("CAMCView"), _T("Layout"));
  95. CTraceTag tagSplitterTracking (_T("CAMCView"), _T("Splitter tracking"));
  96. CTraceTag tagListSelection (_T("Result list"), _T("Selection"));
  97. CTraceTag tagViewActivation (_T("View Activation"), _T("View Activation"));
  98. #endif
  99. /*+-------------------------------------------------------------------------*
  100. * CAMCView::ScNotifySelect
  101. *
  102. *
  103. *--------------------------------------------------------------------------*/
  104. SC CAMCView::ScNotifySelect (
  105. INodeCallback* pCallback,
  106. HNODE hNode,
  107. bool fMultiSelect,
  108. bool fSelect,
  109. SELECTIONINFO* pSelInfo)
  110. {
  111. DECLARE_SC(sc, TEXT("CAMCView::ScNotifySelect"));
  112. // parameter check
  113. sc = ScCheckPointers(pCallback);
  114. if (sc)
  115. return sc;
  116. // pSelInfo can be NULL only for multi-select.
  117. if (!pSelInfo && !fMultiSelect)
  118. return (sc = E_INVALIDARG);
  119. #ifdef DBG
  120. Trace (tagListSelection, _T("%s (fSelect=%s, pwnd=0x%08x)"),
  121. (fMultiSelect) ? _T("NCLBK_MULTI_SELECT") : _T("NCLBK_SELECT"),
  122. (fSelect) ? _T("true") : _T("false"),
  123. static_cast<CWnd *>(this));
  124. #endif
  125. // we want this error (not a failure to broadcast the event) to be returned,
  126. // so cache it and assign before return
  127. SC sc_notify = (pCallback->Notify (hNode, fMultiSelect ? NCLBK_MULTI_SELECT :NCLBK_SELECT,
  128. fSelect, reinterpret_cast<LPARAM>(pSelInfo)));
  129. // fire event whenever the selection changes, but not if
  130. // its a background hit or loss of focus
  131. if(fMultiSelect ||
  132. (pSelInfo->m_bBackground == FALSE && (fSelect == TRUE || pSelInfo->m_bDueToFocusChange == FALSE)))
  133. {
  134. sc = ScFireEvent(CAMCViewObserver::ScOnResultSelectionChange, this);
  135. if (sc)
  136. sc.TraceAndClear(); // ignore & continue;
  137. }
  138. sc = sc_notify;
  139. return sc;
  140. }
  141. /*+-------------------------------------------------------------------------*
  142. * GetAMCView
  143. *
  144. * Returns the CAMCView window for any child of CChildFrame.
  145. *--------------------------------------------------------------------------*/
  146. CAMCView* GetAMCView (CWnd* pwnd)
  147. {
  148. /*
  149. * get the input window's parent frame window
  150. */
  151. CWnd* pFrame = pwnd->GetParentFrame();
  152. /*
  153. * if we couldn't find a parent frame, or that parent frame isn't
  154. * of type CChildFrame, fail
  155. */
  156. if ((pFrame == NULL) || !pFrame->IsKindOf (RUNTIME_CLASS (CChildFrame)))
  157. return (NULL);
  158. /*
  159. * get the first view of the frame window
  160. */
  161. CWnd* pView = pFrame->GetDlgItem (AFX_IDW_PANE_FIRST);
  162. /*
  163. * if we can't find a window with the right ID, or the one we find
  164. * isn't of type CAMCView, fail
  165. */
  166. if ((pView == NULL) || !pView->IsKindOf (RUNTIME_CLASS (CAMCView)))
  167. return (NULL);
  168. return (dynamic_cast<CAMCView*>(pView));
  169. }
  170. //############################################################################
  171. //############################################################################
  172. //
  173. // Implementation of class CMMCView
  174. //
  175. //############################################################################
  176. //############################################################################
  177. /*+-------------------------------------------------------------------------*
  178. * class CMMCView
  179. *
  180. *
  181. * PURPOSE: The COM 0bject that exposes the View interface.
  182. *
  183. *+-------------------------------------------------------------------------*/
  184. class CMMCView :
  185. public CTiedComObject<CAMCView>,
  186. public CMMCIDispatchImpl<View>
  187. {
  188. typedef CAMCView CMyTiedObject;
  189. public:
  190. BEGIN_MMC_COM_MAP(CMMCView)
  191. END_MMC_COM_MAP()
  192. public:
  193. //#######################################################################
  194. //#######################################################################
  195. //
  196. // Item and item collection related methods
  197. //
  198. //#######################################################################
  199. //#######################################################################
  200. MMC_METHOD1(get_ActiveScopeNode, PPNODE);
  201. MMC_METHOD1(put_ActiveScopeNode, PNODE);
  202. MMC_METHOD1(get_Selection, PPNODES);
  203. MMC_METHOD1(get_ListItems, PPNODES);
  204. MMC_METHOD2(SnapinScopeObject, VARIANT, PPDISPATCH);
  205. MMC_METHOD1(SnapinSelectionObject, PPDISPATCH);
  206. //#######################################################################
  207. //#######################################################################
  208. MMC_METHOD2(Is, PVIEW, VARIANT_BOOL *);
  209. MMC_METHOD1(get_Document, PPDOCUMENT);
  210. //#######################################################################
  211. //#######################################################################
  212. //
  213. // Selection changing methods
  214. //
  215. //#######################################################################
  216. //#######################################################################
  217. MMC_METHOD0(SelectAll);
  218. MMC_METHOD1(Select, PNODE);
  219. MMC_METHOD1(Deselect, PNODE);
  220. MMC_METHOD2(IsSelected, PNODE, PBOOL);
  221. //#######################################################################
  222. //#######################################################################
  223. //
  224. // Verb and selection related methods
  225. //
  226. //#######################################################################
  227. //#######################################################################
  228. MMC_METHOD1(DisplayScopeNodePropertySheet, VARIANT);
  229. MMC_METHOD0(DisplaySelectionPropertySheet);
  230. MMC_METHOD1(CopyScopeNode, VARIANT);
  231. MMC_METHOD0(CopySelection);
  232. MMC_METHOD1(DeleteScopeNode, VARIANT);
  233. MMC_METHOD0(DeleteSelection);
  234. MMC_METHOD2(RenameScopeNode, BSTR, VARIANT);
  235. MMC_METHOD1(RenameSelectedItem, BSTR);
  236. MMC_METHOD2(get_ScopeNodeContextMenu,VARIANT, PPCONTEXTMENU);
  237. MMC_METHOD1(get_SelectionContextMenu,PPCONTEXTMENU);
  238. MMC_METHOD1(RefreshScopeNode, VARIANT);
  239. MMC_METHOD0(RefreshSelection);
  240. MMC_METHOD1(ExecuteSelectionMenuItem, BSTR /*MenuItemPath*/);
  241. MMC_METHOD2(ExecuteScopeNodeMenuItem, BSTR /*MenuItemPath*/, VARIANT /*varScopeNode = ActiveScopeNode */);
  242. MMC_METHOD4(ExecuteShellCommand, BSTR /*Command*/, BSTR /*Directory*/, BSTR /*Parameters*/, BSTR /*WindowState*/);
  243. //#######################################################################
  244. //#######################################################################
  245. //
  246. // Frame and view related methods
  247. //
  248. //#######################################################################
  249. //#######################################################################
  250. MMC_METHOD1(get_Frame, PPFRAME);
  251. MMC_METHOD0(Close);
  252. MMC_METHOD1(get_ScopeTreeVisible, PBOOL);
  253. MMC_METHOD1(put_ScopeTreeVisible, BOOL);
  254. MMC_METHOD0(Back);
  255. MMC_METHOD0(Forward);
  256. MMC_METHOD1(put_StatusBarText, BSTR);
  257. MMC_METHOD1(get_Memento, PBSTR);
  258. MMC_METHOD1(ViewMemento, BSTR);
  259. //#######################################################################
  260. //#######################################################################
  261. //
  262. // List related methods
  263. //
  264. //#######################################################################
  265. //#######################################################################
  266. MMC_METHOD1(get_Columns, PPCOLUMNS);
  267. MMC_METHOD3(get_CellContents, PNODE, long, PBSTR);
  268. MMC_METHOD2(ExportList, BSTR, ExportListOptions);
  269. MMC_METHOD1(get_ListViewMode, PLISTVIEWMODE);
  270. MMC_METHOD1(put_ListViewMode, ListViewMode);
  271. //#######################################################################
  272. //#######################################################################
  273. //
  274. // ActiveX control related methods
  275. //
  276. //#######################################################################
  277. //#######################################################################
  278. MMC_METHOD1(get_ControlObject, PPDISPATCH);
  279. };
  280. /*
  281. * WM_APPCOMMAND is only defined in winuser.h if _WIN32_WINNT >= 0x0500.
  282. * We need these definitions, but can't use _WIN32_WINNT==0x0500 (yet).
  283. */
  284. #ifndef WM_APPCOMMAND
  285. #define WM_APPCOMMAND 0x0319
  286. #define APPCOMMAND_BROWSER_BACKWARD 1
  287. #define APPCOMMAND_BROWSER_FORWARD 2
  288. #define APPCOMMAND_BROWSER_REFRESH 3
  289. #define FAPPCOMMAND_MOUSE 0x8000
  290. #define FAPPCOMMAND_KEY 0
  291. #define FAPPCOMMAND_OEM 0x1000
  292. #define FAPPCOMMAND_MASK 0xF000
  293. #define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
  294. #endif // WM_APPCOMMAND
  295. //############################################################################
  296. //############################################################################
  297. //
  298. // Implementation of class CAMCView
  299. //
  300. //############################################################################
  301. //############################################################################
  302. IMPLEMENT_DYNCREATE(CAMCView, CView);
  303. BEGIN_MESSAGE_MAP(CAMCView, CView)
  304. //{{AFX_MSG_MAP(CAMCView)
  305. ON_WM_MOUSEMOVE()
  306. ON_WM_LBUTTONDOWN()
  307. ON_WM_LBUTTONUP()
  308. ON_WM_CREATE()
  309. ON_WM_SETFOCUS()
  310. ON_WM_CONTEXTMENU()
  311. ON_WM_DESTROY()
  312. ON_UPDATE_COMMAND_UI(ID_FILE_SNAPINMANAGER, OnUpdateFileSnapinmanager)
  313. ON_WM_SHOWWINDOW()
  314. ON_COMMAND(ID_MMC_NEXT_PANE, OnNextPane)
  315. ON_COMMAND(ID_MMC_PREV_PANE, OnPrevPane)
  316. ON_WM_SETCURSOR()
  317. ON_COMMAND(ID_MMC_CONTEXTHELP, OnContextHelp)
  318. ON_COMMAND(ID_HELP_SNAPINHELP, OnSnapInHelp)
  319. ON_COMMAND(ID_SNAPIN_ABOUT, OnSnapinAbout)
  320. ON_COMMAND(ID_HELP_HELPTOPICS, OnHelpTopics)
  321. ON_WM_SIZE()
  322. ON_WM_SYSKEYDOWN()
  323. ON_WM_PALETTECHANGED()
  324. ON_WM_QUERYNEWPALETTE()
  325. ON_WM_SYSCOLORCHANGE()
  326. ON_WM_DRAWCLIPBOARD()
  327. ON_WM_SETTINGCHANGE()
  328. ON_WM_MENUSELECT()
  329. //}}AFX_MSG_MAP
  330. // keep this outside the AFX_MSG_MAP markers so ClassWizard doesn't munge it
  331. ON_COMMAND_RANGE(ID_MMC_CUT, ID_MMC_PRINT, OnVerbAccelKey)
  332. // WARNING: If your message handler has void return use ON_MESSAGE_VOID !!
  333. ON_MESSAGE(MMC_MSG_CONNECT_TO_CIC, OnConnectToCIC)
  334. ON_MESSAGE(MMC_MSG_CONNECT_TO_TPLV, OnConnectToTPLV)
  335. ON_MESSAGE(MMC_MSG_GET_ICON_INFO, OnGetIconInfoForSelectedNode)
  336. ON_MESSAGE(WM_APPCOMMAND, OnAppCommand)
  337. ON_REGISTERED_MESSAGE (m_nShowWebContextMenuMsg, OnShowWebContextMenu)
  338. ON_REGISTERED_MESSAGE (m_nProcessMultiSelectionChangesMsg, OnProcessMultiSelectionChanges)
  339. ON_REGISTERED_MESSAGE (m_nAddPageBreakAndNavigateMsg, OnAddPageBreakAndNavigate)
  340. ON_REGISTERED_MESSAGE (m_nJiggleListViewFocusMsg, OnJiggleListViewFocus)
  341. ON_REGISTERED_MESSAGE (m_nDeferRecalcLayoutMsg, OnDeferRecalcLayout)
  342. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  343. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  344. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  345. ON_NOTIFY(FTN_TABCHANGED, IDC_ResultTabCtrl, OnChangedResultTab)
  346. END_MESSAGE_MAP()
  347. /////////////////////////////////////////////////////////////////////////////
  348. // CAMCView construction/destruction
  349. const CSize CAMCView::m_sizEdge (GetSystemMetrics (SM_CXEDGE),
  350. GetSystemMetrics (SM_CYEDGE));
  351. const int CAMCView::m_cxSplitter = 3;
  352. //+-------------------------------------------------------------------
  353. //
  354. // Member: CAMCView::OnMenuSelect
  355. //
  356. // Synopsis: Handles WM_MENUSELECT for Favorites menu.
  357. //
  358. // Arguments: [nItemID] - the resource id of menu item.
  359. // [nFlags] - MF_* flags
  360. //
  361. // Returns: none
  362. //
  363. //--------------------------------------------------------------------
  364. void CAMCView::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
  365. {
  366. DECLARE_SC(sc, TEXT("CAMCView::OnMenuSelect"));
  367. CMainFrame* pFrame = AMCGetMainWnd();
  368. sc = ScCheckPointers(pFrame, E_UNEXPECTED);
  369. if (sc)
  370. return;
  371. // Pass onto the mainframe.
  372. return pFrame->OnMenuSelect(nItemID, nFlags, hSysMenu);
  373. }
  374. CAMCView::CAMCView() :
  375. m_pResultFolderTabView(new CFolderTabView(this)) // dynamically allocated for decoupling
  376. {
  377. TRACE_CONSTRUCTOR(CAMCView);
  378. // Init pointer members to NULL
  379. m_nViewID = 0;
  380. m_pTreeCtrl = NULL;
  381. m_pListCtrl = NULL;
  382. m_pWebViewCtrl = NULL;
  383. m_pViewExtensionCtrl = NULL;
  384. m_pOCXHostView = NULL;
  385. m_nSelectNestLevel = 0;
  386. // if the view is a listview, then this member define what the view
  387. // mode is for all snapins with that view.
  388. m_nViewMode = LVS_REPORT; // REVIEW: Must we persist this - ravi
  389. // REVIEW consider moving the above initialzation to the InitSplitter
  390. // CommonConstruct
  391. // NOTE moved code from InitSplitter into the contructor and deleted InitSplitter
  392. // Default values for view. User can set these values with SetPaneInfo;
  393. m_PaneInfo[ePane_ScopeTree].pView = NULL;
  394. m_PaneInfo[ePane_ScopeTree].cx = -1;
  395. m_PaneInfo[ePane_ScopeTree].cxMin = 50;
  396. m_PaneInfo[ePane_Results].pView = NULL;
  397. m_PaneInfo[ePane_Results].cx = -1;
  398. m_PaneInfo[ePane_Results].cxMin = 50;
  399. m_pTracker = NULL;
  400. m_rectResultFrame = g_rectEmpty;
  401. m_rectVSplitter = g_rectEmpty;
  402. // m_fDontPersistOCX = FALSE;
  403. // root node for the view
  404. m_hMTNode = 0;
  405. // Bug 157408: remove the "Type" column for static nodes
  406. // m_columnWidth[0] = 90;
  407. // m_columnWidth[1] = 50;
  408. m_columnWidth[0] = 200;
  409. m_columnWidth[1] = 0;
  410. m_iFocusedLV = -1;
  411. m_bLVItemSelected = FALSE;
  412. m_DefaultLVStyle = 0;
  413. m_bProcessMultiSelectionChanges = false;
  414. m_htiCut = NULL;
  415. m_nReleaseViews = 0;
  416. m_htiStartingSelectedNode = NULL;
  417. m_bLastSelWasMultiSel = false;
  418. m_eCurrentActivePane = eActivePaneNone;
  419. m_fRootedAtNonPersistedDynamicNode = false;
  420. m_fSnapinDisplayedHelp = false;
  421. m_fActivatingSpecialResultPane = false;
  422. m_bDirty = false;
  423. m_fViewExtended = false;
  424. m_pHistoryList = new CHistoryList (this);
  425. m_ListPadNode = NULL;
  426. /*
  427. * Bug 103604: Mark this as an author mode view if it was created in
  428. * author mode. If we're loading a user mode console file, it will
  429. * have author mode views and possibly some views that were created
  430. * in user mode, but this code will mark all of the views as non-author
  431. * mode views. CAMCView::Persist will fix that.
  432. */
  433. CAMCApp* pApp = AMCGetApp();
  434. if (pApp != NULL)
  435. m_bAuthorModeView = (pApp->GetMode() == eMode_Author);
  436. else
  437. m_bAuthorModeView = true;
  438. }
  439. CAMCView::~CAMCView()
  440. {
  441. TRACE_DESTRUCTOR(CAMCView);
  442. // Delete all pointer members. (C++ checks to see if they are NULL before deleting)
  443. // The standard ~CWnd destructor will call DestroyWindow()
  444. // REVIEW set the pointers to NULL after deleting them
  445. // Note Done
  446. // CViews "delete this" in PostNcDestroy, no need to delete here
  447. //delete m_pTreeCtrl;
  448. m_pTreeCtrl = NULL;
  449. m_pListCtrl->Release();
  450. m_pListCtrl = NULL;
  451. /*
  452. * DONT_DELETE_VIEWS
  453. *
  454. * CViews "delete this" in PostNcDestroy, no need to delete
  455. * here if the web view control is derived from CView. See
  456. * AttachWebViewAsResultPane (search for "DONT_DELETE_VIEWS")
  457. * for the ASSERTs that make sure this code is right.
  458. */
  459. //delete m_pWebViewCtrl;
  460. //m_pWebViewCtrl = NULL;
  461. /*
  462. * CViews "delete this" in PostNcDestroy, no need to delete here
  463. */
  464. m_pOCXHostView = NULL;
  465. m_pResultFolderTabView = NULL;
  466. if (m_ViewData.m_spNodeManager != NULL)
  467. m_ViewData.m_spNodeManager->CleanupViewData(
  468. reinterpret_cast<LONG_PTR>(&m_ViewData));
  469. ASSERT (m_ViewData.m_pMultiSelection == NULL);
  470. delete m_pHistoryList;
  471. // First destroy the IControlbarsCache as snapins call CAMCViewToolbars
  472. // to cleanup toolbars before the CAMCViewToolbars itself gets destroyed.
  473. m_ViewData.m_spControlbarsCache = NULL;
  474. // (UI cleanup) release toolbars related to this view.
  475. m_spAMCViewToolbars = std::auto_ptr<CAMCViewToolbars>(NULL);
  476. m_spStandardToolbar = std::auto_ptr<CStandardToolbar>(NULL);
  477. //m_spStandardToolbar = NULL;
  478. //m_spAMCViewToolbars = NULL;
  479. }
  480. //############################################################################
  481. //############################################################################
  482. //
  483. // CAMCView: Object model methods - View Interface
  484. //
  485. //############################################################################
  486. //############################################################################
  487. /*+-------------------------------------------------------------------------*
  488. *
  489. * CAMCView::ScGetOptionalScopeNodeParameter
  490. *
  491. * PURPOSE: Helper function - returns the scope node pointer, if supplied
  492. * in the variant, or the Active Scope node pointer, if not
  493. * supplied.
  494. *
  495. * PARAMETERS:
  496. * VARIANT varScopeNode : The parameter, which can be empty. NOTE: This is a
  497. * reference, so we don't need to call VariantClear on it.
  498. * PPNODE ppNode :
  499. * bool& bMatchedGivenNode: If true the returned ppNode corresponds to the given node
  500. * applies only if given node is in bookmark format.
  501. *
  502. * RETURNS:
  503. * SC
  504. *
  505. *+-------------------------------------------------------------------------*/
  506. SC
  507. CAMCView::ScGetOptionalScopeNodeParameter(VARIANT &varScopeNode, PPNODE ppNode, bool& bMatchedGivenNode)
  508. {
  509. DECLARE_SC(sc, TEXT("CAMCView::ScGetOptionalScopeNodeParameter"));
  510. sc = ScCheckPointers(ppNode);
  511. if(sc)
  512. return sc;
  513. // init the out parameter
  514. *ppNode = NULL;
  515. bMatchedGivenNode = true;
  516. // supply the optional parameter if it is missing
  517. if(IsOptionalParamMissing(varScopeNode))
  518. {
  519. sc = Scget_ActiveScopeNode(ppNode);
  520. return sc;
  521. }
  522. VARIANT* pvarTemp = ConvertByRefVariantToByValue(&varScopeNode);
  523. sc = ScCheckPointers(pvarTemp,E_UNEXPECTED);
  524. if(sc)
  525. return sc;
  526. bool bByReference = ( VT_BYREF == (V_VT(pvarTemp) & VT_BYREF) ); // value passed by reference
  527. UINT uiVarType = (V_VT(pvarTemp) & VT_TYPEMASK); // get variable type (strip flags)
  528. if(uiVarType == VT_DISPATCH) // do we have a dispatch interface.
  529. {
  530. IDispatchPtr spDispatch = NULL;
  531. if(bByReference) // a reference, use ppDispVal
  532. spDispatch = *(pvarTemp->ppdispVal);
  533. else
  534. spDispatch = pvarTemp->pdispVal; // passed by value, use pDispVal
  535. sc = ScCheckPointers(spDispatch.GetInterfacePtr());
  536. if(sc)
  537. return sc;
  538. // at this point spDispatch is correctly set. QI for Node from it.
  539. NodePtr spNode = spDispatch;
  540. if(spNode == NULL)
  541. return (sc = E_INVALIDARG);
  542. *ppNode = spNode.Detach(); // keep the reference.
  543. }
  544. else if(uiVarType == VT_BSTR)
  545. {
  546. // Name: get string properly ( see if it's a reference )
  547. LPOLESTR lpstrBookmark = bByReference ? *(pvarTemp->pbstrVal) : pvarTemp->bstrVal;
  548. // get the bookmark
  549. CBookmark bm;
  550. sc = bm.ScLoadFromString(lpstrBookmark);
  551. if(sc)
  552. return sc;
  553. if(!bm.IsValid())
  554. return (sc = E_UNEXPECTED);
  555. IScopeTree* const pScopeTree = GetScopeTreePtr();
  556. sc = ScCheckPointers(pScopeTree, E_UNEXPECTED);
  557. if(sc)
  558. return sc;
  559. NodePtr spNode;
  560. // Need a bool variable to find if exact match is found or not, cannot return
  561. // MMC specific error codes from nodemgr to conui.
  562. bMatchedGivenNode = false;
  563. sc = pScopeTree->GetNodeFromBookmark( bm, this, ppNode, bMatchedGivenNode);
  564. if(sc)
  565. return sc;
  566. }
  567. else
  568. return (sc = E_INVALIDARG);
  569. // we should have a valid node at this point.
  570. if(!ppNode)
  571. return (sc = E_UNEXPECTED);
  572. return sc;
  573. }
  574. /*+-------------------------------------------------------------------------*
  575. *
  576. * CAMCView::Scget_ActiveScopeNode
  577. *
  578. * PURPOSE: Implements get method for Wiew.ActiveScopeNode property
  579. *
  580. * PARAMETERS:
  581. * PPNODE ppNode - resulting node
  582. *
  583. * RETURNS:
  584. * SC
  585. *
  586. *+-------------------------------------------------------------------------*/
  587. SC
  588. CAMCView::Scget_ActiveScopeNode( PPNODE ppNode)
  589. {
  590. DECLARE_SC(sc, TEXT("CAMCView::Scget_ActiveScopeNode"));
  591. // checking parameters
  592. sc= ScCheckPointers(ppNode);
  593. if (sc)
  594. return sc;
  595. // get selected node
  596. HNODE hNode = GetSelectedNode();
  597. sc= ScCheckPointers((LPVOID)hNode, E_FAIL);
  598. if (sc)
  599. return sc;
  600. // get node callback
  601. INodeCallback* pNodeCallBack = GetNodeCallback();
  602. sc= ScCheckPointers(pNodeCallBack, E_FAIL);
  603. if (sc)
  604. return sc;
  605. // now get an HMTNODE
  606. HMTNODE hmtNode = NULL;
  607. sc = pNodeCallBack->GetMTNode(hNode, &hmtNode);
  608. if (sc)
  609. return sc;
  610. // geting pointer to scope tree
  611. IScopeTree* const pScopeTree = GetScopeTreePtr();
  612. sc= ScCheckPointers(pScopeTree, E_UNEXPECTED);
  613. if (sc)
  614. return sc;
  615. // map to PNODE
  616. sc = pScopeTree->GetMMCNode(hmtNode, ppNode);
  617. if (sc)
  618. return sc;
  619. return sc;
  620. }
  621. /***************************************************************************\
  622. *
  623. * METHOD: CExpandSyncModeLock
  624. *
  625. * PURPOSE: constructing the object of this class locks MMC in syncronous
  626. * expansion mode (node expansion will send MMCN_EXPANDSYNC to snapin)
  627. * destructor of the class restores the previous mode
  628. *
  629. \***************************************************************************/
  630. class CExpandSyncModeLock
  631. {
  632. IScopeTreePtr m_spScopeTree;
  633. bool m_fSyncExpandWasRequired;
  634. public:
  635. CExpandSyncModeLock( IScopeTree *pScopeTree ) : m_spScopeTree(pScopeTree),
  636. m_fSyncExpandWasRequired(false)
  637. {
  638. ASSERT( m_spScopeTree != NULL );
  639. if ( m_spScopeTree )
  640. {
  641. m_fSyncExpandWasRequired = (m_spScopeTree->IsSynchronousExpansionRequired() == S_OK);
  642. m_spScopeTree->RequireSynchronousExpansion (true);
  643. }
  644. }
  645. ~CExpandSyncModeLock()
  646. {
  647. if ( m_spScopeTree )
  648. {
  649. m_spScopeTree->RequireSynchronousExpansion ( m_fSyncExpandWasRequired );
  650. }
  651. }
  652. };
  653. /*+-------------------------------------------------------------------------*
  654. *
  655. * CAMCView::Scset_ActiveScopeNode
  656. *
  657. * PURPOSE: Implements set method for Wiew.ActiveScopeNode property
  658. *
  659. * PARAMETERS:
  660. * PNODE pNode - node to activate
  661. *
  662. * RETURNS:
  663. * SC
  664. *
  665. *+-------------------------------------------------------------------------*/
  666. SC
  667. CAMCView::Scput_ActiveScopeNode( PNODE pNode)
  668. {
  669. DECLARE_SC(sc, TEXT("CAMCView::Scput_ActiveScopeNode"));
  670. // checking parameters
  671. sc= ScCheckPointers(pNode);
  672. if (sc)
  673. return sc;
  674. // geting pointer to scope tree
  675. IScopeTree* const pScopeTree = GetScopeTreePtr();
  676. sc= ScCheckPointers(pScopeTree, E_UNEXPECTED);
  677. if (sc)
  678. return sc;
  679. // Converting PNODE to TNODEID
  680. MTNODEID ID = 0;
  681. sc = pScopeTree->GetNodeID(pNode, &ID);
  682. if (sc)
  683. return sc;
  684. // always require syncronous expansion for Object Model
  685. // see bug #154694
  686. CExpandSyncModeLock lock( pScopeTree );
  687. // selecting the node
  688. sc = ScSelectNode(ID);
  689. if (sc)
  690. return sc;
  691. return sc;
  692. }
  693. /***************************************************************************\
  694. *
  695. * METHOD: CAMCView::Scget_Selection
  696. *
  697. * PURPOSE: creates enumerator for Selected Nodes
  698. *
  699. * PARAMETERS:
  700. * PPNODES ppNodes - resulting enumerator
  701. *
  702. * RETURNS:
  703. * SC - result code
  704. *
  705. \***************************************************************************/
  706. SC CAMCView::Scget_Selection( PPNODES ppNodes )
  707. {
  708. DECLARE_SC(sc, TEXT("CAMCView::Scget_SelectedItems"));
  709. // check for list view control
  710. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  711. if (sc)
  712. return sc;
  713. // get enumerator from list control
  714. sc = m_pListCtrl->Scget_SelectedItems(ppNodes);
  715. if (sc)
  716. return sc;
  717. return sc;
  718. }
  719. /***************************************************************************\
  720. *
  721. * METHOD: CAMCView::Scget_ListItems
  722. *
  723. * PURPOSE:
  724. *
  725. * PARAMETERS:
  726. * PPNODES ppNodes - resulting enumerator
  727. *
  728. * RETURNS:
  729. * SC - result code
  730. *
  731. \***************************************************************************/
  732. SC CAMCView::Scget_ListItems( PPNODES ppNodes )
  733. {
  734. DECLARE_SC(sc, TEXT("CAMCView::Scget_ListItems"));
  735. // check for list view control
  736. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  737. if (sc)
  738. return sc;
  739. // get enumerator from list control
  740. sc = m_pListCtrl->Scget_ListItems(ppNodes);
  741. if (sc)
  742. return sc;
  743. return sc;
  744. }
  745. //+-------------------------------------------------------------------
  746. //
  747. // Member: CAMCView::ScSnapinScopeObject
  748. //
  749. // Synopsis: Get the IDispatch* from snapin for given ScopeNode object.
  750. //
  751. // Arguments: varScopeNode - Given ScopeNode object.
  752. // ScopeNodeObject [out] - IDispatch for ScopeNode object.
  753. //
  754. // Returns: SC
  755. //
  756. //--------------------------------------------------------------------
  757. SC CAMCView::ScSnapinScopeObject (VARIANT& varScopeNode, /*[out]*/PPDISPATCH ScopeNodeObject)
  758. {
  759. DECLARE_SC(sc, _T("CAMCView::ScSnapinScopeObject"));
  760. sc = ScCheckPointers(ScopeNodeObject);
  761. if (sc)
  762. return sc;
  763. *ScopeNodeObject = NULL;
  764. bool bMatchedGivenNode = false; // unused
  765. NodePtr spNode = NULL;
  766. sc = ScGetOptionalScopeNodeParameter(varScopeNode, &spNode, bMatchedGivenNode);
  767. if(sc)
  768. return sc;
  769. INodeCallback* pNC = GetNodeCallback();
  770. sc = ScCheckPointers(spNode.GetInterfacePtr(), pNC, E_UNEXPECTED);
  771. if(sc)
  772. return sc;
  773. sc = pNC->QueryCompDataDispatch(spNode, ScopeNodeObject);
  774. if (sc)
  775. return sc;
  776. return sc;
  777. }
  778. //+-------------------------------------------------------------------
  779. //
  780. // Member: CAMCView::ScSnapinSelectionObject
  781. //
  782. // Synopsis: Get the IDispatch* from snapin for selected items in result pane.
  783. //
  784. // Arguments: SelectedObject [out] - IDispatch for Selected items object.
  785. //
  786. // Returns: SC
  787. //
  788. //--------------------------------------------------------------------
  789. SC CAMCView::ScSnapinSelectionObject (PPDISPATCH SelectedObject)
  790. {
  791. DECLARE_SC(sc, _T("CAMCView::ScSnapinSelectionObject"));
  792. sc = ScCheckPointers(SelectedObject);
  793. if (sc)
  794. return sc;
  795. *SelectedObject = NULL;
  796. if (!HasList()) // not a list. Return error
  797. return (sc = ScFromMMC(MMC_E_NOLIST));
  798. LPARAM lvData = LVDATA_ERROR;
  799. sc = ScGetSelectedLVItem(lvData);
  800. if (sc)
  801. return sc;
  802. HNODE hNode = GetSelectedNode();
  803. sc = ScCheckPointers(hNode, E_UNEXPECTED);
  804. if (sc)
  805. return sc;
  806. INodeCallback* pNodeCallback = GetNodeCallback();
  807. sc = ScCheckPointers(pNodeCallback, E_UNEXPECTED);
  808. if(sc)
  809. return sc.ToHr();
  810. sc = pNodeCallback->QueryComponentDispatch(hNode, lvData, SelectedObject);
  811. if (sc)
  812. return sc;
  813. return (sc);
  814. }
  815. /***************************************************************************\
  816. *
  817. * METHOD: CAMCView::ScIs
  818. *
  819. * PURPOSE: compares two views if they are the same
  820. *
  821. * PARAMETERS:
  822. * PVIEW pView - [in] another view
  823. * VARIANT_BOOL * pbTheSame - [out] comparison result
  824. *
  825. * RETURNS:
  826. * SC - result code
  827. *
  828. \***************************************************************************/
  829. SC CAMCView::ScIs (PVIEW pView, VARIANT_BOOL *pbTheSame)
  830. {
  831. DECLARE_SC(sc, TEXT("CAMCView::ScIs"));
  832. // parameter check
  833. sc = ScCheckPointers(pView, pbTheSame);
  834. if (sc)
  835. return sc;
  836. *pbTheSame = CComPtr<View>(pView).IsEqualObject(m_spView)
  837. ? VARIANT_TRUE : VARIANT_FALSE;
  838. return sc;
  839. }
  840. //+-------------------------------------------------------------------
  841. //
  842. // Member: CAMCView::ScSelectAll
  843. //
  844. // Synopsis: Selects all items in the result pane
  845. //
  846. // Arguments: None
  847. //
  848. // Returns: SC
  849. //
  850. //--------------------------------------------------------------------
  851. SC CAMCView::ScSelectAll ()
  852. {
  853. DECLARE_SC(sc, _T("CAMCView::ScSelectAll"));
  854. if (! (GetListOptions() & RVTI_LIST_OPTIONS_MULTISELECT) )
  855. return (sc = ScFromMMC(MMC_E_NO_MULTISELECT));
  856. // check for list view control
  857. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  858. if (sc)
  859. return sc;
  860. // forward to list control
  861. sc = m_pListCtrl->ScSelectAll();
  862. if (sc)
  863. return sc;
  864. return (sc);
  865. }
  866. /***************************************************************************\
  867. *
  868. * METHOD: CAMCView::ScSelect
  869. *
  870. * PURPOSE: selects item identified by node [implements View.Select()]
  871. *
  872. * PARAMETERS:
  873. * PNODE pNode - node to select
  874. *
  875. * RETURNS:
  876. * SC - result code
  877. *
  878. \***************************************************************************/
  879. SC CAMCView::ScSelect( PNODE pNode )
  880. {
  881. DECLARE_SC(sc, TEXT("CAMCView::ScSelect"));
  882. // parameter check
  883. sc = ScCheckPointers(pNode);
  884. if (sc)
  885. return sc;
  886. // check for list view control
  887. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  888. if (sc)
  889. return sc;
  890. // forward to list control
  891. sc = m_pListCtrl->ScSelect( pNode );
  892. if (sc)
  893. return sc;
  894. return sc;
  895. }
  896. /***************************************************************************\
  897. *
  898. * METHOD: CAMCView::ScDeselect
  899. *
  900. * PURPOSE: deselects item identified by node [implements View.Deselect()]
  901. *
  902. * PARAMETERS:
  903. * PNODE pNode - node to deselect
  904. *
  905. * RETURNS:
  906. * SC - result code
  907. *
  908. \***************************************************************************/
  909. SC CAMCView::ScDeselect( PNODE pNode)
  910. {
  911. DECLARE_SC(sc, TEXT("CAMCView::ScDeselect"));
  912. // parameter check
  913. sc = ScCheckPointers(pNode);
  914. if (sc)
  915. return sc;
  916. // check for list view control
  917. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  918. if (sc)
  919. return sc;
  920. // forward to list control
  921. sc = m_pListCtrl->ScDeselect( pNode );
  922. if (sc)
  923. return sc;
  924. return sc;
  925. }
  926. /***************************************************************************\
  927. *
  928. * METHOD: CAMCView::ScIsSelected
  929. *
  930. * PURPOSE: checks the status of item identified by node [implements View.IsSelected]
  931. *
  932. * PARAMETERS:
  933. * PNODE pNode - node to examine
  934. * PBOOL pIsSelected - storage for result
  935. *
  936. * RETURNS:
  937. * SC - result code
  938. *
  939. \***************************************************************************/
  940. SC CAMCView::ScIsSelected( PNODE pNode, PBOOL pIsSelected )
  941. {
  942. DECLARE_SC(sc, TEXT("CAMCView::ScIsSelected"));
  943. // parameter check
  944. sc = ScCheckPointers(pNode, pIsSelected);
  945. if (sc)
  946. return sc;
  947. *pIsSelected = FALSE;
  948. // check for list view control
  949. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  950. if (sc)
  951. return sc;
  952. // forward to list control
  953. sc = m_pListCtrl->ScIsSelected( pNode, pIsSelected );
  954. if (sc)
  955. return sc;
  956. return sc;
  957. }
  958. //+-------------------------------------------------------------------
  959. //
  960. // Member: CAMCView::ScExecuteScopeItemVerb
  961. //
  962. // Synopsis: Get the context and pass it on to nodemgr to execute
  963. // given verb.
  964. //
  965. // Arguments: [verb] - Verb to execute
  966. // [varScopeNode] - Optional scope node (if not given,
  967. // currently selected item will be used.)
  968. // [bstrNewName] - valid for Rename else NULL.
  969. //
  970. // Returns: SC
  971. //
  972. //--------------------------------------------------------------------
  973. SC CAMCView::ScExecuteScopeItemVerb (MMC_CONSOLE_VERB verb, VARIANT& varScopeNode, BSTR bstrNewName)
  974. {
  975. DECLARE_SC(sc, _T("CAMCView::ScExecuteScopeItemVerb"));
  976. NodePtr spNode = NULL;
  977. bool bMatchedGivenNode = false;
  978. // We should navigate to exact node to execute the verb.
  979. sc = ScGetOptionalScopeNodeParameter(varScopeNode, &spNode, bMatchedGivenNode);
  980. if(sc)
  981. return sc;
  982. if (! bMatchedGivenNode)
  983. return (sc = ScFromMMC(IDS_ACTION_COULD_NOTBE_COMPLETED));
  984. HNODE hNode = NULL;
  985. sc = ScGetHNodeFromPNode(spNode, hNode);
  986. if (sc)
  987. return sc;
  988. INodeCallback* pNC = GetNodeCallback();
  989. sc = ScCheckPointers(spNode.GetInterfacePtr(), pNC);
  990. if(sc)
  991. return sc;
  992. sc = pNC->ExecuteScopeItemVerb(verb, hNode, bstrNewName);
  993. if (sc)
  994. return sc;
  995. return (sc);
  996. }
  997. //+-------------------------------------------------------------------
  998. //
  999. // Member: CAMCView::ScExecuteResultItemVerb
  1000. //
  1001. // Synopsis: Get the currently selected context and pass it on to
  1002. // nodemgr to execute given verb.
  1003. //
  1004. // Arguments: [verb] - Verb to execute
  1005. // [bstrNewName] - valid for Rename else NULL.
  1006. //
  1007. // Returns: SC
  1008. //
  1009. //--------------------------------------------------------------------
  1010. SC CAMCView::ScExecuteResultItemVerb (MMC_CONSOLE_VERB verb, BSTR bstrNewName)
  1011. {
  1012. DECLARE_SC(sc, _T("CAMCView::ScExecuteResultItemVerb"));
  1013. if (!HasList()) // not a list. Return error
  1014. return (sc = ScFromMMC(MMC_E_NOLIST));
  1015. LPARAM lvData = LVDATA_ERROR;
  1016. sc = ScGetSelectedLVItem(lvData);
  1017. if (sc)
  1018. return sc;
  1019. if (lvData == LVDATA_ERROR)
  1020. return (sc = E_UNEXPECTED);
  1021. HNODE hNode = GetSelectedNode();
  1022. sc = ScCheckPointers(hNode, E_UNEXPECTED);
  1023. if (sc)
  1024. return sc;
  1025. INodeCallback* pNodeCallback = GetNodeCallback();
  1026. sc = ScCheckPointers(pNodeCallback, E_UNEXPECTED);
  1027. if(sc)
  1028. return sc.ToHr();
  1029. sc = pNodeCallback->ExecuteResultItemVerb( verb, hNode, lvData, bstrNewName);
  1030. if (sc)
  1031. return sc;
  1032. return (sc);
  1033. }
  1034. /*+-------------------------------------------------------------------------*
  1035. *
  1036. * CAMCView::ScDisplayScopeNodePropertySheet
  1037. *
  1038. * PURPOSE: Displays the property sheet for a scope node.
  1039. *
  1040. * PARAMETERS:
  1041. * VARIANT varScopeNode :
  1042. *
  1043. * RETURNS:
  1044. * SC
  1045. *
  1046. *+-------------------------------------------------------------------------*/
  1047. SC
  1048. CAMCView::ScDisplayScopeNodePropertySheet(VARIANT& varScopeNode)
  1049. {
  1050. DECLARE_SC(sc, TEXT("CAMCView::ScDisplayPropertySheet"));
  1051. sc = ScExecuteScopeItemVerb(MMC_VERB_PROPERTIES, varScopeNode, NULL);
  1052. if (sc)
  1053. return sc;
  1054. return sc;
  1055. }
  1056. //+-------------------------------------------------------------------
  1057. //
  1058. // Member: CAMCView::ScDisplaySelectionPropertySheet
  1059. //
  1060. // Synopsis: Show the property sheet for selected result item(s).
  1061. //
  1062. // Arguments: None
  1063. //
  1064. // Returns: SC
  1065. //
  1066. //--------------------------------------------------------------------
  1067. SC CAMCView::ScDisplaySelectionPropertySheet ()
  1068. {
  1069. DECLARE_SC(sc, _T("CAMCView::ScDisplaySelectionPropertySheet"));
  1070. sc = ScExecuteResultItemVerb(MMC_VERB_PROPERTIES, NULL);
  1071. if (sc)
  1072. return sc;
  1073. return (sc);
  1074. }
  1075. //+-------------------------------------------------------------------
  1076. //
  1077. // Member: CAMCView::ScCopyScopeNode
  1078. //
  1079. // Synopsis: Copy the specified scope node (if given) or currently
  1080. // selected node to clipboard.
  1081. //
  1082. // Arguments: [varScopeNode] - given node.
  1083. //
  1084. // Returns: SC
  1085. //
  1086. //--------------------------------------------------------------------
  1087. SC CAMCView::ScCopyScopeNode (VARIANT& varScopeNode)
  1088. {
  1089. DECLARE_SC(sc, _T("CAMCView::ScCopyScopeNode"));
  1090. sc = ScExecuteScopeItemVerb(MMC_VERB_COPY, varScopeNode, NULL);
  1091. if (sc)
  1092. return sc;
  1093. return (sc);
  1094. }
  1095. //+-------------------------------------------------------------------
  1096. //
  1097. // Member: CAMCView::ScCopySelection
  1098. //
  1099. // Synopsis: Copy the selected result item(s) to clipboard.
  1100. //
  1101. // Arguments:
  1102. //
  1103. // Returns: SC
  1104. //
  1105. //--------------------------------------------------------------------
  1106. SC CAMCView::ScCopySelection ()
  1107. {
  1108. DECLARE_SC(sc, _T("CAMCView::ScCopySelection"));
  1109. sc = ScExecuteResultItemVerb(MMC_VERB_COPY, NULL);
  1110. if (sc)
  1111. return sc;
  1112. return (sc);
  1113. }
  1114. //+-------------------------------------------------------------------
  1115. //
  1116. // Member: CAMCView::ScDeleteScopeNode
  1117. //
  1118. // Synopsis: Deletes the specified scope node (if given) or currently
  1119. // selected node.
  1120. //
  1121. // Arguments: [varScopeNode] - node to delete
  1122. //
  1123. // Returns: SC
  1124. //
  1125. //--------------------------------------------------------------------
  1126. SC CAMCView::ScDeleteScopeNode (VARIANT& varScopeNode)
  1127. {
  1128. DECLARE_SC(sc, _T("CAMCView::ScDeleteScopeNode"));
  1129. sc = ScExecuteScopeItemVerb(MMC_VERB_DELETE, varScopeNode, NULL);
  1130. if (sc)
  1131. return sc;
  1132. return (sc);
  1133. }
  1134. //+-------------------------------------------------------------------
  1135. //
  1136. // Member: CAMCView::ScDeleteSelection
  1137. //
  1138. // Synopsis: Deletes the selected item(s) in result pane.
  1139. //
  1140. // Returns: SC
  1141. //
  1142. //--------------------------------------------------------------------
  1143. SC CAMCView::ScDeleteSelection ()
  1144. {
  1145. DECLARE_SC(sc, _T("CAMCView::ScDeleteSelection"));
  1146. sc = ScExecuteResultItemVerb(MMC_VERB_DELETE, NULL);
  1147. if (sc)
  1148. return sc;
  1149. return (sc);
  1150. }
  1151. //+-------------------------------------------------------------------
  1152. //
  1153. // Member: CAMCView::ScRenameScopeNode
  1154. //
  1155. // Synopsis: Rename the specified scope node (if given) or currently
  1156. // selected node with given new name.
  1157. //
  1158. // Arguments: [bstrNewName] - the new name
  1159. // [varScopeNode] - given node.
  1160. //
  1161. // Returns: SC
  1162. //
  1163. //--------------------------------------------------------------------
  1164. SC CAMCView::ScRenameScopeNode (BSTR bstrNewName, VARIANT& varScopeNode)
  1165. {
  1166. DECLARE_SC(sc, _T("CAMCView::ScRenameScopeNode"));
  1167. sc = ScExecuteScopeItemVerb(MMC_VERB_RENAME, varScopeNode, bstrNewName);
  1168. if (sc)
  1169. return sc;
  1170. return (sc);
  1171. }
  1172. //+-------------------------------------------------------------------
  1173. //
  1174. // Member: CAMCView::ScRenameSelectedItem
  1175. //
  1176. // Synopsis: Rename the selected result item with given new name.
  1177. //
  1178. // Arguments:
  1179. //
  1180. // Returns: SC
  1181. //
  1182. //--------------------------------------------------------------------
  1183. SC CAMCView::ScRenameSelectedItem (BSTR bstrNewName)
  1184. {
  1185. DECLARE_SC(sc, _T("CAMCView::ScRenameSelectedItem"));
  1186. sc = ScExecuteResultItemVerb(MMC_VERB_RENAME, bstrNewName);
  1187. if (sc)
  1188. return sc;
  1189. return (sc);
  1190. }
  1191. //+-------------------------------------------------------------------
  1192. //
  1193. // Member: CAMCView::ScRefreshScopeNode
  1194. //
  1195. // Synopsis: Refresh the specified scope node (if given) or currently
  1196. // selected node.
  1197. //
  1198. // Arguments: [varScopeNode] - given node.
  1199. //
  1200. // Returns: SC
  1201. //
  1202. //--------------------------------------------------------------------
  1203. SC CAMCView::ScRefreshScopeNode (VARIANT& varScopeNode)
  1204. {
  1205. DECLARE_SC(sc, _T("CAMCView::ScRefreshScopeNode"));
  1206. sc = ScExecuteScopeItemVerb(MMC_VERB_REFRESH, varScopeNode, NULL);
  1207. if (sc)
  1208. return sc;
  1209. return (sc);
  1210. }
  1211. //+-------------------------------------------------------------------
  1212. //
  1213. // Member: CAMCView::ScRefreshSelection
  1214. //
  1215. // Synopsis: Refresh the selected result item(s).
  1216. //
  1217. // Arguments:
  1218. //
  1219. // Returns: SC
  1220. //
  1221. //--------------------------------------------------------------------
  1222. SC CAMCView::ScRefreshSelection ()
  1223. {
  1224. DECLARE_SC(sc, _T("CAMCView::ScRefreshSelection"));
  1225. sc = ScExecuteResultItemVerb(MMC_VERB_REFRESH, NULL);
  1226. if (sc)
  1227. return sc;
  1228. return (sc);
  1229. }
  1230. /*+-------------------------------------------------------------------------*
  1231. *
  1232. * CAMCView::Scget_ScopeNodeContextMenu
  1233. *
  1234. * PURPOSE: Creates a context menu for a scope node and returns it.
  1235. *
  1236. * PARAMETERS:
  1237. * VARIANT varScopeNode :
  1238. * PPCONTEXTMENU ppContextMenu :
  1239. *
  1240. * RETURNS:
  1241. * SC
  1242. *
  1243. *+-------------------------------------------------------------------------*/
  1244. SC
  1245. CAMCView::Scget_ScopeNodeContextMenu(VARIANT& varScopeNode, PPCONTEXTMENU ppContextMenu, bool bMatchGivenNode /* = false*/)
  1246. {
  1247. DECLARE_SC(sc, TEXT("CAMCView::Scget_ContextMenu"));
  1248. NodePtr spNode;
  1249. // See if context menu for exactly the given node is asked for.
  1250. bool bMatchedGivenNode = false;
  1251. sc = ScGetOptionalScopeNodeParameter(varScopeNode, &spNode, bMatchedGivenNode);
  1252. if (sc)
  1253. return sc;
  1254. if ( (bMatchGivenNode) && (!bMatchedGivenNode) )
  1255. return ScFromMMC(IDS_NODE_NOT_FOUND);
  1256. if(sc)
  1257. return sc;
  1258. INodeCallback* spNodeCallback = GetNodeCallback();
  1259. sc = ScCheckPointers(spNode, ppContextMenu, spNodeCallback, GetTreeCtrl());
  1260. if(sc)
  1261. return sc.ToHr();
  1262. *ppContextMenu = NULL; // initialize output.
  1263. HNODE hNode = NULL;
  1264. sc = ScGetHNodeFromPNode(spNode, hNode);
  1265. if (sc)
  1266. return sc;
  1267. // tell the node callback to add menu items for the scope node.
  1268. sc = spNodeCallback->CreateContextMenu(spNode, hNode, ppContextMenu);
  1269. return sc;
  1270. }
  1271. /*+-------------------------------------------------------------------------*
  1272. *
  1273. * CAMCView::Scget_SelectionContextMenu
  1274. *
  1275. * PURPOSE: Creates a context menu for the current selection and returns it.
  1276. *
  1277. * PARAMETERS:
  1278. * PPCONTEXTMENU ppContextMenu : [OUT]: The context menu object
  1279. *
  1280. * RETURNS:
  1281. * SC : error if no list exists, or there is nothing selected.
  1282. *
  1283. *+-------------------------------------------------------------------------*/
  1284. SC
  1285. CAMCView::Scget_SelectionContextMenu( PPCONTEXTMENU ppContextMenu)
  1286. {
  1287. DECLARE_SC(sc, TEXT("CAMCView::Scget_SelectionContextMenu"));
  1288. sc = ScCheckPointers(ppContextMenu);
  1289. if(sc)
  1290. return sc;
  1291. if (!HasListOrListPad()) // not a list. Return error
  1292. return (sc = ScFromMMC(MMC_E_NOLIST));
  1293. INodeCallback* pNodeCallback = GetNodeCallback();
  1294. sc = ScCheckPointers(pNodeCallback);
  1295. if(sc)
  1296. return sc.ToHr();
  1297. CContextMenuInfo contextInfo; // the structure to pass to nodemgr
  1298. // common entries
  1299. contextInfo.m_pConsoleView = this;
  1300. // always use the temp verbs - cannot depend on what the active pane is
  1301. contextInfo.m_dwFlags = CMINFO_USE_TEMP_VERB;
  1302. int iIndex = -1;
  1303. HNODE hNode = GetSelectedNode();
  1304. ASSERT(hNode != NULL);
  1305. int cSel = m_pListCtrl->GetSelectedCount();
  1306. if(0 == cSel)
  1307. {
  1308. // no items selected, bail
  1309. return (sc = ScFromMMC(MMC_E_NO_SELECTED_ITEMS));
  1310. }
  1311. else if(1 == cSel)
  1312. {
  1313. // single selection
  1314. LPARAM lvData = LVDATA_ERROR;
  1315. iIndex = _GetLVSelectedItemData(&lvData);
  1316. ASSERT(iIndex != -1);
  1317. ASSERT(lvData != LVDATA_ERROR);
  1318. if (IsVirtualList())
  1319. {
  1320. // virtual list item in the result pane
  1321. contextInfo.m_eDataObjectType = CCT_RESULT;
  1322. contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
  1323. contextInfo.m_bBackground = false;
  1324. contextInfo.m_bMultiSelect = false;
  1325. contextInfo.m_resultItemParam = iIndex;
  1326. contextInfo.m_iListItemIndex = iIndex;
  1327. }
  1328. else
  1329. {
  1330. CResultItem* pri = CResultItem::FromHandle (lvData);
  1331. if(!pri)
  1332. return (sc = E_UNEXPECTED);
  1333. if (pri->IsScopeItem())
  1334. {
  1335. // scope item in the result pane
  1336. contextInfo.m_eDataObjectType = CCT_SCOPE;
  1337. contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
  1338. contextInfo.m_bBackground = FALSE;
  1339. contextInfo.m_hSelectedScopeNode = GetSelectedNode();
  1340. contextInfo.m_resultItemParam = NULL;
  1341. contextInfo.m_bMultiSelect = FALSE;
  1342. contextInfo.m_bScopeAllowed = TRUE;
  1343. // change the scope node on which the menu is to be displayed
  1344. hNode = pri->GetScopeNode();
  1345. }
  1346. else
  1347. {
  1348. // single result item in the result pane
  1349. contextInfo.m_eDataObjectType = CCT_RESULT;
  1350. contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
  1351. contextInfo.m_bBackground = false;
  1352. contextInfo.m_bMultiSelect = false;
  1353. contextInfo.m_resultItemParam = lvData;
  1354. contextInfo.m_iListItemIndex = iIndex;
  1355. }
  1356. }
  1357. }
  1358. else
  1359. {
  1360. // multiselection
  1361. iIndex = INDEX_MULTISELECTION; // => MultiSelect
  1362. contextInfo.m_eDataObjectType = CCT_RESULT;
  1363. contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
  1364. contextInfo.m_bBackground = false;
  1365. contextInfo.m_bMultiSelect = true;
  1366. contextInfo.m_resultItemParam = LVDATA_MULTISELECT;
  1367. contextInfo.m_iListItemIndex = iIndex;
  1368. }
  1369. sc = pNodeCallback->CreateSelectionContextMenu(hNode, &contextInfo, ppContextMenu);
  1370. return sc;
  1371. }
  1372. /*+-------------------------------------------------------------------------*
  1373. *
  1374. * CAMCView::ScExecuteMenuItem
  1375. *
  1376. * PURPOSE: Executes the specified context menu item on the specified context menu
  1377. *
  1378. * PARAMETERS:
  1379. * PCONTEXTMENU pContextMenu :
  1380. * BSTR MenuItemPath : Either the language-independent path or the
  1381. * language-dependent path.
  1382. *
  1383. * RETURNS:
  1384. * SC
  1385. *
  1386. *+-------------------------------------------------------------------------*/
  1387. SC
  1388. CAMCView::ScExecuteMenuItem(PCONTEXTMENU pContextMenu, BSTR MenuItemPath)
  1389. {
  1390. DECLARE_SC(sc, TEXT("CAMCView::ScExecuteMenuItem"));
  1391. sc = ScCheckPointers(MenuItemPath);
  1392. if(sc)
  1393. return sc;
  1394. sc = ScCheckPointers(pContextMenu, E_UNEXPECTED);
  1395. if(sc)
  1396. return sc;
  1397. // execute the menu item, if found.
  1398. MenuItemPtr spMenuItem;
  1399. sc = pContextMenu->get_Item(CComVariant(MenuItemPath), &spMenuItem);
  1400. if(sc.IsError() || sc == SC(S_FALSE)) // error or no item
  1401. return (sc = E_INVALIDARG); // did not find the menu item.
  1402. // recheck the pointer
  1403. sc = ScCheckPointers(spMenuItem, E_UNEXPECTED);
  1404. if (sc)
  1405. return sc;
  1406. // found - execute it
  1407. sc = spMenuItem->Execute();
  1408. return sc;
  1409. }
  1410. /*+-------------------------------------------------------------------------*
  1411. *
  1412. * CAMCView::ScExecuteSelectionMenuItem
  1413. *
  1414. * PURPOSE: Executes a context menu item on the selection.
  1415. *
  1416. * PARAMETERS:
  1417. * BSTR MenuItemPath : Either the language-independent path or the
  1418. * language-dependent path of the menu item.
  1419. *
  1420. * NOTE: This is an aggregate or utility function - it only uses other
  1421. * object model functions
  1422. *
  1423. * RETURNS:
  1424. * SC
  1425. *
  1426. *+-------------------------------------------------------------------------*/
  1427. SC
  1428. CAMCView::ScExecuteSelectionMenuItem(BSTR MenuItemPath)
  1429. {
  1430. DECLARE_SC(sc, TEXT("CAMCView::ScExecuteSelectionMenuItem"));
  1431. // get the context menu object
  1432. ContextMenuPtr spContextMenu;
  1433. sc = Scget_SelectionContextMenu(&spContextMenu);
  1434. if(sc)
  1435. return sc;
  1436. sc = ScExecuteMenuItem(spContextMenu, MenuItemPath);
  1437. return sc;
  1438. }
  1439. /*+-------------------------------------------------------------------------*
  1440. *
  1441. * CAMCView::ScExecuteScopeNodeMenuItem
  1442. *
  1443. * PURPOSE: Executes a context menu item on the specified scope node. The parameter
  1444. * is the language independent path of the menu item
  1445. *
  1446. * PARAMETERS:
  1447. * BSTR MenuItemLanguageIndependentPath :
  1448. *
  1449. * NOTE: This is an aggregate or utility function - it only uses other
  1450. * object model functions
  1451. *
  1452. * RETURNS:
  1453. * SC
  1454. *
  1455. *+-------------------------------------------------------------------------*/
  1456. SC
  1457. CAMCView::ScExecuteScopeNodeMenuItem(BSTR MenuItemPath, VARIANT &varScopeNode /* = ActiveScopeNode */)
  1458. {
  1459. DECLARE_SC(sc, TEXT("CAMCView::ScExecuteScopeNodeMenuItem"));
  1460. // get the context menu object for exactly the given node.
  1461. ContextMenuPtr spContextMenu;
  1462. sc = Scget_ScopeNodeContextMenu(varScopeNode, &spContextMenu, /*bMatchGivenNode = */ true);
  1463. if (sc == ScFromMMC(IDS_NODE_NOT_FOUND))
  1464. {
  1465. sc = ScFromMMC(IDS_ACTION_COULD_NOTBE_COMPLETED);
  1466. return sc;
  1467. }
  1468. if(sc)
  1469. return sc;
  1470. sc = ScExecuteMenuItem(spContextMenu, MenuItemPath);
  1471. return sc;
  1472. }
  1473. /*+-------------------------------------------------------------------------*
  1474. *
  1475. * CAMCView::ScExecuteShellCommand
  1476. *
  1477. * PURPOSE: Executes a shell command with the specified parameters in the
  1478. * specified directory with the correct window size
  1479. *
  1480. * PARAMETERS:
  1481. * BSTR Command :
  1482. * BSTR Directory :
  1483. * BSTR Parameters :
  1484. * BSTR WindowState :
  1485. *
  1486. * RETURNS:
  1487. * SC
  1488. *
  1489. *+-------------------------------------------------------------------------*/
  1490. SC
  1491. CAMCView::ScExecuteShellCommand(BSTR Command, BSTR Directory, BSTR Parameters, BSTR WindowState)
  1492. {
  1493. DECLARE_SC(sc, TEXT("CAMCView::ScExecuteShellCommand"));
  1494. sc = ScCheckPointers(Command, Directory, Parameters, WindowState);
  1495. if(sc)
  1496. return sc;
  1497. INodeCallback *pNodeCallback = GetNodeCallback();
  1498. HNODE hNodeSel = GetSelectedNode();
  1499. sc = ScCheckPointers(pNodeCallback, hNodeSel, E_UNEXPECTED);
  1500. if(sc)
  1501. return sc;
  1502. sc = pNodeCallback->ExecuteShellCommand(hNodeSel, Command, Directory, Parameters, WindowState);
  1503. return sc;
  1504. }
  1505. /*+-------------------------------------------------------------------------*
  1506. *
  1507. * CAMCView::Scget_ListViewMode
  1508. *
  1509. * PURPOSE: Returns the list view mode, if available.
  1510. *
  1511. * PARAMETERS:
  1512. * ListViewMode * pMode :
  1513. *
  1514. * RETURNS:
  1515. * STDMETHODIMP
  1516. *
  1517. *+-------------------------------------------------------------------------*/
  1518. SC
  1519. CAMCView::Scget_ListViewMode(PLISTVIEWMODE pMode)
  1520. {
  1521. DECLARE_SC(sc, TEXT("CAMCView::Scget_ListViewMode"));
  1522. // check parameter
  1523. if(!pMode)
  1524. {
  1525. sc = E_INVALIDARG;
  1526. return sc;
  1527. }
  1528. if (!HasList())
  1529. return (ScFromMMC(MMC_E_NOLIST));
  1530. int mode = 0;
  1531. // translate it into an automation friendly enum
  1532. switch(GetViewMode())
  1533. {
  1534. default:
  1535. ASSERT( 0 && "Should not come here");
  1536. // fall thru.
  1537. case LVS_LIST:
  1538. *pMode = ListMode_List;
  1539. break;
  1540. case LVS_ICON:
  1541. *pMode = ListMode_Large_Icons;
  1542. break;
  1543. case LVS_SMALLICON:
  1544. *pMode = ListMode_Small_Icons;
  1545. break;
  1546. case LVS_REPORT:
  1547. *pMode = ListMode_Detail;
  1548. break;
  1549. case MMCLV_VIEWSTYLE_FILTERED:
  1550. *pMode = ListMode_Filtered;
  1551. break;
  1552. }
  1553. return sc;
  1554. }
  1555. /*+-------------------------------------------------------------------------*
  1556. *
  1557. * CAMCView::Scput_ListViewMode
  1558. *
  1559. * PURPOSE: Sets the list mode to the specified mode.
  1560. *
  1561. * PARAMETERS:
  1562. * ListViewMode mode :
  1563. *
  1564. * RETURNS:
  1565. * STDMETHODIMP
  1566. *
  1567. *+-------------------------------------------------------------------------*/
  1568. SC
  1569. CAMCView::Scput_ListViewMode(ListViewMode mode)
  1570. {
  1571. DECLARE_SC(sc, TEXT("CAMCView::Scput_ListViewMode"));
  1572. int nMode;
  1573. if (!HasList())
  1574. return (ScFromMMC(MMC_E_NOLIST));
  1575. switch (mode)
  1576. {
  1577. default:
  1578. sc = E_INVALIDARG;
  1579. return sc;
  1580. case ListMode_List:
  1581. nMode = LVS_LIST;
  1582. break;
  1583. case ListMode_Detail:
  1584. nMode = LVS_REPORT;
  1585. break;
  1586. case ListMode_Large_Icons:
  1587. nMode = LVS_ICON;
  1588. break;
  1589. case ListMode_Small_Icons:
  1590. nMode = LVS_SMALLICON;
  1591. break;
  1592. case ListMode_Filtered:
  1593. nMode = MMCLV_VIEWSTYLE_FILTERED;
  1594. break;
  1595. }
  1596. sc = ScChangeViewMode(nMode);
  1597. return sc;
  1598. }
  1599. /*+-------------------------------------------------------------------------*
  1600. *
  1601. * CAMCView::ScBack
  1602. *
  1603. * PURPOSE: Invokes the Back command on the view.
  1604. *
  1605. * RETURNS:
  1606. * SC
  1607. *
  1608. *+-------------------------------------------------------------------------*/
  1609. SC
  1610. CAMCView::ScBack()
  1611. {
  1612. DECLARE_SC(sc, TEXT("CAMCView::ScBack"));
  1613. sc = ScWebCommand(CConsoleView::eWeb_Back);
  1614. return sc;
  1615. }
  1616. /*+-------------------------------------------------------------------------*
  1617. *
  1618. * CAMCView::ScForward
  1619. *
  1620. * PURPOSE: Invokes the Forward command on the view.
  1621. *
  1622. * RETURNS:
  1623. * SC
  1624. *
  1625. *+-------------------------------------------------------------------------*/
  1626. SC
  1627. CAMCView::ScForward()
  1628. {
  1629. DECLARE_SC(sc, TEXT("CAMCView::ScForward"));
  1630. sc = ScWebCommand(CConsoleView::eWeb_Forward);
  1631. return sc;
  1632. }
  1633. /*+-------------------------------------------------------------------------*
  1634. *
  1635. * CAMCView::Scput_StatusBarText
  1636. *
  1637. * PURPOSE: Sets the status bar text for the view
  1638. *
  1639. * PARAMETERS:
  1640. * BSTR StatusBarText :
  1641. *
  1642. * RETURNS:
  1643. * SC
  1644. *
  1645. *+-------------------------------------------------------------------------*/
  1646. SC
  1647. CAMCView::Scput_StatusBarText(BSTR StatusBarText)
  1648. {
  1649. DECLARE_SC(sc, TEXT("CAMCView::Scput_StatusBarText"));
  1650. // check the in parameter
  1651. sc = ScCheckPointers(StatusBarText);
  1652. if(sc)
  1653. return sc;
  1654. CConsoleStatusBar *pStatusBar = m_ViewData.GetStatusBar();
  1655. sc = ScCheckPointers(pStatusBar, E_UNEXPECTED);
  1656. if(sc)
  1657. return sc;
  1658. USES_CONVERSION;
  1659. // set the status text
  1660. sc = pStatusBar->ScSetStatusText(OLE2T(StatusBarText));
  1661. return sc;
  1662. }
  1663. /*+-------------------------------------------------------------------------*
  1664. *
  1665. * CAMCView::Scget_Memento
  1666. *
  1667. * PURPOSE: Returns the XML version of the memento for the current view.
  1668. *
  1669. * PARAMETERS:
  1670. * PBSTR Memento : [out]: The memento
  1671. *
  1672. * RETURNS:
  1673. * SC
  1674. *
  1675. *+-------------------------------------------------------------------------*/
  1676. SC
  1677. CAMCView::Scget_Memento(PBSTR Memento)
  1678. {
  1679. DECLARE_SC(sc, TEXT("CAMCView::Scget_Memento"));
  1680. sc = ScCheckPointers(Memento);
  1681. if(sc)
  1682. return sc;
  1683. // initialize the out parameter
  1684. *Memento = NULL;
  1685. CMemento memento;
  1686. sc = ScInitializeMemento(memento);
  1687. if(sc)
  1688. return sc;
  1689. std::wstring xml_contents;
  1690. sc = memento.ScSaveToString(&xml_contents);
  1691. if(sc)
  1692. return sc.ToHr();
  1693. // store the result
  1694. CComBSTR bstrBuff(xml_contents.c_str());
  1695. *Memento = bstrBuff.Detach();
  1696. return sc;
  1697. }
  1698. /*+-------------------------------------------------------------------------*
  1699. *
  1700. * CAMCView::ScViewMemento
  1701. *
  1702. * PURPOSE: Sets the view from the specified XML memento.
  1703. *
  1704. * PARAMETERS:
  1705. * BSTR Memento :
  1706. *
  1707. * RETURNS:
  1708. * SC
  1709. *
  1710. *+-------------------------------------------------------------------------*/
  1711. SC
  1712. CAMCView::ScViewMemento(BSTR Memento)
  1713. {
  1714. DECLARE_SC(sc, TEXT("CAMCView::ScViewMemento"));
  1715. sc = ScCheckPointers(Memento);
  1716. if(sc)
  1717. return sc;
  1718. CMemento memento;
  1719. sc = memento.ScLoadFromString(Memento);
  1720. if(sc)
  1721. return sc;
  1722. sc = ScViewMemento(&memento);
  1723. if (sc == ScFromMMC(IDS_NODE_NOT_FOUND))
  1724. return (sc = ScFromMMC(IDS_ACTION_COULD_NOTBE_COMPLETED));
  1725. return sc;
  1726. }
  1727. //+-------------------------------------------------------------------
  1728. //
  1729. // Member: CAMCView::Scget_CellContents
  1730. //
  1731. // Synopsis: Given row & column, get the text.
  1732. //
  1733. // Arguments: Node: - the row
  1734. // [Column] - 1 based column index
  1735. // [pbstrCellContents] - return value, contents of cell.
  1736. //
  1737. // Returns: SC
  1738. //
  1739. //--------------------------------------------------------------------
  1740. SC CAMCView::Scget_CellContents (PNODE Node, long Column, PBSTR pbstrCellContents)
  1741. {
  1742. DECLARE_SC(sc, _T("CAMCView::Scget_CellContents"));
  1743. sc = ScCheckPointers(Node, pbstrCellContents);
  1744. if (sc)
  1745. return sc;
  1746. *pbstrCellContents = NULL;
  1747. if (!HasList())
  1748. return (ScFromMMC(MMC_E_NOLIST));
  1749. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  1750. if (sc)
  1751. return sc;
  1752. // No need to check if we are in REPORT mode as columns exist
  1753. // even in other modes (small icon....).
  1754. int iItem = -1;
  1755. sc = m_pListCtrl->ScFindResultItem( Node, iItem );
  1756. if (sc)
  1757. return sc;
  1758. // Script uses 1- based index for columns & rows.
  1759. // ColCount are total # of cols.
  1760. if (m_pListCtrl->GetColCount() < Column)
  1761. return (sc = E_INVALIDARG);
  1762. CListCtrl& ctlList = m_pListCtrl->GetListCtrl();
  1763. CString strData = ctlList.GetItemText(iItem, Column-1 /*convert to zero-based*/);
  1764. *pbstrCellContents = strData.AllocSysString();
  1765. return (sc);
  1766. }
  1767. //+-------------------------------------------------------------------
  1768. //
  1769. // Member: CAMCView::ScExportList
  1770. //
  1771. // Synopsis: Export the list view data to given file with given options.
  1772. //
  1773. // Arguments: [bstrFile] - File to save to.
  1774. // [exportoptions] - (Unicode, tab/comma delimited & selected rows only).
  1775. //
  1776. // Returns: SC
  1777. //
  1778. //--------------------------------------------------------------------
  1779. SC CAMCView::ScExportList (BSTR bstrFile, ExportListOptions exportoptions)
  1780. {
  1781. DECLARE_SC(sc, _T("CAMCView::ScExportList"));
  1782. if (SysStringLen(bstrFile) < 1)
  1783. return (sc = E_INVALIDARG);
  1784. if (!HasList())
  1785. return (ScFromMMC(MMC_E_NOLIST));
  1786. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  1787. if (sc)
  1788. return sc;
  1789. bool bUnicode = (exportoptions & ExportListOptions_Unicode);
  1790. bool bTabDelimited = (exportoptions & ExportListOptions_TabDelimited);
  1791. bool bSelectedRowsOnly = (exportoptions & ExportListOptions_SelectedItemsOnly);
  1792. USES_CONVERSION;
  1793. LPCTSTR lpszFileName = OLE2T(bstrFile);
  1794. sc = ScWriteExportListData(lpszFileName, bUnicode,
  1795. bTabDelimited, bSelectedRowsOnly,
  1796. false /*bShowErrorDialogs*/);
  1797. if (sc)
  1798. return (sc);
  1799. return (sc);
  1800. }
  1801. /*+-------------------------------------------------------------------------*
  1802. *
  1803. * CAMCView::ScClose
  1804. *
  1805. * PURPOSE: Implements Wiew.Close method
  1806. *
  1807. * PARAMETERS:
  1808. *
  1809. * RETURNS:
  1810. * SC
  1811. *
  1812. *+-------------------------------------------------------------------------*/
  1813. SC
  1814. CAMCView::ScClose()
  1815. {
  1816. DECLARE_SC(sc, TEXT("CAMCView::ScClose"));
  1817. // get the frame and the document
  1818. CChildFrame* pFrame = GetParentFrame();
  1819. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  1820. sc= ScCheckPointers(pDoc, pFrame, E_FAIL);
  1821. if (sc)
  1822. return sc;
  1823. // count the views
  1824. int cViews = 0;
  1825. CAMCViewPosition pos = pDoc->GetFirstAMCViewPosition();
  1826. while (pos != NULL)
  1827. {
  1828. CAMCView* pView = pDoc->GetNextAMCView(pos);
  1829. if ((pView != NULL) && ++cViews >= 2)
  1830. break;
  1831. }
  1832. // prevent closing the document this way !!!
  1833. if (cViews == 1)
  1834. {
  1835. sc.FromMMC(IDS_CloseDocNotLastView);
  1836. return sc;
  1837. }
  1838. // if not closing last view, then give it
  1839. // a chance to clean up first.
  1840. // (if whole doc is closing CAMCDoc will handle
  1841. // closing all the views.)
  1842. /*
  1843. * Don't allow the user to close the last persisted view.
  1844. */
  1845. if (IsPersisted() && (pDoc->GetNumberOfPersistedViews() == 1))
  1846. {
  1847. sc.FromMMC(IDS_CantCloseLastPersistableView);
  1848. return sc;
  1849. }
  1850. // checkings done, do close
  1851. // do it indirectly so that it won't hurt the view extension it it
  1852. // tries to close itself
  1853. pFrame->PostMessage(WM_CLOSE);
  1854. return sc;
  1855. }
  1856. /*+-------------------------------------------------------------------------*
  1857. *
  1858. * CAMCView::Scget_ScopeTreeVisible
  1859. *
  1860. * PURPOSE: Implements get method for Wiew.ScopeTreeVisible property
  1861. *
  1862. * PARAMETERS:
  1863. *
  1864. * RETURNS:
  1865. * SC
  1866. *
  1867. *+-------------------------------------------------------------------------*/
  1868. SC
  1869. CAMCView::Scget_ScopeTreeVisible( PBOOL pbVisible )
  1870. {
  1871. DECLARE_SC(sc, TEXT("CAMCView::Scget_ScopeTreeVisible"));
  1872. // parameter check...
  1873. sc = ScCheckPointers(pbVisible);
  1874. if (sc)
  1875. return sc;
  1876. *pbVisible = IsScopePaneVisible();
  1877. return sc;
  1878. }
  1879. /*+-------------------------------------------------------------------------*
  1880. *
  1881. * CAMCView::Scput_ScopeTreeVisible
  1882. *
  1883. * PURPOSE: Implements set method for Wiew.ScopeTreeVisible property
  1884. *
  1885. * PARAMETERS:
  1886. *
  1887. * RETURNS:
  1888. * SC
  1889. *
  1890. *+-------------------------------------------------------------------------*/
  1891. SC
  1892. CAMCView::Scput_ScopeTreeVisible( BOOL bVisible )
  1893. {
  1894. DECLARE_SC(sc, TEXT("CAMCView::Scput_ScopeTreeVisible"));
  1895. // show/hide the scope pane
  1896. sc = ScShowScopePane (bVisible);
  1897. if (sc)
  1898. return (sc);
  1899. return sc;
  1900. }
  1901. /***************************************************************************\
  1902. *
  1903. * METHOD: CAMCView::ScFindResultItemForScopeNode
  1904. *
  1905. * PURPOSE: - Calculates result item representing the scope node in the list
  1906. *
  1907. * PARAMETERS:
  1908. * PNODE pNode - node to search
  1909. * HRESULTITEM &itm - resulting item
  1910. *
  1911. * RETURNS:
  1912. * SC - result code
  1913. *
  1914. \***************************************************************************/
  1915. SC CAMCView::ScFindResultItemForScopeNode( PNODE pNode, HRESULTITEM &itm )
  1916. {
  1917. DECLARE_SC(sc, TEXT("CAMCView::ScFindResultItemForScopeNode"));
  1918. // initialization
  1919. itm = NULL;
  1920. // parameter check
  1921. sc = ScCheckPointers(pNode);
  1922. if (sc)
  1923. return sc;
  1924. // get/check for list view and tree controls and callback
  1925. IScopeTree* const pScopeTree = GetScopeTreePtr();
  1926. sc = ScCheckPointers( pScopeTree, m_pTreeCtrl, m_spNodeCallback, E_UNEXPECTED);
  1927. if (sc)
  1928. return sc;
  1929. // retrieve MTNode
  1930. HMTNODE hMTNode = NULL;
  1931. sc = pScopeTree->GetHMTNode(pNode, &hMTNode);
  1932. if (sc)
  1933. return sc;
  1934. // get the pointer to the map
  1935. CTreeViewMap *pTreeMap = m_pTreeCtrl->GetTreeViewMap();
  1936. sc = ScCheckPointers(pTreeMap, E_UNEXPECTED);
  1937. if (sc)
  1938. return sc;
  1939. // find the tree item for the node
  1940. HTREEITEM htiNode = NULL;
  1941. sc = pTreeMap->ScGetHTreeItemFromHMTNode(hMTNode, &htiNode);
  1942. if (sc)
  1943. return sc = ScFromMMC(MMC_E_RESULT_ITEM_NOT_FOUND);
  1944. // try to match the node to the child of selected one
  1945. HTREEITEM htiParent = m_pTreeCtrl->GetParentItem(htiNode);
  1946. if (htiParent == NULL || htiParent != m_pTreeCtrl->GetSelectedItem())
  1947. return sc = ScFromMMC(MMC_E_RESULT_ITEM_NOT_FOUND);
  1948. // the node shold be in the ListView, lets find if!
  1949. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(htiNode);
  1950. // get result item id
  1951. sc = m_spNodeCallback->GetResultItem (hNode, &itm);
  1952. if (sc)
  1953. return sc;
  1954. return sc;
  1955. }
  1956. /***************************************************************************\
  1957. *
  1958. * METHOD: CAMCView::ScGetScopeNodeForItem
  1959. *
  1960. * PURPOSE: Returns Node (Scope Node) for specified item index
  1961. *
  1962. * PARAMETERS:
  1963. * int nItem - node index to retrieve
  1964. * PPNODE ppNode - result storage
  1965. *
  1966. * RETURNS:
  1967. * SC - result code
  1968. *
  1969. \***************************************************************************/
  1970. SC CAMCView::ScGetScopeNode( HNODE hNode, PPNODE ppNode )
  1971. {
  1972. DECLARE_SC(sc, TEXT("CCCListViewCtrl::ScGetScopeNodeForItem"));
  1973. // check the parameters
  1974. sc = ScCheckPointers(ppNode);
  1975. if (sc)
  1976. return sc;
  1977. // initialize the result
  1978. *ppNode = NULL;
  1979. // get/check required pointers
  1980. IScopeTree* const pScopeTree = GetScopeTreePtr();
  1981. sc = ScCheckPointers(pScopeTree, m_spNodeCallback, E_UNEXPECTED);
  1982. if (sc)
  1983. return sc;
  1984. // find MTNode
  1985. HMTNODE hmtNode;
  1986. sc = m_spNodeCallback->GetMTNode(hNode, &hmtNode);
  1987. if (sc)
  1988. return sc;
  1989. // request the object!
  1990. sc = pScopeTree->GetMMCNode(hmtNode, ppNode);
  1991. if (sc)
  1992. return sc;
  1993. return sc;
  1994. }
  1995. /***************************************************************************\
  1996. *
  1997. * METHOD: CAMCView::Scget_Columns
  1998. *
  1999. * PURPOSE: create new or return pointer to existing Columns object
  2000. *
  2001. * PARAMETERS:
  2002. * PPCOLUMNS ppColumns - resulting (AddRef'ed) pointer
  2003. *
  2004. * RETURNS:
  2005. * SC - result code
  2006. *
  2007. \***************************************************************************/
  2008. SC CAMCView::Scget_Columns(PPCOLUMNS ppColumns)
  2009. {
  2010. DECLARE_SC(sc, TEXT("CAMCView::Scget_Columns"));
  2011. // Check received parameters
  2012. sc = ScCheckPointers(ppColumns);
  2013. if (sc)
  2014. return sc;
  2015. // initialize
  2016. *ppColumns = NULL;
  2017. // Check the pointer to LV
  2018. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  2019. if (sc)
  2020. return sc;
  2021. // forward the request to LV
  2022. sc = m_pListCtrl->Scget_Columns(ppColumns);
  2023. if (sc)
  2024. return sc;
  2025. return sc;
  2026. }
  2027. //+-------------------------------------------------------------------
  2028. //
  2029. // Member: CAMCView::ScGetSelectedLVItem
  2030. //
  2031. // Synopsis: Return the LVItem cookie.
  2032. //
  2033. // Arguments: LPARAM - the LVDATA retval.
  2034. //
  2035. // Returns: SC - Fails if no selected item in LV.
  2036. //
  2037. //--------------------------------------------------------------------
  2038. SC CAMCView::ScGetSelectedLVItem(LPARAM& lvData)
  2039. {
  2040. DECLARE_SC(sc, _T("CAMCView::ScGetSelectedLVItem"));
  2041. lvData = LVDATA_ERROR;
  2042. int cSel = m_pListCtrl->GetSelectedCount();
  2043. if(0 == cSel)
  2044. {
  2045. // no items selected, bail
  2046. return (sc = ScFromMMC(MMC_E_NO_SELECTED_ITEMS));
  2047. }
  2048. else if(1 == cSel)
  2049. {
  2050. // single selection
  2051. int iIndex = _GetLVSelectedItemData(&lvData);
  2052. if (iIndex == -1 || lvData == LVDATA_ERROR)
  2053. return (sc = E_UNEXPECTED);
  2054. if (IsVirtualList())
  2055. {
  2056. // virtual list item in the result pane
  2057. lvData = iIndex;
  2058. }
  2059. }
  2060. else if (cSel > 1)
  2061. {
  2062. // multiselection
  2063. lvData = LVDATA_MULTISELECT;
  2064. }
  2065. return (sc);
  2066. }
  2067. //+-------------------------------------------------------------------
  2068. //
  2069. // Member: CAMCView::ScGetHNodeFromPNode
  2070. //
  2071. // Synopsis: Takes in PNODE and returns corresponding hNode
  2072. //
  2073. // Arguments: [PNODE] - Given pnode.
  2074. // [HNODE] - ret val.
  2075. //
  2076. // Returns: SC
  2077. //
  2078. //--------------------------------------------------------------------
  2079. SC CAMCView::ScGetHNodeFromPNode (const PNODE& pNode, HNODE& hNode)
  2080. {
  2081. DECLARE_SC(sc, _T("CAMCView::ScGetHNodeFromPNode"));
  2082. hNode = NULL;
  2083. CAMCTreeView* pAMCTreeView = GetTreeCtrl();
  2084. sc = ScCheckPointers(pAMCTreeView, E_UNEXPECTED);
  2085. if (sc)
  2086. return sc;
  2087. CTreeViewMap *pTreeMap = pAMCTreeView->GetTreeViewMap();
  2088. IScopeTree *pScopeTree = GetScopeTree();
  2089. sc = ScCheckPointers(pTreeMap, pScopeTree, E_UNEXPECTED);
  2090. if(sc)
  2091. return sc;
  2092. HMTNODE hMTNode = NULL;
  2093. sc = pScopeTree->GetHMTNode(pNode, &hMTNode);
  2094. if(sc)
  2095. return sc;
  2096. sc = pTreeMap->ScGetHNodeFromHMTNode(hMTNode, &hNode);
  2097. if(sc)
  2098. return sc;
  2099. return (sc);
  2100. }
  2101. /*+-------------------------------------------------------------------------*
  2102. *
  2103. * CAMCView::ScGetMMCView
  2104. *
  2105. * PURPOSE: Creates, AddRef's, and returns a pointer to the tied COM object.
  2106. *
  2107. * PARAMETERS:
  2108. * View ** ppView :
  2109. *
  2110. * RETURNS:
  2111. * SC
  2112. *
  2113. *+-------------------------------------------------------------------------*/
  2114. SC
  2115. CAMCView::ScGetMMCView(View **ppView)
  2116. {
  2117. DECLARE_SC(sc, TEXT("CAMCView::ScGetMMCView"));
  2118. sc = ScCheckPointers(ppView);
  2119. if (sc)
  2120. return sc;
  2121. // init out parameter
  2122. *ppView = NULL;
  2123. // create a CMMCView if needed.
  2124. sc = CTiedComObjectCreator<CMMCView>::ScCreateAndConnect(*this, m_spView);
  2125. if(sc)
  2126. return sc;
  2127. if(m_spView == NULL)
  2128. {
  2129. sc = E_UNEXPECTED;
  2130. return sc;
  2131. }
  2132. // addref the pointer for the client.
  2133. m_spView->AddRef();
  2134. *ppView = m_spView;
  2135. return sc;
  2136. }
  2137. /*+-------------------------------------------------------------------------*
  2138. *
  2139. * CAMCView::IsDirty
  2140. *
  2141. * PURPOSE: Determines whether or not CAMCView is in a dirty state
  2142. *
  2143. * RETURNS:
  2144. * bool
  2145. *
  2146. *+-------------------------------------------------------------------------*/
  2147. bool CAMCView::IsDirty()
  2148. {
  2149. bool bRet = m_bDirty;
  2150. if (!m_bDirty && !m_fRootedAtNonPersistedDynamicNode)
  2151. bRet = HasNodeSelChanged();
  2152. TraceDirtyFlag(TEXT("CAMCView"), bRet);
  2153. return (bRet);
  2154. }
  2155. /////////////////////////////////////////////////////////////////////////////
  2156. // CAMCView drawing
  2157. void CAMCView::OnDraw(CDC* pDC)
  2158. {
  2159. if (IsScopePaneVisible())
  2160. {
  2161. pDC->FillRect (m_rectVSplitter, AMCGetSysColorBrush (COLOR_3DFACE));
  2162. }
  2163. }
  2164. /////////////////////////////////////////////////////////////////////////////
  2165. // CAMCView printing
  2166. BOOL CAMCView::OnPreparePrinting(CPrintInfo* pInfo)
  2167. {
  2168. TRACE_METHOD(CAMCView, OnPreparePrinting);
  2169. // default preparation
  2170. return DoPreparePrinting(pInfo);
  2171. }
  2172. void CAMCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  2173. {
  2174. TRACE_METHOD(CAMCView, OnBeginPrinting);
  2175. }
  2176. void CAMCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  2177. {
  2178. TRACE_METHOD(CAMCView, OnEndPrinting);
  2179. }
  2180. /////////////////////////////////////////////////////////////////////////////
  2181. // CAMCView diagnostics
  2182. #ifdef _DEBUG
  2183. void CAMCView::AssertValid() const
  2184. {
  2185. CView::AssertValid();
  2186. }
  2187. void CAMCView::Dump(CDumpContext& dc) const
  2188. {
  2189. CView::Dump(dc);
  2190. }
  2191. CAMCDoc* CAMCView::GetDocument() // non-debug version is inline
  2192. {
  2193. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAMCDoc)));
  2194. return (CAMCDoc*)m_pDocument;
  2195. }
  2196. #endif //_DEBUG
  2197. /////////////////////////////////////////////////////////////////////////////
  2198. // CAMCView message handlers
  2199. //+-------------------------------------------------------------------------
  2200. //
  2201. // Function: PreCreateWindow
  2202. //
  2203. // Synopsis: Create new window class (CAMCView) - WS_EX_CLIENTEDGE
  2204. //
  2205. //--------------------------------------------------------------------------
  2206. BOOL CAMCView::PreCreateWindow(CREATESTRUCT& cs)
  2207. {
  2208. cs.style |= WS_CLIPCHILDREN;
  2209. cs.style &= ~WS_BORDER;
  2210. // give base class a chance to do own job
  2211. BOOL bOK = (CView::PreCreateWindow(cs));
  2212. // register view class
  2213. LPCTSTR pszViewClassName = g_szAMCViewWndClassName;
  2214. // try to register window class which does not cause the repaint
  2215. // on resizing (do it only once)
  2216. static bool bClassRegistered = false;
  2217. if ( !bClassRegistered )
  2218. {
  2219. WNDCLASS wc;
  2220. if (::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc))
  2221. {
  2222. // Clear the H and V REDRAW flags
  2223. wc.style &= ~(CS_HREDRAW | CS_VREDRAW);
  2224. wc.lpszClassName = pszViewClassName;
  2225. // Register this new class;
  2226. bClassRegistered = AfxRegisterClass(&wc);
  2227. }
  2228. }
  2229. // change window class to one which does not cause the repaint
  2230. // on resizing if we successfully registered such
  2231. if ( bClassRegistered )
  2232. cs.lpszClass = pszViewClassName;
  2233. return bOK;
  2234. }
  2235. //+-------------------------------------------------------------------------
  2236. //
  2237. // Function: OnCreate
  2238. //
  2239. // Synopsis: Create Window, and Tree control / Default List control
  2240. //
  2241. //--------------------------------------------------------------------------
  2242. int CAMCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2243. {
  2244. DECLARE_SC(sc, _T("CAMCView::OnCreate"));
  2245. if (CView::OnCreate(lpCreateStruct) == -1)
  2246. {
  2247. sc = E_FAIL;
  2248. return -1;
  2249. }
  2250. CChildFrame* pFrame = GetParentFrame();
  2251. ASSERT(NULL != pFrame);
  2252. if (pFrame)
  2253. pFrame->SetAMCView(this);
  2254. m_ViewData.SetStatusBar (dynamic_cast<CConsoleStatusBar*>(pFrame));
  2255. m_ViewData.SetConsoleView (this);
  2256. m_RightDescCtrl.Create (NULL, WS_CHILD, g_rectEmpty, this, IDC_RightDescBar);
  2257. ASSERT (m_pDocument != NULL);
  2258. ASSERT (m_pDocument == CAMCDoc::GetDocument());
  2259. ASSERT_KINDOF (CAMCDoc, m_pDocument);
  2260. CAMCDoc* pAMCDoc = reinterpret_cast<CAMCDoc *>(m_pDocument);
  2261. CCreateContext* pContext = (CCreateContext*) lpCreateStruct->lpCreateParams;
  2262. ASSERT (pContext != NULL);
  2263. // Set window options
  2264. m_ViewData.m_lWindowOptions = pAMCDoc->GetNewWindowOptions();
  2265. /*
  2266. * If the scope pane is suppressed, clear the scope-visible flag.
  2267. * It's not necessary to call ScShowScopePane here because none of
  2268. * the windows have been created yet. We just need to keep our
  2269. * interal accounting correct.
  2270. */
  2271. if (m_ViewData.m_lWindowOptions & MMC_NW_OPTION_NOSCOPEPANE)
  2272. SetScopePaneVisible (false);
  2273. // Create tree ctrl.
  2274. if (!CreateView (IDC_TreeView) || (!m_pTreeCtrl) )
  2275. {
  2276. sc = E_FAIL;
  2277. return -1;
  2278. }
  2279. SetPane(ePane_ScopeTree, m_pTreeCtrl, uiClientEdge);
  2280. if (!AreStdToolbarsAllowed())
  2281. m_ViewData.m_dwToolbarsDisplayed &= ~(STD_MENUS | STD_BUTTONS);
  2282. // Create default list control
  2283. if (!CreateListCtrl (IDC_ListView, pContext))
  2284. {
  2285. sc = E_FAIL;
  2286. return -1;
  2287. }
  2288. // Create the folder tab control
  2289. if (!CreateFolderCtrls ())
  2290. {
  2291. sc = E_FAIL;
  2292. return -1;
  2293. }
  2294. // initialize the result pane to the list view
  2295. {
  2296. CResultViewType rvt;
  2297. sc = ScSetResultPane(NULL /*HNODE*/, rvt, MMCLV_VIEWSTYLE_REPORT /*viewMode*/, false /*bUsingHistory*/);
  2298. if(sc)
  2299. return -1;
  2300. }
  2301. sc = ScCreateToolbarObjects();
  2302. if (sc)
  2303. return -1;
  2304. //
  2305. // Set m_ViewData.
  2306. //
  2307. m_ViewData.m_nViewID = 0;// Set in OnInitialUpdate
  2308. VERIFY ((m_ViewData.m_spNodeManager = m_pTreeCtrl->m_spNodeManager) != NULL);
  2309. VERIFY ((m_ViewData.m_spResultData = m_pTreeCtrl->m_spResultData) != NULL);
  2310. VERIFY ((m_ViewData.m_spRsltImageList = m_pTreeCtrl->m_spRsltImageList) != NULL);
  2311. VERIFY ( m_ViewData.m_hwndView = m_hWnd);
  2312. VERIFY ( m_ViewData.m_hwndListCtrl = m_pListCtrl->GetListViewHWND());
  2313. VERIFY ( m_ViewData.m_pConsoleData = GetDocument()->GetConsoleData());
  2314. m_ViewData.m_pMultiSelection = NULL;
  2315. if(pFrame)
  2316. {
  2317. // add the MDIClient window's taskbar as an observer
  2318. CMDIFrameWnd * pFrameWnd = pFrame->GetMDIFrame();
  2319. CWnd *pWnd = NULL;
  2320. if(pFrameWnd)
  2321. pWnd = pFrameWnd->GetWindow(GW_CHILD); // get the first child of the frame.
  2322. }
  2323. // add AMCDoc as an observer for this source (object)
  2324. CAMCApp *pCAMCApp = AMCGetApp();
  2325. if ( pCAMCApp )
  2326. AddObserver(*static_cast<CAMCViewObserver *>(pCAMCApp));
  2327. // fire the view creation event to all observers.
  2328. sc = ScFireEvent(CAMCViewObserver::ScOnViewCreated, this);
  2329. if(sc)
  2330. sc.TraceAndClear();
  2331. return 0;
  2332. }
  2333. /*+-------------------------------------------------------------------------*
  2334. *
  2335. * CAMCView::CreateFolderCtrls
  2336. *
  2337. * PURPOSE: Creates the tabbed folder controls for the scope and result panes.
  2338. *
  2339. * RETURNS:
  2340. * bool
  2341. *
  2342. *+-------------------------------------------------------------------------*/
  2343. bool
  2344. CAMCView::CreateFolderCtrls()
  2345. {
  2346. if (!m_pResultFolderTabView->Create (WS_CHILD|WS_VISIBLE, g_rectEmpty, this, IDC_ResultTabCtrl))
  2347. return false;
  2348. // add the views to the framework
  2349. GetDocument()->AddView(m_pResultFolderTabView);
  2350. return true;
  2351. }
  2352. /*+-------------------------------------------------------------------------*
  2353. * CAMCView::CreateView
  2354. *
  2355. * This was copied largely from CFrameWnd::CreateView. We need to duplicate
  2356. * it here so common control-based views are initially created with the
  2357. * correct parent. A common control caches its original parent, so
  2358. * using CFrameWnd::CreateView (which will create the view with the frame
  2359. * as its parent) then reparenting to CAMCView will result in the common
  2360. * control caching the wrong parent.
  2361. *--------------------------------------------------------------------------*/
  2362. CView* CAMCView::CreateView (CCreateContext* pContext, int nID, DWORD dwStyle)
  2363. {
  2364. ASSERT(m_hWnd != NULL);
  2365. ASSERT(::IsWindow(m_hWnd));
  2366. ASSERT(pContext != NULL);
  2367. ASSERT(pContext->m_pNewViewClass != NULL);
  2368. CView* pView = (CView*)pContext->m_pNewViewClass->CreateObject();
  2369. if (pView == NULL)
  2370. {
  2371. TRACE1("Warning: Dynamic create of view type %hs failed.\n",
  2372. pContext->m_pNewViewClass->m_lpszClassName);
  2373. return NULL;
  2374. }
  2375. ASSERT_KINDOF(CView, pView);
  2376. // views are always created with a border!
  2377. if (!pView->Create (NULL, NULL, AFX_WS_DEFAULT_VIEW | dwStyle,
  2378. g_rectEmpty, this, nID, pContext))
  2379. {
  2380. TRACE0("Warning: could not create view for frame.\n");
  2381. return NULL; // can't continue without a view
  2382. }
  2383. return pView;
  2384. }
  2385. /*+-------------------------------------------------------------------------*
  2386. * CAMCView::CreateView
  2387. *
  2388. *
  2389. *--------------------------------------------------------------------------*/
  2390. bool CAMCView::CreateView (int nID)
  2391. {
  2392. struct CreateViewData
  2393. {
  2394. int nID;
  2395. CRuntimeClass* pClass;
  2396. CView** ppView;
  2397. DWORD dwStyle;
  2398. };
  2399. CreateViewData rgCreateViewData[] =
  2400. {
  2401. { IDC_TreeView,
  2402. RUNTIME_CLASS(CAMCTreeView),
  2403. (CView**)&m_pTreeCtrl,
  2404. 0 },
  2405. { IDC_OCXHostView,
  2406. RUNTIME_CLASS(COCXHostView),
  2407. (CView**)&m_pOCXHostView,
  2408. 0 },
  2409. { IDC_WebViewCtrl,
  2410. RUNTIME_CLASS(CAMCWebViewCtrl),
  2411. (CView**)&m_pWebViewCtrl,
  2412. CAMCWebViewCtrl::WS_HISTORY | CAMCWebViewCtrl::WS_SINKEVENTS},
  2413. { IDC_ViewExtensionView,
  2414. RUNTIME_CLASS(CAMCWebViewCtrl),
  2415. (CView**)&m_pViewExtensionCtrl,
  2416. WS_CLIPSIBLINGS },
  2417. };
  2418. for (int i = 0; i < countof (rgCreateViewData); i++)
  2419. {
  2420. if (rgCreateViewData[i].nID == nID)
  2421. {
  2422. CCreateContext ctxt;
  2423. ZeroMemory (&ctxt, sizeof (ctxt));
  2424. ctxt.m_pCurrentDoc = GetDocument();
  2425. ctxt.m_pNewViewClass = rgCreateViewData[i].pClass;
  2426. CView*& pView = *rgCreateViewData[i].ppView;
  2427. ASSERT (pView == NULL);
  2428. pView = CreateView (&ctxt, nID, rgCreateViewData[i].dwStyle);
  2429. ASSERT ((pView != NULL) && "Check the debug output window");
  2430. // Add observers only to tree, ocx and web hosts. Do not add to view extension host
  2431. // as we do not care about its activation/deactivations.
  2432. switch (nID)
  2433. {
  2434. case IDC_TreeView:
  2435. // set the view and the description bar as observers of the tree view control
  2436. m_pTreeCtrl->AddObserver(static_cast<CTreeViewObserver &>(*this));
  2437. m_pTreeCtrl->AddObserver(static_cast<CTreeViewObserver &>(m_RightDescCtrl));
  2438. break;
  2439. case IDC_OCXHostView:
  2440. m_pOCXHostView->AddObserver(static_cast<COCXHostActivationObserver &>(*this));
  2441. break;
  2442. case IDC_WebViewCtrl:
  2443. m_pWebViewCtrl->AddObserver(static_cast<COCXHostActivationObserver &>(*this));
  2444. break;
  2445. }
  2446. return (pView != NULL);
  2447. }
  2448. }
  2449. ASSERT (false && "Missing an entry in rgCreateViewData");
  2450. return (false);
  2451. }
  2452. /*+-------------------------------------------------------------------------*
  2453. * CAMCView::GetActiveView
  2454. *
  2455. *
  2456. *--------------------------------------------------------------------------*/
  2457. CAMCView* CAMCView::GetActiveView()
  2458. {
  2459. return NULL;
  2460. }
  2461. /*+-------------------------------------------------------------------------*
  2462. * CAMCView::ScChangeViewMode
  2463. *
  2464. *
  2465. *--------------------------------------------------------------------------*/
  2466. SC CAMCView::ScChangeViewMode (int nNewMode)
  2467. {
  2468. AFX_MANAGE_STATE (AfxGetAppModuleState());
  2469. DECLARE_SC (sc, _T("CAMCView::OnViewModeChange"));
  2470. // if switching from a custom view, force a reselect
  2471. if (!HasListOrListPad())
  2472. {
  2473. NavState state = m_pHistoryList->GetNavigateState();
  2474. m_pHistoryList->SetNavigateState (MMC_HISTORY_BUSY);
  2475. PrivateChangeListViewMode(nNewMode);
  2476. m_pHistoryList->SetNavigateState (state);
  2477. sc = m_pTreeCtrl->ScReselect();
  2478. if (sc)
  2479. return sc;
  2480. }
  2481. else
  2482. {
  2483. int nCurMode = m_pListCtrl->GetViewMode();
  2484. if ( (nNewMode == MMCLV_VIEWSTYLE_FILTERED) &&
  2485. (!(GetListOptions() & RVTI_LIST_OPTIONS_FILTERED)) )
  2486. return (sc = E_INVALIDARG);
  2487. PrivateChangeListViewMode(nNewMode);
  2488. // if filter state change, notify the snap-in
  2489. if ( ((nCurMode == MMCLV_VIEWSTYLE_FILTERED) != (nNewMode == MMCLV_VIEWSTYLE_FILTERED))
  2490. && (GetListOptions() & RVTI_LIST_OPTIONS_FILTERED))
  2491. {
  2492. HNODE hNodeSel = GetSelectedNode();
  2493. ASSERT(hNodeSel != NULL);
  2494. m_spNodeCallback->Notify(hNodeSel, NCLBK_FILTER_CHANGE,
  2495. (nNewMode == MMCLV_VIEWSTYLE_FILTERED) ? MFCC_ENABLE : MFCC_DISABLE, 0);
  2496. }
  2497. }
  2498. return (sc);
  2499. }
  2500. /*+-------------------------------------------------------------------------*
  2501. * CAMCView::ViewMmento
  2502. *
  2503. *
  2504. *--------------------------------------------------------------------------*/
  2505. SC CAMCView::ScViewMemento(CMemento* pMemento)
  2506. {
  2507. DECLARE_SC (sc, TEXT("CAMCView::ScViewMemento"));
  2508. sc = ScCheckPointers(pMemento);
  2509. if (sc)
  2510. return sc;
  2511. AFX_MANAGE_STATE (AfxGetAppModuleState());
  2512. IScopeTree* const pScopeTree = GetScopeTreePtr();
  2513. sc = ScCheckPointers(pScopeTree, E_UNEXPECTED);
  2514. if (sc)
  2515. return sc;
  2516. MTNODEID NodeId = 0;
  2517. CBookmark& bm = pMemento->GetBookmark();
  2518. ASSERT(bm.IsValid());
  2519. // We want to display message if exact favorite item cannot be selected.
  2520. bool bExactMatchFound = false; // out value from GetNodeIDFromBookmark.
  2521. sc = pScopeTree->GetNodeIDFromBookmark( bm, &NodeId, bExactMatchFound);
  2522. if(sc)
  2523. return sc;
  2524. if (! bExactMatchFound)
  2525. return ScFromMMC(IDS_NODE_NOT_FOUND); // do not trace
  2526. INodeCallback *pNodeCallback = GetNodeCallback();
  2527. sc = ScCheckPointers(pNodeCallback, E_UNEXPECTED);
  2528. if (sc)
  2529. return sc;
  2530. // set the persisted information to the saved settings.
  2531. sc = pNodeCallback->SetViewSettings(GetViewID(),
  2532. reinterpret_cast<HBOOKMARK>(&bm),
  2533. reinterpret_cast<HVIEWSETTINGS>(&pMemento->GetViewSettings()));
  2534. if (sc)
  2535. return sc;
  2536. sc = ScSelectNode(NodeId, /*bSelectExactNode*/ true);
  2537. if (sc == ScFromMMC(IDS_NODE_NOT_FOUND))
  2538. {
  2539. SC scNoTrace = sc;
  2540. sc.Clear();
  2541. return scNoTrace;
  2542. }
  2543. if (sc)
  2544. return sc;
  2545. return sc;
  2546. }
  2547. /*+-------------------------------------------------------------------------*
  2548. * CAMCView::OnSetFocus
  2549. *
  2550. * WM_SETFOCUS handler for CAMCView.
  2551. *--------------------------------------------------------------------------*/
  2552. void CAMCView::OnSetFocus(CWnd* pOldWnd)
  2553. {
  2554. /*
  2555. * try to deflect the activation to a child view; if we couldn't just punt
  2556. */
  2557. if (!DeflectActivation (true, NULL))
  2558. CView::OnSetFocus(pOldWnd);
  2559. }
  2560. /*+-------------------------------------------------------------------------*
  2561. * CAMCView::OnActivateView
  2562. *
  2563. *
  2564. *--------------------------------------------------------------------------*/
  2565. void CAMCView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
  2566. {
  2567. /*
  2568. * try to deflect the activation to a child view; if we couldn't just punt
  2569. */
  2570. if (!DeflectActivation (bActivate, pDeactiveView))
  2571. CView::OnActivateView (bActivate, pActivateView, pDeactiveView);
  2572. }
  2573. /*+-------------------------------------------------------------------------*
  2574. * CAMCView::DeflectActivation
  2575. *
  2576. *
  2577. *--------------------------------------------------------------------------*/
  2578. bool CAMCView::DeflectActivation (BOOL fActivate, CView* pDeactivatingView)
  2579. {
  2580. if (fActivate)
  2581. {
  2582. CFrameWnd* pFrame = GetParentFrame();
  2583. if (pFrame == NULL)
  2584. return (false);
  2585. /*
  2586. * first try to put the focus back on the deactivating view
  2587. */
  2588. if (pDeactivatingView == NULL)
  2589. pDeactivatingView = pFrame->GetActiveView();
  2590. if ((pDeactivatingView != NULL) && (pDeactivatingView != this))
  2591. {
  2592. pFrame->SetActiveView (pDeactivatingView);
  2593. return true;
  2594. }
  2595. /*
  2596. * otherwise, deflect the activation to the scope view, if it's there
  2597. */
  2598. CView* pScopeView = NULL;
  2599. if (IsScopePaneVisible() && ((pScopeView = GetPaneView(ePane_ScopeTree)) != NULL))
  2600. {
  2601. if (IsWindow (pScopeView->GetSafeHwnd()))
  2602. {
  2603. pFrame->SetActiveView (pScopeView);
  2604. return (true);
  2605. }
  2606. }
  2607. /*
  2608. * finally, no scope view, try the result view
  2609. */
  2610. CView* pResultView = GetResultView();
  2611. if (pResultView != NULL)
  2612. {
  2613. pFrame->SetActiveView(pResultView);
  2614. return (true);
  2615. }
  2616. }
  2617. return (false);
  2618. }
  2619. //+-------------------------------------------------------------------------
  2620. //
  2621. // Function: OnLButtonDown
  2622. //
  2623. // Synopsis: If mouse down in splitter area initiate view tracker to move
  2624. // the splitter. (TrackerCallback function handles completion)
  2625. //--------------------------------------------------------------------------
  2626. void CAMCView::OnLButtonDown(UINT nFlags, CPoint pt)
  2627. {
  2628. TRACE_METHOD(CAMCView, OnLButtonDown);
  2629. // click in splitter bar?
  2630. if (!m_rectVSplitter.PtInRect(pt))
  2631. return;
  2632. // setup tracker information
  2633. TRACKER_INFO trkinfo;
  2634. // range is client area
  2635. GetClientRect(trkinfo.rectArea);
  2636. // bound by min size of panes
  2637. trkinfo.rectBounds = trkinfo.rectArea;
  2638. trkinfo.rectBounds.left += m_PaneInfo[ePane_ScopeTree].cxMin;
  2639. trkinfo.rectBounds.right -= m_PaneInfo[ePane_Results].cxMin;
  2640. // Current tracker is splitter rect
  2641. trkinfo.rectTracker = trkinfo.rectArea;
  2642. trkinfo.rectTracker.left = m_PaneInfo[ePane_ScopeTree].cx;
  2643. trkinfo.rectTracker.right = trkinfo.rectTracker.left + m_cxSplitter;
  2644. // Don't allow either pane to be hidden by dragging the splitter
  2645. trkinfo.bAllowLeftHide = FALSE;
  2646. trkinfo.bAllowRightHide = FALSE;
  2647. // back ptr and completion callback
  2648. trkinfo.pView = this;
  2649. trkinfo.pCallback = TrackerCallback;
  2650. // initiate tracking
  2651. CViewTracker::StartTracking (&trkinfo);
  2652. }
  2653. void CAMCView::AdjustTracker (int cx, int cy)
  2654. { // if user resizes window so that splitter becomes hidden,
  2655. // move it like Explorer does.
  2656. if (!IsScopePaneVisible())
  2657. return;
  2658. // extra adjustment
  2659. cx -= BORDERPADDING + 1;
  2660. if (cx <= m_PaneInfo[ePane_ScopeTree].cx + m_cxSplitter)
  2661. {
  2662. int offset = m_PaneInfo[ePane_ScopeTree].cx + m_cxSplitter - cx;
  2663. m_PaneInfo[ePane_ScopeTree].cx -= offset;
  2664. m_PaneInfo[ePane_Results].cx -= offset;
  2665. RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
  2666. }
  2667. }
  2668. /*+-------------------------------------------------------------------------*
  2669. *
  2670. * CAMCView::ScAddDefaultColumns
  2671. *
  2672. * PURPOSE:
  2673. *
  2674. * RETURNS:
  2675. * SC
  2676. *
  2677. *+-------------------------------------------------------------------------*/
  2678. SC
  2679. CAMCView::ScAddDefaultColumns()
  2680. {
  2681. DECLARE_SC(sc, TEXT("CAMCView::ScAddDefaultColumns"));
  2682. IHeaderCtrlPtr spHeaderCtrl = m_ViewData.m_spNodeManager;
  2683. sc = ScCheckPointers(spHeaderCtrl, E_UNEXPECTED);
  2684. if(sc)
  2685. return sc;
  2686. SetUsingDefColumns(TRUE);
  2687. const int INDEX_MAX = 2;
  2688. CString str[INDEX_MAX];
  2689. LoadString(str[0], IDS_NAME);
  2690. LoadString(str[1], IDS_TYPE);
  2691. int iMax = 0;
  2692. int nMax = str[0].GetLength();
  2693. int nTemp = 0;
  2694. for (int i=1; i < INDEX_MAX; i++)
  2695. {
  2696. nTemp = str[i].GetLength();
  2697. if (nTemp > nMax)
  2698. {
  2699. nMax = nTemp;
  2700. iMax = i;
  2701. }
  2702. }
  2703. LPOLESTR psz = new OLECHAR[nMax + 1];
  2704. int alWidths[INDEX_MAX] = {0, 0};
  2705. GetDefaultColumnWidths(alWidths);
  2706. for (i=0; i < INDEX_MAX; i++)
  2707. {
  2708. // Bug 157408: remove the "Type" column for static nodes
  2709. if (i == 1)
  2710. continue;
  2711. USES_CONVERSION;
  2712. wcscpy(psz, T2COLE( (LPCTSTR) str[i] ));
  2713. sc = spHeaderCtrl->InsertColumn(i, psz, LVCFMT_LEFT, alWidths[i]);
  2714. if(sc)
  2715. return sc;
  2716. }
  2717. delete [] psz;
  2718. return sc;
  2719. }
  2720. SC
  2721. CAMCView::ScInitDefListView(LPUNKNOWN pUnkResultsPane)
  2722. {
  2723. DECLARE_SC(sc, TEXT("CAMCView::ScInitDefListView"));
  2724. if (!HasList())
  2725. return (sc = E_UNEXPECTED);
  2726. sc = ScCheckPointers(pUnkResultsPane, m_ViewData.m_spResultData, E_UNEXPECTED);
  2727. if(sc)
  2728. return sc;
  2729. m_ViewData.m_spResultData->ResetResultData();
  2730. return sc;
  2731. }
  2732. /*+-------------------------------------------------------------------------*
  2733. *
  2734. * CAMCView::ScOnSelectNode
  2735. *
  2736. * Most of this code was moved out of CAMCTreeView::OnSelectNode, as it is
  2737. * more appropriate that this is executed by CAMCView.
  2738. *
  2739. * PURPOSE: Called when an item in the tree is selected. Does the following:
  2740. * 1) Sets up the result pane to either a list, and OCX, or a web page.
  2741. * 2) Sets the view options
  2742. * 3) Sends a selection notification to the node.
  2743. * 3) Adds a history entry if needed.
  2744. *
  2745. * PARAMETERS:
  2746. * HNODE hNode : [IN]: The node that got selected.
  2747. * BOOL & bAddSubFolders : [OUT]: Whether subfolders should be added to the list
  2748. *
  2749. * RETURNS:
  2750. * SC
  2751. *
  2752. *+-------------------------------------------------------------------------*/
  2753. SC
  2754. CAMCView::ScOnSelectNode(HNODE hNode, BOOL &bAddSubFolders)
  2755. {
  2756. DECLARE_SC(sc, TEXT("CAMCView::ScOnSelectNode"));
  2757. USES_CONVERSION;
  2758. //
  2759. // Set the result pane
  2760. //
  2761. LPOLESTR pszResultPane = NULL;
  2762. GUID guidTaskpad = GUID_NULL;
  2763. int lViewMode = MMCLV_VIEWSTYLE_REPORT; // the default view mode
  2764. //long lViewOptions = MMC_VIEW_OPTIONS_NONE;
  2765. bool bUsingHistory = false;
  2766. bool bRestoredView = false;
  2767. INodeCallback* spNodeCallBack = GetNodeCallback();
  2768. sc = ScCheckPointers(spNodeCallBack, E_UNEXPECTED);
  2769. if (sc)
  2770. return sc;
  2771. CHistoryList* pHistoryList = GetHistoryList();
  2772. sc = ScCheckPointers(pHistoryList, E_UNEXPECTED);
  2773. if (sc)
  2774. return sc;
  2775. CResultViewType rvt;
  2776. if (pHistoryList->GetNavigateState() == MMC_HISTORY_NAVIGATING)
  2777. {
  2778. // we're going "back" or "forward":
  2779. // get Result pane stuff from history
  2780. bUsingHistory = true;
  2781. sc = pHistoryList->ScGetCurrentResultViewType(rvt, lViewMode, guidTaskpad);
  2782. if (sc)
  2783. return sc;
  2784. sc = spNodeCallBack->RestoreResultView(hNode, rvt);
  2785. if (sc)
  2786. {
  2787. TraceError(_T("Snapin failed on NCLBK_RESTORE_VIEW\n"), sc);
  2788. sc.Clear(); // Compatible with 1.2 dont need this error.
  2789. }
  2790. if (sc.ToHr() == S_OK)
  2791. bRestoredView = true;
  2792. else
  2793. rvt = CResultViewType(); // this restores rvt back to a nascent state. see Bug 176058.
  2794. }
  2795. // The view is not restored by history so ask snapin for view settings.
  2796. if (! bRestoredView)
  2797. {
  2798. // get Result pane stuff from snapin
  2799. GUID guid = GUID_NULL;
  2800. sc = spNodeCallBack->GetResultPane(hNode, rvt, &guid);
  2801. if (sc)
  2802. return sc;
  2803. // we cannot pass the guidTaskpad to GetResultPane directly, since
  2804. // when it is navigation what causes the change, view settings are
  2805. // not yet updated and thus the guid returned will not reflect the
  2806. // current situation
  2807. if (!bUsingHistory)
  2808. guidTaskpad = guid;
  2809. }
  2810. // make sure we have a taskpad set (this will change the value of guidTaskpad if required)
  2811. // This is required when pages referred from history are no longer available when returning
  2812. // to the view (taskpad being deleted/default page being replaced/etc.)
  2813. if (bUsingHistory)
  2814. spNodeCallBack->SetTaskpad(hNode, &guidTaskpad);
  2815. //SetViewOptions(lViewOptions);
  2816. // at this stage, rvt contains all the result view information (excluding, as always the list view mode.)
  2817. if (rvt.HasList())
  2818. {
  2819. SetListViewMultiSelect(
  2820. (rvt.GetListOptions() & RVTI_LIST_OPTIONS_MULTISELECT) == RVTI_LIST_OPTIONS_MULTISELECT);
  2821. }
  2822. sc = ScSetResultPane(hNode, rvt, lViewMode, bUsingHistory);
  2823. if(sc)
  2824. return sc;
  2825. ::CoTaskMemFree(pszResultPane);
  2826. //
  2827. // Initialize default list view.
  2828. //
  2829. LPUNKNOWN pUnkResultsPane = GetPaneUnknown(CConsoleView::ePane_Results);
  2830. if (rvt.HasList())
  2831. {
  2832. sc = ScInitDefListView(pUnkResultsPane);
  2833. if(sc)
  2834. return sc;
  2835. sc = ScCheckPointers(m_ViewData.m_spResultData, E_UNEXPECTED);
  2836. if (sc)
  2837. return sc;
  2838. // this turns off list view redrawing. Should have some sort of smart object that automatically
  2839. // turns redrawing on in its destructor.
  2840. m_ViewData.m_spResultData->SetLoadMode(TRUE); // SetLoadMode(FALSE) is called by the caller, CAMCTreeView::OnSelectNode
  2841. }
  2842. //
  2843. // Notify the new node that it is selected.
  2844. //
  2845. SELECTIONINFO selInfo;
  2846. ZeroMemory(&selInfo, sizeof(selInfo));
  2847. selInfo.m_bScope = TRUE;
  2848. selInfo.m_pView = pUnkResultsPane;
  2849. if (rvt.HasWebBrowser())
  2850. {
  2851. selInfo.m_bResultPaneIsWeb = TRUE;
  2852. selInfo.m_lCookie = LVDATA_CUSTOMWEB;
  2853. }
  2854. else if (rvt.HasOCX())
  2855. {
  2856. selInfo.m_bResultPaneIsOCX = TRUE;
  2857. selInfo.m_lCookie = LVDATA_CUSTOMOCX;
  2858. }
  2859. // Increment and save local copy of nesting level counter. This counter serves
  2860. // two purposes. First, it allows AMCView to inhibit inserting scope items in
  2861. // the result pane during a select by checking the IsSelectingNode method.
  2862. // Without this test the scope items would appear twice because all the scope
  2863. // items are added to the result pane at the end of this method.
  2864. // Second, during the following ScNotifySelect call the snap-in could do another
  2865. // select which would re-enter this method. In that case, only the innermost
  2866. // call to this method should do the post-notify processing. The outer calls
  2867. // should just exit, returning S_FALSE instead of S_OK.
  2868. int nMyNestLevel = ++m_nSelectNestLevel;
  2869. // collect / manage view tabs
  2870. sc = ScAddFolderTabs( hNode, guidTaskpad );
  2871. if (sc)
  2872. return sc;
  2873. try
  2874. {
  2875. sc = ScNotifySelect ( spNodeCallBack, hNode, false /*fMultiSelect*/, true, &selInfo);
  2876. if (sc)
  2877. sc.TraceAndClear(); // ignore & continue;
  2878. }
  2879. catch(...)
  2880. {
  2881. // if first call to Select, reset level to zero before leaving
  2882. if (nMyNestLevel == 1) m_nSelectNestLevel = 0;
  2883. throw;
  2884. }
  2885. // if the local call level does not match the shared call level then this
  2886. // method was reentered during the ScNotifySelect. In that case don't finish
  2887. // the processing because the node and/or view may have changed.
  2888. // Be sure to reset the call level to zero if this is the outermost call.
  2889. ASSERT(nMyNestLevel <= m_nSelectNestLevel);
  2890. BOOL bDoProcessing = (nMyNestLevel == m_nSelectNestLevel);
  2891. if (nMyNestLevel == 1)
  2892. m_nSelectNestLevel = 0;
  2893. if (!bDoProcessing)
  2894. return S_FALSE;
  2895. //
  2896. // If the result pane is the def-LV, ensure that there are headers.
  2897. // If not add the default ones
  2898. //
  2899. if (rvt.HasList())
  2900. {
  2901. SetUsingDefColumns(FALSE);
  2902. // Get ptr to ResultPane.
  2903. IMMCListViewPtr pMMCLV = pUnkResultsPane;
  2904. sc = ScCheckPointers(pMMCLV, E_UNEXPECTED);
  2905. if (sc)
  2906. return sc;
  2907. int nCols = 0;
  2908. sc = pMMCLV->GetColumnCount(&nCols);
  2909. if (sc)
  2910. return sc;
  2911. if(0 == nCols)
  2912. {
  2913. sc = ScAddDefaultColumns();
  2914. if(sc)
  2915. return sc;
  2916. IResultDataPrivatePtr& pResultDataPrivate = m_ViewData.m_spResultData;
  2917. sc = ScCheckPointers(pResultDataPrivate, E_UNEXPECTED);
  2918. if (sc)
  2919. return sc;
  2920. long lViewMode = GetViewMode();
  2921. // If default mode is filtered and new node doesn't
  2922. // support that, use report mode instead
  2923. if (lViewMode == MMCLV_VIEWSTYLE_FILTERED &&
  2924. !(rvt.GetListOptions() & RVTI_LIST_OPTIONS_FILTERED))
  2925. lViewMode = LVS_REPORT;
  2926. // you've got to change the mode before you change the
  2927. // style: style doesn't contain the "quickfilter" bit.
  2928. pResultDataPrivate->SetViewMode (lViewMode);
  2929. long style = GetDefaultListViewStyle();
  2930. if (style != 0)
  2931. {
  2932. sc = pResultDataPrivate->SetListStyle(style);
  2933. if (sc)
  2934. return sc;
  2935. }
  2936. }
  2937. }
  2938. //
  2939. // Show the static scope items in the result pane,
  2940. // but not for a virtual list view, or views specifically
  2941. // marked that they don't want scope items in the result view
  2942. //
  2943. if (rvt.HasList() &&
  2944. !(rvt.GetListOptions() & RVTI_LIST_OPTIONS_OWNERDATALIST) &&
  2945. !(rvt.GetListOptions() & RVTI_LIST_OPTIONS_EXCLUDE_SCOPE_ITEMS_FROM_LIST))
  2946. {
  2947. bAddSubFolders = TRUE;
  2948. }
  2949. // Update window title.
  2950. sc = ScUpdateWindowTitle();
  2951. if(sc)
  2952. return sc;
  2953. // fire event to script
  2954. sc = ScFireEvent(CAMCViewObserver::ScOnViewChange, this, hNode);
  2955. if (sc)
  2956. return sc;
  2957. return sc;
  2958. }
  2959. /*+-------------------------------------------------------------------------*
  2960. *
  2961. * CAMCView::ScSetResultPane
  2962. *
  2963. * PURPOSE: Sets the result pane to the specified configuration.
  2964. *
  2965. * PARAMETERS:
  2966. * HNODE hNode :
  2967. * CResultViewType rvt :
  2968. * long lViewOptions :
  2969. * bool bUsingHistory :
  2970. *
  2971. * RETURNS:
  2972. * SC
  2973. *
  2974. *+-------------------------------------------------------------------------*/
  2975. SC
  2976. CAMCView::ScSetResultPane(HNODE hNode, CResultViewType rvt, int viewMode, bool bUsingHistory)
  2977. {
  2978. DECLARE_SC(sc, TEXT("CAMCView::SetResultPane"));
  2979. m_ViewData.SetResultViewType(rvt);
  2980. if(rvt.HasList())
  2981. {
  2982. sc = ScAttachListViewAsResultPane();
  2983. if(sc)
  2984. return sc;
  2985. }
  2986. else if(rvt.HasWebBrowser())
  2987. {
  2988. sc = ScAttachWebViewAsResultPane();
  2989. if(sc)
  2990. return sc;
  2991. }
  2992. else if(rvt.HasOCX())
  2993. {
  2994. sc = ScAttachOCXAsResultPane(hNode);
  2995. if(sc)
  2996. return sc;
  2997. }
  2998. else
  2999. {
  3000. ASSERT(0 && "Should not come here!!");
  3001. return (sc = E_UNEXPECTED);
  3002. }
  3003. // show the toolbars
  3004. if(GetStdToolbar() != NULL) // may be NULL at startup.
  3005. {
  3006. sc = GetStdToolbar()->ScShowStdBar(true);
  3007. if(sc)
  3008. return sc;
  3009. }
  3010. // if we haven't gotten here using history, add a history entry.
  3011. if(!bUsingHistory)
  3012. {
  3013. GUID guidTaskpad = GUID_NULL;
  3014. GetTaskpadID(guidTaskpad);
  3015. sc = m_pHistoryList->ScAddEntry(rvt, m_nViewMode, guidTaskpad);
  3016. if(sc)
  3017. return sc;
  3018. }
  3019. // if we have a node manager, tell it what the result pane is.
  3020. if(m_ViewData.m_spNodeManager)
  3021. {
  3022. LPUNKNOWN pUnkResultsPane = GetPaneUnknown(CConsoleView::ePane_Results);
  3023. m_ViewData.m_spNodeManager->SetResultView(pUnkResultsPane);
  3024. }
  3025. return sc;
  3026. }
  3027. BOOL CAMCView::CreateListCtrl(int nID, CCreateContext* pContext)
  3028. {
  3029. TRACE_METHOD(CAMCView, CreateListCtrl);
  3030. ASSERT(m_pListCtrl == NULL);
  3031. CComObject<CCCListViewCtrl> *pLV = NULL;
  3032. CComObject<CCCListViewCtrl>::CreateInstance( &pLV );
  3033. if (pLV == NULL)
  3034. {
  3035. ASSERT(0 && "Unable to create list control");
  3036. return FALSE;
  3037. }
  3038. // we assign directly - implicit cast works, since we have a type derived from the one we need
  3039. m_pListCtrl = pLV;
  3040. // we intend to hold a reference, so do addref here (CreateInstance creates w/ 0 reffs)
  3041. m_pListCtrl->AddRef();
  3042. if (!m_pListCtrl->Create (WS_VISIBLE | WS_CHILD, g_rectEmpty, this, nID, pContext))
  3043. {
  3044. ASSERT(0 && "Unable to create list control");
  3045. return FALSE;
  3046. }
  3047. m_pListCtrl->SetViewMode (m_nViewMode);
  3048. SC SC = m_pListCtrl->ScInitialize(); // intialize the list control
  3049. return TRUE;
  3050. }
  3051. void CAMCView::SetListViewOptions(DWORD dwListOptions)
  3052. {
  3053. TRACE_METHOD(CAMCView, SetListViewOptions);
  3054. bool bVirtual = (dwListOptions & RVTI_LIST_OPTIONS_OWNERDATALIST) ? true : false;
  3055. ASSERT(m_pListCtrl != NULL);
  3056. CDocument* pDoc = GetDocument();
  3057. ASSERT(pDoc != NULL);
  3058. // If change to/from virtual list, change list mode
  3059. if (IsVirtualList() != bVirtual)
  3060. {
  3061. m_ViewData.SetVirtualList (bVirtual);
  3062. pDoc->RemoveView(m_pListCtrl->GetListViewPtr());
  3063. m_pListCtrl->SetVirtualMode(bVirtual);
  3064. pDoc->AddView(m_pListCtrl->GetListViewPtr());
  3065. m_ViewData.m_hwndListCtrl = m_pListCtrl->GetListViewHWND();
  3066. }
  3067. // if snapin doesn't support filtering make sure it's off
  3068. if (!(GetListOptions() & RVTI_LIST_OPTIONS_FILTERED) &&
  3069. m_pListCtrl->GetViewMode() == MMCLV_VIEWSTYLE_FILTERED)
  3070. {
  3071. m_pListCtrl->SetViewMode(LVS_REPORT);
  3072. }
  3073. }
  3074. /*+-------------------------------------------------------------------------*
  3075. *
  3076. * CAMCView::ScAttachListViewAsResultPane
  3077. *
  3078. * PURPOSE: Sets up the list view as the result pane.
  3079. *
  3080. * PARAMETERS: NONE
  3081. *
  3082. * RETURNS:
  3083. * SC
  3084. *
  3085. *+-------------------------------------------------------------------------*/
  3086. SC
  3087. CAMCView::ScAttachListViewAsResultPane()
  3088. {
  3089. DECLARE_SC(sc, TEXT("CAMCView::ScAttachListViewAsResultPane"));
  3090. bool bVirtual = (GetListOptions() & RVTI_LIST_OPTIONS_OWNERDATALIST) ? true : false;
  3091. GUID guidTaskpad;
  3092. GetTaskpadID(guidTaskpad);
  3093. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  3094. if(sc)
  3095. return sc;
  3096. CDocument* pDoc = GetDocument();
  3097. ASSERT(pDoc != NULL);
  3098. // If change to/from virtual list, change list mode
  3099. if (IsVirtualList() != bVirtual)
  3100. {
  3101. m_ViewData.SetVirtualList (bVirtual);
  3102. pDoc->RemoveView(m_pListCtrl->GetListViewPtr());
  3103. m_pListCtrl->SetVirtualMode(bVirtual);
  3104. pDoc->AddView(m_pListCtrl->GetListViewPtr());
  3105. m_ViewData.m_hwndListCtrl = m_pListCtrl->GetListViewHWND();
  3106. }
  3107. // if snapin doesn't support filtering make sure it's off
  3108. if (!(GetListOptions() & RVTI_LIST_OPTIONS_FILTERED) &&
  3109. m_pListCtrl->GetViewMode() == MMCLV_VIEWSTYLE_FILTERED)
  3110. {
  3111. m_pListCtrl->SetViewMode(LVS_REPORT);
  3112. }
  3113. ShowResultPane(m_pListCtrl->GetListViewPtr(), uiClientEdge);
  3114. return sc;
  3115. }
  3116. /*+-------------------------------------------------------------------------*
  3117. *
  3118. * CAMCView::ScAttachWebViewAsResultPane
  3119. *
  3120. * PURPOSE:
  3121. *
  3122. * PARAMETERS: NONE
  3123. *
  3124. * RETURNS:
  3125. * void
  3126. *
  3127. *+-------------------------------------------------------------------------*/
  3128. SC
  3129. CAMCView::ScAttachWebViewAsResultPane()
  3130. {
  3131. DECLARE_SC(sc, TEXT("CAMCView::ScAttachWebViewAsResultPane"));
  3132. // if we were in ListPad-mode, undo that.
  3133. if (m_pListCtrl->IsListPad())
  3134. {
  3135. sc = m_pListCtrl->ScAttachToListPad (NULL, NULL);
  3136. if(sc)
  3137. return sc;
  3138. }
  3139. // The control is created on demand. This prevents IE from loading when unnecessary
  3140. // and reduces startup time.
  3141. if (m_pWebViewCtrl == NULL)
  3142. CreateView (IDC_WebViewCtrl);
  3143. sc = ScCheckPointers(m_pWebViewCtrl, E_UNEXPECTED);
  3144. if(sc)
  3145. return sc;
  3146. // Force web control to update its palette
  3147. SendMessage(WM_QUERYNEWPALETTE);
  3148. ShowResultPane(m_pWebViewCtrl, uiNoClientEdge);
  3149. return sc;
  3150. }
  3151. /*+-------------------------------------------------------------------------*
  3152. *
  3153. * CAMCView::ScAttachOCXAsResultPane
  3154. *
  3155. * PURPOSE:
  3156. *
  3157. * PARAMETERS:
  3158. * LPCTSTR pszResultPane :
  3159. *
  3160. * RETURNS:
  3161. * SC
  3162. *
  3163. *+-------------------------------------------------------------------------*/
  3164. SC
  3165. CAMCView::ScAttachOCXAsResultPane(HNODE hNode)
  3166. {
  3167. DECLARE_SC(sc, TEXT("CAMCView::ScAttachOCXAsResultPane"));
  3168. USES_CONVERSION;
  3169. ASSERT(m_pListCtrl != NULL);
  3170. if (m_pOCXHostView == NULL)
  3171. CreateView (IDC_OCXHostView);
  3172. sc = ScCheckPointers(m_pOCXHostView);
  3173. if(sc)
  3174. return sc;
  3175. sc = m_pOCXHostView->ScSetControl(hNode, m_ViewData.m_rvt, GetNodeCallback());
  3176. if(sc)
  3177. return sc;
  3178. ShowResultPane(m_pOCXHostView, uiClientEdge);
  3179. return sc;
  3180. }
  3181. /*+-------------------------------------------------------------------------*
  3182. * CAMCView::ScApplyViewExtension
  3183. *
  3184. * Applies a view extension to the current view. pszURL specifies the
  3185. * URL of the HTML to load as the view extension. If pszURL is NULL or
  3186. * empty, the view extension is removed.
  3187. *
  3188. * This method will force a layout of the view if it is required.
  3189. *--------------------------------------------------------------------------*/
  3190. SC CAMCView::ScApplyViewExtension (
  3191. LPCTSTR pszURL) /* I:URL to use, NULL to remove */
  3192. {
  3193. DECLARE_SC (sc, _T("CAMCView::ScApplyViewExtension"));
  3194. /*
  3195. * assume no view extension
  3196. */
  3197. bool fViewWasExtended = m_fViewExtended;
  3198. m_fViewExtended = false;
  3199. /*
  3200. * if we're given a URL with which to extend the view, turn on the extension
  3201. */
  3202. if ((pszURL != NULL) && (*pszURL != 0))
  3203. {
  3204. /*
  3205. * if we don't have a web control for the view extension yet, create one
  3206. */
  3207. if (m_pViewExtensionCtrl == NULL)
  3208. CreateView (IDC_ViewExtensionView);
  3209. sc = ScCheckPointers (m_pViewExtensionCtrl, E_FAIL);
  3210. if (sc)
  3211. return (sc);
  3212. m_fViewExtended = true;
  3213. // hide the hosted window initially
  3214. CWnd *pwndHosted = GetPaneView(ePane_Results);
  3215. sc = ScCheckPointers(pwndHosted);
  3216. if(sc)
  3217. return sc;
  3218. pwndHosted->ShowWindow(SW_HIDE);
  3219. RecalcLayout(); // do this BEFORE calling Navigate, which may resize the above rectangle via the mmcview behavior
  3220. // navigate to the requested URL
  3221. m_pViewExtensionCtrl->Navigate (pszURL, NULL);
  3222. }
  3223. else if (fViewWasExtended && (m_pViewExtensionCtrl != NULL))
  3224. {
  3225. /*
  3226. * Bug 96948: If we've got an extension and we're currently extending
  3227. * the view, navigate the view extension's web browser to an empty page
  3228. * so the behavior that resizes the hosted result frame is disabled
  3229. */
  3230. CStr strEmptyPage;
  3231. sc = ScGetPageBreakURL (strEmptyPage);
  3232. if (sc)
  3233. return (sc);
  3234. m_pViewExtensionCtrl->Navigate (strEmptyPage, NULL);
  3235. if(fViewWasExtended)
  3236. DeferRecalcLayout();
  3237. }
  3238. return (sc);
  3239. }
  3240. /*+-------------------------------------------------------------------------*
  3241. *
  3242. * CAMCView::ShowResultPane
  3243. *
  3244. * PURPOSE:
  3245. *
  3246. * PARAMETERS:
  3247. * CView* pNewView :
  3248. * EUIStyleType nStyle :
  3249. *
  3250. * RETURNS:
  3251. * void
  3252. *
  3253. *+-------------------------------------------------------------------------*/
  3254. void
  3255. CAMCView::ShowResultPane(CView* pNewView, EUIStyleType nStyle)
  3256. {
  3257. TRACE_METHOD(CAMCView, ShowResultPane);
  3258. ASSERT(pNewView != NULL);
  3259. CView* pCurrentView = GetPaneView(ePane_Results);
  3260. bool bActive = (GetParentFrame()->GetActiveView() == pCurrentView);
  3261. // Check to see if we need to swap the CWnd control in the result pane
  3262. if (pNewView != pCurrentView)
  3263. {
  3264. HWND hwndCurrentView = pCurrentView->GetSafeHwnd();
  3265. if (IsWindow (hwndCurrentView))
  3266. {
  3267. pCurrentView->ShowWindow(SW_HIDE);
  3268. // Note: We are directly hiding the window for cases that controls
  3269. // don't hide during a DoVerb(OLEIVERB_HIDE). Actually, this does a
  3270. // hide on all windows. It's too hard at this point to optimize the code
  3271. // for doing this with an OLE control only.
  3272. ::ShowWindow(hwndCurrentView, SW_HIDE);
  3273. }
  3274. SetPane(ePane_Results, pNewView, nStyle);
  3275. RecalcLayout();
  3276. // if other pane was active, make the new one active
  3277. if ((pCurrentView != NULL) && bActive)
  3278. {
  3279. // make sure the new window is visible
  3280. pNewView->ShowWindow(SW_SHOW);
  3281. GetParentFrame()->SetActiveView(pNewView);
  3282. }
  3283. }
  3284. }
  3285. //+-------------------------------------------------------------------------
  3286. //
  3287. // Function: GetPaneInfo
  3288. //
  3289. // Synopsis: Get information about a particular pane
  3290. //
  3291. //--------------------------------------------------------------------------
  3292. void CAMCView::GetPaneInfo(ViewPane ePane, int* pcxCur, int* pcxMin)
  3293. {
  3294. TRACE_METHOD(CAMCView, GetPaneInfo);
  3295. ASSERT_VALID(this);
  3296. if (!IsValidPane (ePane))
  3297. {
  3298. ASSERT (false && "CAMCView::GetPaneInfo: Invalid pane specifier");
  3299. return;
  3300. }
  3301. if ((pcxCur==NULL) || (pcxMin==NULL))
  3302. {
  3303. ASSERT(FALSE); // One or more of the args is wrong
  3304. return;
  3305. }
  3306. // REVIEW fix enum
  3307. *pcxCur = m_PaneInfo[ePane].cx;
  3308. *pcxMin = m_PaneInfo[ePane].cxMin;
  3309. }
  3310. //+-------------------------------------------------------------------------
  3311. //
  3312. // Function: SetPaneInfo
  3313. //
  3314. // Synopsis: Set information about a particular pane
  3315. //
  3316. //--------------------------------------------------------------------------
  3317. void CAMCView::SetPaneInfo(ViewPane ePane, int cxCur, int cxMin)
  3318. {
  3319. TRACE_METHOD(CAMCView, SetPaneInfo);
  3320. ASSERT_VALID(this);
  3321. if (!IsValidPane (ePane))
  3322. {
  3323. ASSERT (false && "CAMCView::SetPaneInfo: Invalid pane specifier");
  3324. return;
  3325. }
  3326. if (cxCur < 0 || cxMin < 0)
  3327. {
  3328. ASSERT(FALSE); // One or more of the args is wrong
  3329. return;
  3330. }
  3331. m_PaneInfo[ePane].cx = cxCur;
  3332. m_PaneInfo[ePane].cxMin = cxMin;
  3333. }
  3334. //+-------------------------------------------------------------------------
  3335. //
  3336. // Function: GetPaneView
  3337. //
  3338. // Synopsis: Returns a pointer to CView for a particular pane
  3339. //
  3340. //--------------------------------------------------------------------------
  3341. CView* CAMCView::GetPaneView(ViewPane ePane)
  3342. {
  3343. TRACE_METHOD(CAMCView, GetPaneView);
  3344. ASSERT_VALID(this);
  3345. if (!IsValidPane (ePane))
  3346. {
  3347. ASSERT (false && "CAMCView::GetPaneView: Invalid pane specifier");
  3348. return (NULL);
  3349. }
  3350. return (m_PaneInfo[ePane].pView);
  3351. }
  3352. /*+-------------------------------------------------------------------------*
  3353. * CAMCView::GetResultView
  3354. *
  3355. *
  3356. *--------------------------------------------------------------------------*/
  3357. CView* CAMCView::GetResultView() const
  3358. {
  3359. CView* pView = NULL;
  3360. // may need changes here - assumes the different types are independent.
  3361. if(HasWebBrowser())
  3362. pView = m_pWebViewCtrl;
  3363. else if(HasList())
  3364. pView = m_pListCtrl->GetListViewPtr();
  3365. else if(HasOCX())
  3366. pView = m_pOCXHostView;
  3367. ASSERT (pView != NULL);
  3368. return (pView);
  3369. }
  3370. //+-------------------------------------------------------------------------
  3371. //
  3372. // Function: GetPaneUnknown
  3373. //
  3374. // Synopsis: Returns a pointer to the Unknown
  3375. //
  3376. //--------------------------------------------------------------------------
  3377. LPUNKNOWN CAMCView::GetPaneUnknown(ViewPane ePane)
  3378. {
  3379. TRACE_METHOD(CAMCView, GetPaneUnknown);
  3380. ASSERT_VALID(this);
  3381. if (!IsValidPane (ePane))
  3382. {
  3383. ASSERT (false && "CAMCView::GetPaneUnknown: Invalid pane specifier");
  3384. return (NULL);
  3385. }
  3386. if (!IsWindow (GetPaneView(ePane)->GetSafeHwnd()))
  3387. {
  3388. ASSERT(FALSE); // Invalid pane element
  3389. return NULL;
  3390. }
  3391. if (HasWebBrowser() && m_pWebViewCtrl != NULL)
  3392. {
  3393. return m_pWebViewCtrl->GetIUnknown();
  3394. }
  3395. else if( HasList() && m_pListCtrl != NULL )
  3396. {
  3397. IUnknownPtr spUnk = m_pListCtrl;
  3398. LPUNKNOWN pUnk = spUnk;
  3399. return pUnk;
  3400. }
  3401. else if (HasOCX() && m_pOCXHostView != NULL)
  3402. {
  3403. ASSERT(GetPaneView (ePane));
  3404. return m_pOCXHostView->GetIUnknown();
  3405. }
  3406. else
  3407. {
  3408. // result pane not initialized yet. This is usually because we are in between a deselect and a
  3409. // subsequent reselect.
  3410. return NULL;
  3411. }
  3412. }
  3413. //+-------------------------------------------------------------------------
  3414. //
  3415. // Function: SetPane
  3416. //
  3417. // Synopsis: Set a CWnd pointer for a particular pane and other information
  3418. //
  3419. //--------------------------------------------------------------------------
  3420. void CAMCView::SetPane(ViewPane ePane, CView* pView, EUIStyleType nStyle)
  3421. {
  3422. TRACE_METHOD(CAMCView, SetPane);
  3423. ASSERT_VALID(this);
  3424. if (!IsValidPane (ePane))
  3425. {
  3426. ASSERT (false && "CAMCView::SetPane: Invalid pane specifier");
  3427. return;
  3428. }
  3429. if (pView==NULL || !IsWindow(*pView))
  3430. {
  3431. ASSERT(FALSE); // Invalid arg
  3432. return;
  3433. }
  3434. m_PaneInfo[ePane].pView = pView;
  3435. // Ensure that the window is visible & at the top of the Z-order.
  3436. pView->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
  3437. // Note: We are directly showing the window for cases that controls
  3438. // don't show during a DoVerb(OLEIVERB_SHOW). Actually, this does a
  3439. // show on all windows. It's too hard at this point to optimize the code
  3440. // for doing this with an OLE control only.
  3441. ::ShowWindow(pView->m_hWnd, SW_SHOW);
  3442. }
  3443. //
  3444. // Other Methods
  3445. //
  3446. /*+-------------------------------------------------------------------------*
  3447. * CAMCView::ScShowScopePane
  3448. *
  3449. * Shows or hides the scope pane in the current view. If fForce is true,
  3450. * we'll go through the motions of showing the scope pane even if we think
  3451. * its visibility state wouldn't change.
  3452. *--------------------------------------------------------------------------*/
  3453. SC CAMCView::ScShowScopePane (bool fShow, bool fForce /* =false */)
  3454. {
  3455. DECLARE_SC (sc, _T("CAMCView::ScShowScopePane"));
  3456. /*
  3457. * if the current visibility state doesn't match the requested state,
  3458. * change the current state to match the requested state
  3459. */
  3460. if (fForce || (IsScopePaneVisible() != fShow))
  3461. {
  3462. /*
  3463. * If MMC_NW_OPTION_NOSCOPEPANE was specified when this view was
  3464. * created, we can't display a scope pane. If we're asked to, fail.
  3465. */
  3466. if (fShow && !IsScopePaneAllowed())
  3467. return (sc = E_FAIL);
  3468. /*
  3469. * if the scope pane is being hidden and it contained the active
  3470. * view, activate the result pane
  3471. */
  3472. if (!fShow && (GetFocusedPane() == ePane_ScopeTree))
  3473. ScSetFocusToResultPane (); // ignore errors here
  3474. /*
  3475. * remember the new state
  3476. */
  3477. SetScopePaneVisible (fShow);
  3478. /*
  3479. * Don't defer this layout. This may be called by the Customize View
  3480. * dialog which wants to see its updates in real time. It will be
  3481. * sitting in a modal message loop so we won't get a chance to precess
  3482. * our idle task.
  3483. */
  3484. RecalcLayout();
  3485. /*
  3486. * the console has changed
  3487. */
  3488. SetDirty();
  3489. }
  3490. /*
  3491. * put the scope pane toolbar button in the right state
  3492. */
  3493. CStandardToolbar* pStdToolbar = GetStdToolbar();
  3494. sc = ScCheckPointers(pStdToolbar, E_UNEXPECTED);
  3495. if (sc)
  3496. return (sc);
  3497. CAMCDoc *pDoc = GetDocument();
  3498. sc = ScCheckPointers(pDoc, E_UNEXPECTED);
  3499. if (sc)
  3500. return sc;
  3501. bool bEnableScopePaneButton = (IsScopePaneAllowed() && pDoc->AllowViewCustomization());
  3502. // IF view customization is not allowed then "Show/Hide Consolte tree" button should be hidden.
  3503. if (bEnableScopePaneButton)
  3504. {
  3505. /*
  3506. * the scope pane is permitted; show and check the toolbar
  3507. * button if the scope pane is visible, show and uncheck the
  3508. * toolbar button if the scope pane is hidden
  3509. */
  3510. sc = pStdToolbar->ScCheckScopePaneBtn (fShow);
  3511. if (sc)
  3512. return (sc);
  3513. }
  3514. else
  3515. {
  3516. /*
  3517. * no scope pane permitted, hide the scope pane button
  3518. */
  3519. sc = pStdToolbar->ScEnableScopePaneBtn (bEnableScopePaneButton);
  3520. if (sc)
  3521. return (sc);
  3522. }
  3523. /*
  3524. * if we get to this point, the current state should match the requested state
  3525. */
  3526. ASSERT (IsScopePaneVisible() == fShow);
  3527. return (sc);
  3528. }
  3529. /*+-------------------------------------------------------------------------*
  3530. * CAMCView::CDeferredLayout::CDeferredLayout
  3531. *
  3532. * Constructs a CAMCView::CDeferredLayout::CDeferredLayout. Note that if
  3533. * an error occurs during construction, an SC exception will be thrown.
  3534. *--------------------------------------------------------------------------*/
  3535. CAMCView::CDeferredLayout::CDeferredLayout (CAMCView* pAMCView)
  3536. : m_atomTask (AddAtom (_T("CAMCView::CDeferredLayout")))
  3537. {
  3538. DECLARE_SC (sc, _T("CAMCView::CDeferredLayout::CDeferredLayout"));
  3539. if (!Attach (pAMCView))
  3540. (sc = E_INVALIDARG).Throw();
  3541. }
  3542. /*+-------------------------------------------------------------------------*
  3543. * CAMCView::CDeferredLayout::~CDeferredLayout
  3544. *
  3545. *
  3546. *--------------------------------------------------------------------------*/
  3547. CAMCView::CDeferredLayout::~CDeferredLayout()
  3548. {
  3549. DeleteAtom (m_atomTask);
  3550. }
  3551. /*+-------------------------------------------------------------------------*
  3552. * CAMCView::CDeferredLayout::ScDoWork
  3553. *
  3554. *
  3555. *--------------------------------------------------------------------------*/
  3556. SC CAMCView::CDeferredLayout::ScDoWork()
  3557. {
  3558. WindowCollection::iterator it;
  3559. WindowCollection::iterator itEnd = m_WindowsToLayout.end();
  3560. for (it = m_WindowsToLayout.begin(); it != itEnd; ++it)
  3561. {
  3562. CWnd* pwnd = CWnd::FromHandlePermanent (*it);
  3563. CAMCView* pAMCView = dynamic_cast<CAMCView*>(pwnd);
  3564. if (pAMCView != NULL)
  3565. {
  3566. pAMCView->RecalcLayout();
  3567. pAMCView->Invalidate();
  3568. pAMCView->UpdateWindow();
  3569. }
  3570. }
  3571. return (S_OK);
  3572. }
  3573. /*+-------------------------------------------------------------------------*
  3574. * CAMCView::CDeferredLayout::ScGetTaskID
  3575. *
  3576. *
  3577. *--------------------------------------------------------------------------*/
  3578. SC CAMCView::CDeferredLayout::ScGetTaskID(ATOM* pID)
  3579. {
  3580. *pID = m_atomTask;
  3581. return (S_OK);
  3582. }
  3583. /*+-------------------------------------------------------------------------*
  3584. * CAMCView::CDeferredLayout::ScMerge
  3585. *
  3586. *
  3587. *--------------------------------------------------------------------------*/
  3588. SC CAMCView::CDeferredLayout::ScMerge(CIdleTask* pitMergeFrom)
  3589. {
  3590. CDeferredLayout* pdlMergeFrom = dynamic_cast<CDeferredLayout*>(pitMergeFrom);
  3591. ASSERT (pdlMergeFrom != NULL);
  3592. /*
  3593. * copy the windows from the merge-from task into the merge-to task
  3594. */
  3595. WindowCollection::iterator it;
  3596. WindowCollection::iterator itEnd = pdlMergeFrom->m_WindowsToLayout.end();
  3597. for (it = pdlMergeFrom->m_WindowsToLayout.begin(); it != itEnd; ++it)
  3598. {
  3599. m_WindowsToLayout.insert (*it);
  3600. }
  3601. return (S_OK);
  3602. }
  3603. /*+-------------------------------------------------------------------------*
  3604. * CAMCView::CDeferredLayout::Attach
  3605. *
  3606. *
  3607. *--------------------------------------------------------------------------*/
  3608. bool CAMCView::CDeferredLayout::Attach (CAMCView* pAMCView)
  3609. {
  3610. ASSERT (pAMCView != NULL);
  3611. HWND hwndAMCView = pAMCView->GetSafeHwnd();
  3612. if (hwndAMCView != NULL)
  3613. m_WindowsToLayout.insert (hwndAMCView);
  3614. return (hwndAMCView != NULL);
  3615. }
  3616. /*+-------------------------------------------------------------------------*
  3617. * CAMCView::DeferRecalcLayout
  3618. *
  3619. *
  3620. *--------------------------------------------------------------------------*/
  3621. void CAMCView::DeferRecalcLayout (bool fUseIdleTaskQueue /* =true */, bool bArrangeIcons /* = false*/)
  3622. {
  3623. DECLARE_SC (sc, _T("CAMCView::DeferRecalcLayout"));
  3624. if (fUseIdleTaskQueue)
  3625. {
  3626. Trace (tagLayout, _T("CAMCView::DeferRecalcLayout (idle task)"));
  3627. try
  3628. {
  3629. /*
  3630. * get the idle task manager
  3631. */
  3632. CIdleTaskQueue* pIdleTaskQueue = AMCGetIdleTaskQueue();
  3633. if (pIdleTaskQueue == NULL)
  3634. (sc = E_UNEXPECTED).Throw();
  3635. /*
  3636. * create the deferred layout task
  3637. */
  3638. CAutoPtr<CDeferredLayout> spDeferredLayout (new CDeferredLayout (this));
  3639. if (spDeferredLayout == NULL)
  3640. (sc = E_OUTOFMEMORY).Throw();
  3641. /*
  3642. * put the task in the queue, which will take ownership of it
  3643. */
  3644. sc = pIdleTaskQueue->ScPushTask (spDeferredLayout, ePriority_Normal);
  3645. if (sc)
  3646. sc.Throw();
  3647. /*
  3648. * if we get here, the idle task queue owns the idle task, so
  3649. * we can detach it from our smart pointer
  3650. */
  3651. spDeferredLayout.Detach();
  3652. /*
  3653. * jiggle the message pump so that it wakes up and checks idle tasks
  3654. */
  3655. PostMessage (WM_NULL);
  3656. }
  3657. catch (SC& scCaught)
  3658. {
  3659. /*
  3660. * if we failed to enqueue our deferred layout task, do the layout now
  3661. */
  3662. RecalcLayout();
  3663. }
  3664. }
  3665. /*
  3666. * post a message instead of using the idle task queue
  3667. */
  3668. else
  3669. {
  3670. /*
  3671. * we only need to post a message if there's not one in the queue
  3672. * already
  3673. */
  3674. MSG msg;
  3675. if (!PeekMessage (&msg, GetSafeHwnd(),
  3676. m_nDeferRecalcLayoutMsg,
  3677. m_nDeferRecalcLayoutMsg,
  3678. PM_NOREMOVE))
  3679. {
  3680. PostMessage (m_nDeferRecalcLayoutMsg, bArrangeIcons);
  3681. Trace (tagLayout, _T("CAMCView::DeferRecalcLayout (posted message)"));
  3682. }
  3683. else
  3684. {
  3685. Trace (tagLayout, _T("CAMCView::DeferRecalcLayout (skipping redundant posted message)"));
  3686. }
  3687. }
  3688. }
  3689. //+-------------------------------------------------------------------------
  3690. //
  3691. // Function: RecalcLayout
  3692. //
  3693. // Synopsis: Calls methods to layout control and paint borders and splitters.
  3694. //
  3695. //--------------------------------------------------------------------------
  3696. void CAMCView::RecalcLayout(void)
  3697. {
  3698. TRACE_METHOD(CAMCView, RecalcLayout);
  3699. ASSERT_VALID(this);
  3700. Trace (tagLayout, _T("CAMCView::RecalcLayout"));
  3701. /*
  3702. * short out if the client rect is empty
  3703. */
  3704. CRect rectClient;
  3705. GetClientRect (rectClient);
  3706. if (rectClient.IsRectEmpty())
  3707. return;
  3708. CDeferWindowPos dwp (10);
  3709. LayoutScopePane (dwp, rectClient);
  3710. LayoutResultPane (dwp, rectClient);
  3711. /*
  3712. * CDeferWindowPos dtor will position the windows
  3713. */
  3714. }
  3715. /*+-------------------------------------------------------------------------*
  3716. * CAMCView::LayoutScopePane
  3717. *
  3718. *
  3719. *--------------------------------------------------------------------------*/
  3720. void CAMCView::LayoutScopePane (CDeferWindowPos& dwp, CRect& rectRemaining)
  3721. {
  3722. int cxScope = 0;
  3723. // If a scope pane is visible
  3724. if (IsScopePaneVisible())
  3725. {
  3726. int cxTotal = rectRemaining.Width();
  3727. // get the current width
  3728. cxScope = m_PaneInfo[ePane_ScopeTree].cx;
  3729. // if not determined yet, set scope pane width to 1/4 of window
  3730. if (cxScope == -1)
  3731. cxScope = cxTotal / 3;
  3732. /*
  3733. * Bug 86718: Make sure we leave at least the minimum width
  3734. * for the result pane, which is always visible
  3735. */
  3736. cxScope = std::_MIN (cxScope, cxTotal - m_PaneInfo[ePane_Results].cxMin - m_cxSplitter);
  3737. /*
  3738. * remember the scope pane width
  3739. */
  3740. m_PaneInfo[ePane_ScopeTree].cx = cxScope;
  3741. }
  3742. CRect rectScope = rectRemaining;
  3743. rectScope.right = rectScope.left + cxScope;
  3744. /*
  3745. * remove space used by the scope pane
  3746. * (and splitter) from the remaining area
  3747. */
  3748. if (IsScopePaneVisible())
  3749. {
  3750. m_rectVSplitter.left = rectScope.right;
  3751. m_rectVSplitter.top = rectScope.top;
  3752. m_rectVSplitter.right = rectScope.right + m_cxSplitter;
  3753. m_rectVSplitter.bottom = rectScope.bottom;
  3754. rectRemaining.left = m_rectVSplitter.right;
  3755. /*
  3756. * Inflate the splitter rect to give a little bigger hot area.
  3757. * We need to do this logically instead of physically (i.e. instead
  3758. * of increasing m_cxSplitter) to keep the visuals right.
  3759. */
  3760. m_rectVSplitter.InflateRect (GetSystemMetrics (SM_CXEDGE), 0);
  3761. }
  3762. else
  3763. m_rectVSplitter = g_rectEmpty;
  3764. /*
  3765. * scope pane
  3766. */
  3767. dwp.AddWindow (GetPaneView(ePane_ScopeTree), rectScope,
  3768. SWP_NOZORDER | SWP_NOACTIVATE |
  3769. (IsScopePaneVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
  3770. }
  3771. /*+-------------------------------------------------------------------------*
  3772. * CAMCView::LayoutResultPane
  3773. *
  3774. * Lays out the children of the result pane.
  3775. *--------------------------------------------------------------------------*/
  3776. void CAMCView::LayoutResultPane (CDeferWindowPos& dwp, CRect& rectRemaining)
  3777. {
  3778. /*
  3779. * Note: the order of these calls to LayoutXxx is *critical*.
  3780. */
  3781. LayoutResultDescriptionBar (dwp, rectRemaining);
  3782. LayoutResultFolderTabView (dwp, rectRemaining);
  3783. m_rectResultFrame = rectRemaining;
  3784. LayoutResultView (dwp, rectRemaining);
  3785. /*
  3786. * remember the final width of the result pane in m_PaneInfo[ePane_Results].cx
  3787. */
  3788. m_PaneInfo[ePane_Results].cx = m_rectResultFrame.Width();
  3789. }
  3790. /*+-------------------------------------------------------------------------*
  3791. * CAMCView::LayoutResultFolderTabView
  3792. *
  3793. *
  3794. *--------------------------------------------------------------------------*/
  3795. void CAMCView::LayoutResultFolderTabView (CDeferWindowPos& dwp, CRect& rectRemaining)
  3796. {
  3797. DECLARE_SC(sc, TEXT("CAMCView::LayoutResultFolderTabView"));
  3798. sc = ScCheckPointers(m_pResultFolderTabView, E_UNEXPECTED);
  3799. if (sc)
  3800. return;
  3801. // layout the folder tab control - always on top.
  3802. bool bVisible = AreTaskpadTabsAllowed() && m_pResultFolderTabView->IsVisible();
  3803. CRect rectFolder;
  3804. if (bVisible)
  3805. m_pResultFolderTabView->Layout(rectRemaining, rectFolder);
  3806. else
  3807. rectFolder = g_rectEmpty;
  3808. DWORD dwPosFlags = SWP_NOZORDER | SWP_NOACTIVATE |
  3809. (bVisible ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
  3810. dwp.AddWindow (m_pResultFolderTabView, rectFolder, dwPosFlags);
  3811. }
  3812. /*+-------------------------------------------------------------------------*
  3813. * CAMCView::LayoutResultDescriptionBar
  3814. *
  3815. *
  3816. *--------------------------------------------------------------------------*/
  3817. void CAMCView::LayoutResultDescriptionBar (CDeferWindowPos& dwp, CRect& rectRemaining)
  3818. {
  3819. DWORD dwPosFlags = SWP_NOZORDER | SWP_NOACTIVATE;
  3820. CRect rectT = rectRemaining;
  3821. if (IsDescBarVisible() && !rectT.IsRectEmpty())
  3822. {
  3823. rectT.bottom = rectT.top + m_RightDescCtrl.GetHeight();
  3824. rectRemaining.top = rectT.bottom;
  3825. dwPosFlags |= SWP_SHOWWINDOW;
  3826. }
  3827. else
  3828. {
  3829. dwPosFlags |= SWP_HIDEWINDOW;
  3830. }
  3831. dwp.AddWindow (&m_RightDescCtrl, rectT, dwPosFlags);
  3832. }
  3833. /*+-------------------------------------------------------------------------*
  3834. * CAMCView::LayoutResultView
  3835. *
  3836. *
  3837. *--------------------------------------------------------------------------*/
  3838. void CAMCView::LayoutResultView (CDeferWindowPos& dwp, const CRect& rectRemaining)
  3839. {
  3840. DECLARE_SC (sc, _T("CAMCView::LayoutResultView"));
  3841. Trace (tagLayout, _T("CAMCView::LayoutResultView"));
  3842. CWnd* pwndResult = GetPaneView(ePane_Results);
  3843. /*
  3844. * we should never think the view is extended if we don't also have
  3845. * a view extension web host control
  3846. */
  3847. ASSERT (!(m_fViewExtended && (m_pViewExtensionCtrl == NULL)));
  3848. /*
  3849. * if it exists, the view extension control is always at the bottom of
  3850. * the Z-order, and visible if the view is being extended
  3851. */
  3852. if(m_pViewExtensionCtrl != NULL)
  3853. {
  3854. /*
  3855. * note no SWP_NOZORDER
  3856. */
  3857. DWORD dwPosFlags = SWP_NOACTIVATE | ((m_fViewExtended)
  3858. ? SWP_SHOWWINDOW
  3859. : SWP_HIDEWINDOW);
  3860. dwp.AddWindow (m_pViewExtensionCtrl, rectRemaining,
  3861. dwPosFlags, &CWnd::wndBottom);
  3862. }
  3863. /*
  3864. * If the view's not extended, show or hide the result window based on
  3865. * whether there's any room left in the positioning rectangle. (If the
  3866. * view is extended, the result window will have been hidden when the
  3867. * view extension was applied (in ScApplyViewExtension), and possibly
  3868. * redisplayed by the extension in ScSetViewExtensionFrame.)
  3869. */
  3870. if (!m_fViewExtended)
  3871. {
  3872. DWORD dwFlags = SWP_NOZORDER | SWP_NOACTIVATE |
  3873. (rectRemaining.IsRectEmpty() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW);
  3874. dwp.AddWindow (pwndResult, rectRemaining, dwFlags);
  3875. }
  3876. /*
  3877. * lists in extended views and listpads don't get a border, all others do
  3878. */
  3879. if (HasListOrListPad())
  3880. {
  3881. if (HasListPad())
  3882. {
  3883. sc = ScCheckPointers (m_pListCtrl, E_UNEXPECTED);
  3884. if (sc)
  3885. return;
  3886. CWnd* pwndListCtrl = m_pListCtrl->GetListViewPtr();
  3887. sc = ScCheckPointers (pwndListCtrl, E_UNEXPECTED);
  3888. if (sc)
  3889. return;
  3890. pwndListCtrl->ModifyStyleEx (WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED); // remove border
  3891. }
  3892. else if (m_fViewExtended)
  3893. pwndResult->ModifyStyleEx (WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED); // remove border
  3894. else
  3895. pwndResult->ModifyStyleEx (0, WS_EX_CLIENTEDGE, SWP_FRAMECHANGED); // add border
  3896. }
  3897. }
  3898. //
  3899. // Tracking and and hit testing methods
  3900. //
  3901. //+-------------------------------------------------------------------------
  3902. //
  3903. // Function: HitTestPane
  3904. //
  3905. // Synopsis: Test which pane contains the point arg, or ePane_None for
  3906. // the splitter bar
  3907. //
  3908. //--------------------------------------------------------------------------
  3909. int CAMCView::HitTestPane(CPoint& point)
  3910. {
  3911. TRACE_METHOD(CAMCView, HitTestPane);
  3912. if (PtInWindow(m_pTreeCtrl, point))
  3913. return ePane_ScopeTree;
  3914. if (m_PaneInfo[ePane_Results].pView &&
  3915. PtInWindow(m_PaneInfo[ePane_Results].pView, point))
  3916. return ePane_Results;
  3917. return ePane_None;
  3918. }
  3919. HNODE CAMCView::GetSelectedNode(void)
  3920. {
  3921. AFX_MANAGE_STATE (AfxGetAppModuleState());
  3922. TRACE_METHOD(CAMCView, GetSelectedNode);
  3923. // When the tree is empty we don't want to AV
  3924. HTREEITEM hti = m_pTreeCtrl->GetSelectedItem();
  3925. if (hti == NULL)
  3926. return NULL;
  3927. HNODE hNode = m_pTreeCtrl->GetItemNode(hti);
  3928. return hNode;
  3929. }
  3930. HNODE CAMCView::GetRootNode(void)
  3931. {
  3932. TRACE_METHOD(CAMCView, GetSelectedNode);
  3933. // When the tree is empty we don't want to AV
  3934. HTREEITEM hti = m_pTreeCtrl->GetRootItem();
  3935. if (hti == NULL)
  3936. return NULL;
  3937. HNODE hNode = m_pTreeCtrl->GetItemNode(hti);
  3938. return hNode;
  3939. }
  3940. /*+-------------------------------------------------------------------------*
  3941. *
  3942. * CAMCView::ScUpdateWindowTitle
  3943. *
  3944. * PURPOSE: Updates the window title and informs observers about the change.
  3945. *
  3946. * RETURNS:
  3947. * SC
  3948. *
  3949. *+-------------------------------------------------------------------------*/
  3950. SC
  3951. CAMCView::ScUpdateWindowTitle()
  3952. {
  3953. DECLARE_SC(sc, TEXT("CAMCView::ScUpdateWindowTitle"));
  3954. CChildFrame* pFrame = GetParentFrame();
  3955. sc = ScCheckPointers(pFrame);
  3956. if(sc)
  3957. return sc;
  3958. if (pFrame)
  3959. pFrame->OnUpdateFrameTitle(TRUE);
  3960. sc = ScFireEvent(CAMCViewObserver::ScOnViewTitleChanged, this);
  3961. return sc;
  3962. }
  3963. BOOL CAMCView::RenameItem(HNODE hNode, BOOL bScopeItem, MMC_COOKIE lResultItemCookie,
  3964. LPWSTR pszText, LRESULT* pResult)
  3965. {
  3966. DECLARE_SC(sc, TEXT("CAMCView::RenameItem"));
  3967. sc = S_FALSE;
  3968. SELECTIONINFO selInfo;
  3969. ZeroMemory(&selInfo, sizeof(selInfo));
  3970. selInfo.m_bScope = bScopeItem;
  3971. selInfo.m_lCookie = lResultItemCookie;
  3972. if (pszText != NULL)
  3973. {
  3974. USES_CONVERSION;
  3975. /*
  3976. * Bug 322184: The snap-in may throw up some UI on this notification.
  3977. * The list or tree may have captured the mouse to look for a drag,
  3978. * which will interfere with the snap-in's UI. Release the capture
  3979. * during the callback and put it back when we're done.
  3980. */
  3981. HWND hwndCapture = ::SetCapture (NULL);
  3982. sc = m_spNodeCallback->Notify(hNode, NCLBK_RENAME,
  3983. reinterpret_cast<LPARAM>(&selInfo), reinterpret_cast<LPARAM>(pszText));
  3984. /*
  3985. * put the capture back
  3986. */
  3987. ::SetCapture (hwndCapture);
  3988. }
  3989. *pResult = (sc == SC(S_OK));
  3990. if (*pResult)
  3991. {
  3992. sc = ScUpdateWindowTitle();
  3993. if(sc)
  3994. sc.TraceAndClear();
  3995. }
  3996. return TRUE;
  3997. }
  3998. BOOL CAMCView::DispatchListCtrlNotificationMsg(LPARAM lParam, LRESULT* pResult)
  3999. {
  4000. DECLARE_SC(sc, TEXT("CAMCView::DispatchListCtrlNotificationMsg"));
  4001. TRACE_METHOD(CAMCView, DispatchListCtrlNotificationMsg);
  4002. NM_LISTVIEW *pNm = reinterpret_cast<NM_LISTVIEW*>(lParam);
  4003. BOOL bReturn = TRUE;
  4004. switch (pNm->hdr.code)
  4005. {
  4006. case NM_RCLICK:
  4007. bReturn = FALSE; // In case of right click send the select notification to the snapin
  4008. // but return FALSE so that message is further processed to display
  4009. // context menu.
  4010. // Fall thro into NM_CLICK
  4011. case NM_CLICK:
  4012. {
  4013. sc = ScOnLeftOrRightMouseClickInListView();
  4014. if (sc)
  4015. return bReturn;
  4016. }
  4017. break;
  4018. case NM_DBLCLK:
  4019. OnListCtrlItemDblClk();
  4020. break;
  4021. case NM_CUSTOMDRAW:
  4022. *pResult = m_pListCtrl->OnCustomDraw (
  4023. reinterpret_cast<NMLVCUSTOMDRAW *>(lParam));
  4024. break;
  4025. case LVN_BEGINLABELEDITA:
  4026. case LVN_BEGINLABELEDITW:
  4027. {
  4028. CMainFrame* pFrame = AMCGetMainWnd();
  4029. if ((pFrame != NULL) && (IsVerbEnabled(MMC_VERB_RENAME) ||
  4030. m_bRenameListPadItem == true))
  4031. {
  4032. pFrame->SetInRenameMode(true);
  4033. return FALSE;
  4034. }
  4035. else
  4036. {
  4037. return TRUE;
  4038. }
  4039. break;
  4040. }
  4041. case LVN_ENDLABELEDITW:
  4042. case LVN_ENDLABELEDITA:
  4043. {
  4044. CMainFrame* pFrame = AMCGetMainWnd();
  4045. if (pFrame != NULL)
  4046. pFrame->SetInRenameMode(false);
  4047. LPARAM lResultParam = 0;
  4048. long index = -1;
  4049. LPWSTR pszText = NULL;
  4050. if (pNm->hdr.code == LVN_ENDLABELEDITW)
  4051. {
  4052. LV_DISPINFOW* pdi = (LV_DISPINFOW*) lParam;
  4053. index = pdi->item.iItem;
  4054. pszText = pdi->item.pszText;
  4055. lResultParam = pdi->item.lParam;
  4056. }
  4057. else // if (pNm->hdr.code == LVN_ENDLABELEDIT)
  4058. {
  4059. LV_DISPINFO* pdi = (LV_DISPINFO*) lParam;
  4060. index = pdi->item.iItem;
  4061. USES_CONVERSION;
  4062. pszText = T2W(pdi->item.pszText);
  4063. lResultParam = pdi->item.lParam;
  4064. }
  4065. if (IsVirtualList())
  4066. {
  4067. // for virtual list pass the item index rather than the lparam
  4068. HNODE hNodeSel = GetSelectedNode();
  4069. RenameItem(hNodeSel, FALSE, index, pszText, pResult);
  4070. }
  4071. else
  4072. {
  4073. CResultItem* pri = CResultItem::FromHandle (lResultParam);
  4074. if (pri != NULL)
  4075. {
  4076. if (pri->IsScopeItem())
  4077. RenameItem(pri->GetScopeNode(), TRUE, 0, pszText, pResult);
  4078. else
  4079. RenameItem(GetSelectedNode(), FALSE, pri->GetSnapinData(), pszText, pResult);
  4080. }
  4081. }
  4082. break;
  4083. }
  4084. case LVN_GETDISPINFOW:
  4085. {
  4086. LV_DISPINFOW *pDispInfo = reinterpret_cast<LV_DISPINFOW*>(lParam);
  4087. // If column is hidden do not forward the call to snapin.
  4088. if (m_pListCtrl && m_pListCtrl->IsColumnHidden(pDispInfo->item.iSubItem))
  4089. break;
  4090. m_spNodeCallback->GetDispInfo (GetSelectedNode(), &pDispInfo->item);
  4091. break;
  4092. }
  4093. case LVN_GETDISPINFOA:
  4094. {
  4095. LV_DISPINFOA *pDispInfo = reinterpret_cast<LV_DISPINFOA*>(lParam);
  4096. ASSERT (pDispInfo != NULL);
  4097. // If column is hidden do not forward the call to snapin.
  4098. if (m_pListCtrl && m_pListCtrl->IsColumnHidden(pDispInfo->item.iSubItem))
  4099. break;
  4100. /*
  4101. * put the data in the UNICODE structure for the query
  4102. */
  4103. LV_ITEMW lviW;
  4104. lviW.mask = pDispInfo->item.mask;
  4105. lviW.iItem = pDispInfo->item.iItem;
  4106. lviW.iSubItem = pDispInfo->item.iSubItem;
  4107. lviW.state = pDispInfo->item.state;
  4108. lviW.stateMask = pDispInfo->item.stateMask;
  4109. lviW.cchTextMax = pDispInfo->item.cchTextMax;
  4110. lviW.iImage = pDispInfo->item.iImage;
  4111. lviW.lParam = pDispInfo->item.lParam;
  4112. lviW.iIndent = pDispInfo->item.iIndent;
  4113. if (pDispInfo->item.mask & LVIF_TEXT)
  4114. lviW.pszText = new WCHAR[pDispInfo->item.cchTextMax];
  4115. /*
  4116. * convert to ANSI
  4117. */
  4118. if (SUCCEEDED (m_spNodeCallback->GetDispInfo (GetSelectedNode(), &lviW)) &&
  4119. (pDispInfo->item.mask & LVIF_TEXT))
  4120. {
  4121. WideCharToMultiByte (CP_ACP, 0, lviW.pszText, -1,
  4122. pDispInfo->item.pszText,
  4123. pDispInfo->item.cchTextMax,
  4124. NULL, NULL);
  4125. }
  4126. if (pDispInfo->item.mask & LVIF_TEXT)
  4127. delete [] lviW.pszText;
  4128. /*
  4129. * copy the results back to the ANSI structure
  4130. */
  4131. pDispInfo->item.mask = lviW.mask;
  4132. pDispInfo->item.iItem = lviW.iItem;
  4133. pDispInfo->item.iSubItem = lviW.iSubItem;
  4134. pDispInfo->item.state = lviW.state;
  4135. pDispInfo->item.stateMask = lviW.stateMask;
  4136. pDispInfo->item.cchTextMax = lviW.cchTextMax;
  4137. pDispInfo->item.iImage = lviW.iImage;
  4138. pDispInfo->item.lParam = lviW.lParam;
  4139. pDispInfo->item.iIndent = lviW.iIndent;
  4140. break;
  4141. }
  4142. case LVN_DELETEALLITEMS:
  4143. // return TRUE to prevent notification for each item
  4144. return TRUE;
  4145. case LVN_ITEMCHANGED:
  4146. bReturn = OnListItemChanged (pNm);
  4147. break;
  4148. case LVN_ODSTATECHANGED:
  4149. // The state of an item or range of items has changed in virtual list.
  4150. return OnVirtualListItemsStateChanged(reinterpret_cast<LPNMLVODSTATECHANGE>(lParam));
  4151. break;
  4152. case LVN_ODFINDITEMA:
  4153. case LVN_ODFINDITEMW:
  4154. {
  4155. USES_CONVERSION;
  4156. NM_FINDITEM *pNmFind = reinterpret_cast<NM_FINDITEM*>(lParam);
  4157. ASSERT(IsVirtualList() && (pNmFind->lvfi.flags & LVFI_STRING));
  4158. LPOLESTR polestr = NULL;
  4159. if (pNm->hdr.code == LVN_ODFINDITEMW)
  4160. {
  4161. LVFINDINFOW* pfiw = reinterpret_cast<LVFINDINFOW*>(&pNmFind->lvfi);
  4162. polestr = const_cast<LPOLESTR>(pfiw->psz);
  4163. }
  4164. else
  4165. {
  4166. LVFINDINFOA* pfi = reinterpret_cast<LVFINDINFOA*>(&pNmFind->lvfi);
  4167. polestr = A2W(const_cast<LPSTR>(pfi->psz));
  4168. }
  4169. Dbg(DEB_USER1, _T("\n********************** polestr = %ws\n"), polestr);
  4170. RESULTFINDINFO findInfo;
  4171. findInfo.psz = polestr;
  4172. findInfo.nStart = pNmFind->iStart;
  4173. findInfo.dwOptions = 0;
  4174. // Listview bug: LVFI_SUBSTRING is not defined in the SDK headers and the
  4175. // listview sets it instead of LVFI_PARTIAL when it wants a
  4176. // partial match. So for now, define it here and test for both.
  4177. #define LVFI_SUBSTRING 0x0004
  4178. if (pNmFind->lvfi.flags & (LVFI_PARTIAL | LVFI_SUBSTRING))
  4179. findInfo.dwOptions |= RFI_PARTIAL;
  4180. if (pNmFind->lvfi.flags & LVFI_WRAP)
  4181. findInfo.dwOptions |= RFI_WRAP;
  4182. HNODE hNodeSel = GetSelectedNode();
  4183. INodeCallback* pNC = GetNodeCallback();
  4184. ASSERT(pNC != NULL);
  4185. pNC->Notify(hNodeSel, NCLBK_FINDITEM,
  4186. reinterpret_cast<LPARAM>(&findInfo),
  4187. reinterpret_cast<LPARAM>(pResult));
  4188. }
  4189. break;
  4190. case LVN_ODCACHEHINT:
  4191. {
  4192. NM_CACHEHINT *pNmHint = reinterpret_cast<NM_CACHEHINT*>(lParam);
  4193. ASSERT(IsVirtualList());
  4194. HNODE hNodeSel = GetSelectedNode();
  4195. INodeCallback* pNC = GetNodeCallback();
  4196. ASSERT(pNC != NULL);
  4197. pNC->Notify(hNodeSel, NCLBK_CACHEHINT, pNmHint->iFrom, pNmHint->iTo);
  4198. }
  4199. break;
  4200. case LVN_KEYDOWN:
  4201. {
  4202. NMLVKEYDOWN *pNmKeyDown = reinterpret_cast<NMLVKEYDOWN*>(lParam);
  4203. switch (pNmKeyDown->wVKey)
  4204. {
  4205. case VK_DELETE:
  4206. {
  4207. if (!IsVerbEnabled(MMC_VERB_DELETE))
  4208. break;
  4209. INodeCallback* pCallback = GetNodeCallback();
  4210. ASSERT(pCallback != NULL);
  4211. if (pCallback == NULL)
  4212. break;
  4213. HNODE hNode = GetSelectedNode();
  4214. if (hNode == 0)
  4215. break;
  4216. int cSel = m_pListCtrl->GetSelectedCount();
  4217. ASSERT(cSel >= 0);
  4218. LPARAM lvData;
  4219. if (cSel == 0)
  4220. {
  4221. break;
  4222. }
  4223. else if (cSel == 1)
  4224. {
  4225. if (_GetLVSelectedItemData(&lvData) == -1)
  4226. break;
  4227. }
  4228. else if (cSel > 1)
  4229. {
  4230. lvData = LVDATA_MULTISELECT;
  4231. }
  4232. else
  4233. {
  4234. break;
  4235. }
  4236. pCallback->Notify(hNode, NCLBK_DELETE, FALSE, lvData);
  4237. break;
  4238. }
  4239. break;
  4240. case VK_TAB:
  4241. GetParentFrame()->SetActiveView (m_pTreeCtrl);
  4242. break;
  4243. case VK_BACK:
  4244. ScUpOneLevel();
  4245. break;
  4246. case VK_RETURN:
  4247. if(GetKeyState(VK_MENU)<0) // has the ALT key been pressed?
  4248. {
  4249. // Process <ALT><ENTER>
  4250. if (! IsVerbEnabled(MMC_VERB_PROPERTIES))
  4251. break;
  4252. LPARAM lvData = 0;
  4253. if (HasList())
  4254. {
  4255. ASSERT (m_pListCtrl != NULL);
  4256. ASSERT (GetParentFrame()->GetActiveView() == m_pListCtrl->GetListViewPtr());
  4257. int cSel = m_pListCtrl->GetSelectedCount();
  4258. ASSERT(cSel >= 0);
  4259. lvData = LVDATA_ERROR;
  4260. if (cSel == 0)
  4261. lvData = LVDATA_BACKGROUND;
  4262. else if (cSel == 1)
  4263. _GetLVSelectedItemData(&lvData);
  4264. else if (cSel > 1)
  4265. lvData = LVDATA_MULTISELECT;
  4266. ASSERT(lvData != LVDATA_ERROR);
  4267. if (lvData == LVDATA_ERROR)
  4268. break;
  4269. if (lvData == LVDATA_BACKGROUND)
  4270. break;
  4271. }
  4272. else if (HasOCX())
  4273. {
  4274. lvData = LVDATA_CUSTOMOCX;
  4275. }
  4276. else
  4277. {
  4278. ASSERT(HasWebBrowser());
  4279. lvData = LVDATA_CUSTOMWEB;
  4280. }
  4281. INodeCallback* pNC = GetNodeCallback();
  4282. ASSERT(pNC != NULL);
  4283. if (pNC == NULL)
  4284. break;
  4285. HNODE hNodeSel = GetSelectedNode();
  4286. ASSERT(hNodeSel != NULL);
  4287. if (hNodeSel == NULL)
  4288. break;
  4289. pNC->Notify(hNodeSel, NCLBK_PROPERTIES, FALSE, lvData);
  4290. break;
  4291. }
  4292. else // nope, the ALT key has not been pressed.
  4293. {
  4294. // do the default verb.
  4295. OnListCtrlItemDblClk();
  4296. }
  4297. break;
  4298. default:
  4299. bReturn = OnSharedKeyDown(pNmKeyDown->wVKey);
  4300. break;
  4301. }
  4302. }
  4303. break;
  4304. default:
  4305. bReturn = FALSE;
  4306. break;
  4307. }
  4308. return bReturn;
  4309. }
  4310. //+-------------------------------------------------------------------
  4311. //
  4312. // Member: CAMCView::ScOnLeftOrRightMouseClickInListView
  4313. //
  4314. // Synopsis: Left or right mouse button is clicked on the list view, see
  4315. // if it is clicked on list-view background. If so send a select.
  4316. //
  4317. // Click on list view background is treated as scope owner item selected.
  4318. //
  4319. // Arguments: None
  4320. //
  4321. // Returns: SC
  4322. //
  4323. //--------------------------------------------------------------------
  4324. SC CAMCView::ScOnLeftOrRightMouseClickInListView()
  4325. {
  4326. DECLARE_SC(sc, TEXT("CAMCView::ScOnLeftOrRightMouseClickInListView"));
  4327. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  4328. if (sc)
  4329. return sc;
  4330. CAMCListView *pAMCListView = m_pListCtrl->GetListViewPtr();
  4331. sc = ScCheckPointers(pAMCListView, E_UNEXPECTED);
  4332. if (sc)
  4333. return sc;
  4334. CPoint pt;
  4335. GetCursorPos(&pt);
  4336. pAMCListView->ScreenToClient(&pt);
  4337. UINT uFlags = 0;
  4338. int iItem = pAMCListView->GetListCtrl().HitTest(pt, &uFlags);
  4339. Dbg(DEB_USER1, _T("----- HitTest > %d \n"), iItem);
  4340. // Make sure mouse click is in the ListView and there are
  4341. // no items selected in the list view.
  4342. if ( (iItem == -1) &&
  4343. !(uFlags & (LVHT_ABOVE | LVHT_BELOW | LVHT_TOLEFT | LVHT_TORIGHT) ) &&
  4344. (m_pListCtrl->GetSelectedCount() == 0) )
  4345. {
  4346. INodeCallback* pNC = GetNodeCallback();
  4347. sc = ScCheckPointers(pNC, E_UNEXPECTED);
  4348. if (sc)
  4349. return sc;
  4350. HNODE hNodeSel = GetSelectedNode();
  4351. SELECTIONINFO selInfo;
  4352. ZeroMemory(&selInfo, sizeof(selInfo));
  4353. selInfo.m_bScope = TRUE;
  4354. selInfo.m_bDueToFocusChange = TRUE;
  4355. selInfo.m_bBackground = TRUE;
  4356. selInfo.m_lCookie = LVDATA_BACKGROUND;
  4357. sc = ScNotifySelect (pNC, hNodeSel, false /*fMultiSelect*/, true, &selInfo);
  4358. if (sc)
  4359. sc.TraceAndClear(); // ignore & continue;
  4360. }
  4361. return (sc);
  4362. }
  4363. /*+-------------------------------------------------------------------------*
  4364. * CAMCView::OnListItemChanged
  4365. *
  4366. * WM_NOTIFY (LVN_ITEMCHANGED) handler for CAMCView.
  4367. *
  4368. * return true as message is handled here.
  4369. *--------------------------------------------------------------------------*/
  4370. bool CAMCView::OnListItemChanged (NM_LISTVIEW* pnmlv)
  4371. {
  4372. DECLARE_SC (sc, _T("CAMCView::OnListItemChanged"));
  4373. bool bOldState = (pnmlv->uOldState & LVIS_SELECTED);
  4374. bool bNewState = (pnmlv->uNewState & LVIS_SELECTED);
  4375. // is this a selection change?
  4376. if ( (pnmlv->uChanged & LVIF_STATE) &&
  4377. (bOldState != bNewState) )
  4378. {
  4379. const int cSelectedItems = m_pListCtrl->GetSelectedCount();
  4380. #ifdef DBG
  4381. Trace (tagListSelection,
  4382. _T("Item %d %sselected, %d total items selected"),
  4383. pnmlv->iItem,
  4384. (pnmlv->uOldState & LVIS_SELECTED) ? _T("de") : _T(" "),
  4385. cSelectedItems);
  4386. #endif
  4387. SELECTIONINFO selInfo;
  4388. ZeroMemory(&selInfo, sizeof(selInfo));
  4389. selInfo.m_bScope = FALSE;
  4390. selInfo.m_pView = NULL;
  4391. selInfo.m_lCookie = IsVirtualList() ? pnmlv->iItem : pnmlv->lParam;
  4392. /*
  4393. * If user is (de)selecting multiple items using control and/or shift keys
  4394. * then defer the multi-select notification until we're quiescent
  4395. * with the exception of only one item being (de)selected.
  4396. */
  4397. if ((IsKeyPressed(VK_SHIFT) || IsKeyPressed(VK_CONTROL)) &&
  4398. (GetParentFrame()->GetActiveView() == m_pListCtrl->GetListViewPtr()) &&
  4399. (cSelectedItems > 1) )
  4400. {
  4401. // See ScPostMultiSelectionChangesMessage (this handles both selection
  4402. // and de-selection of multiple items).
  4403. sc = ScPostMultiSelectionChangesMessage();
  4404. if (sc)
  4405. sc.TraceAndClear();
  4406. return (true);
  4407. }
  4408. else
  4409. {
  4410. m_bProcessMultiSelectionChanges = false;
  4411. }
  4412. HNODE hNodeSel = GetSelectedNode();
  4413. INodeCallback* pNC = GetNodeCallback();
  4414. sc = ScCheckPointers(pNC, (void*) hNodeSel, E_UNEXPECTED);
  4415. if (sc)
  4416. return (true);
  4417. // item = -1 is only expected for deselect in virtual list
  4418. ASSERT( pnmlv->iItem != -1 || (IsVirtualList() && (pnmlv->uOldState & LVIS_SELECTED)));
  4419. if (pnmlv->uOldState & LVIS_SELECTED)
  4420. {
  4421. if (cSelectedItems == 0)
  4422. {
  4423. if (!m_bLastSelWasMultiSel)
  4424. {
  4425. sc = ScNotifySelect (pNC, hNodeSel, false /*fMultiSelect*/, false, &selInfo);
  4426. if (sc)
  4427. sc.TraceAndClear(); // ignore & continue;
  4428. }
  4429. else
  4430. {
  4431. m_bLastSelWasMultiSel = false;
  4432. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, false, 0);
  4433. if (sc)
  4434. sc.TraceAndClear(); // ignore & continue;
  4435. }
  4436. }
  4437. else if (m_bLastSelWasMultiSel)
  4438. {
  4439. // may need to cancel multiselect and send single select notify.
  4440. // if another change comes in, it will cancel the delayed message
  4441. // This fixes a problem that is caused by large icon mode not
  4442. // sending as many noifications as the other modes.
  4443. // See ScPostMultiSelectionChangesMessage (this handles both selection
  4444. // and de-selection of multiple items).
  4445. sc = ScPostMultiSelectionChangesMessage();
  4446. if (sc)
  4447. sc.TraceAndClear();
  4448. }
  4449. }
  4450. else if (pnmlv->uNewState & LVIS_SELECTED)
  4451. {
  4452. ASSERT(cSelectedItems >= 1);
  4453. if (cSelectedItems == 1)
  4454. {
  4455. sc = ScNotifySelect (pNC, hNodeSel, false /*fMultiSelect*/, true, &selInfo);
  4456. if (sc)
  4457. sc.TraceAndClear(); // ignore & continue;
  4458. }
  4459. else
  4460. {
  4461. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, true, 0);
  4462. if (sc)
  4463. sc.TraceAndClear(); // ignore & continue;
  4464. m_bLastSelWasMultiSel = true;
  4465. }
  4466. }
  4467. }
  4468. return (true);
  4469. }
  4470. //+-------------------------------------------------------------------
  4471. //
  4472. // Member: CAMCView::OnVirtualListItemsStateChanged
  4473. //
  4474. // Synopsis: The state of an item or range of items has changed in virtual list.
  4475. //
  4476. // Arguments: lpStateChange -
  4477. //
  4478. // Returns: should return 0 according to docs.
  4479. //
  4480. //--------------------------------------------------------------------
  4481. int CAMCView::OnVirtualListItemsStateChanged(LPNMLVODSTATECHANGE lpStateChange )
  4482. {
  4483. DECLARE_SC(sc, TEXT("CAMCView::OnVirtualListItemsStateChanged"));
  4484. sc = ScCheckPointers(lpStateChange);
  4485. if (sc)
  4486. {
  4487. sc.TraceAndClear();
  4488. return 0;
  4489. }
  4490. bool bOldState = (lpStateChange->uOldState & LVIS_SELECTED);
  4491. bool bNewState = (lpStateChange->uNewState & LVIS_SELECTED);
  4492. int cItems = (lpStateChange->iTo - lpStateChange->iFrom) + 1;
  4493. #ifdef DBG
  4494. Trace (tagListSelection,
  4495. _T("Items %d to %d were %sselected, %d total items selected"),
  4496. lpStateChange->iFrom, lpStateChange->iTo,
  4497. bOldState ? _T("de") : _T(" "),
  4498. cItems );
  4499. #endif
  4500. if (bOldState != bNewState)
  4501. {
  4502. sc = ScPostMultiSelectionChangesMessage();
  4503. if (sc)
  4504. sc.TraceAndClear();
  4505. }
  4506. return (0);
  4507. }
  4508. //+-------------------------------------------------------------------
  4509. //
  4510. // Member: CAMCView::ScPostMultiSelectionChangesMessage
  4511. //
  4512. // Synopsis: Post selection change message (need to post because multi-sel
  4513. // may not be over, wait till it is quiet.)
  4514. //
  4515. // This method posts message telling selection states of multiple
  4516. // items are changed but not if they are selected or de-selected.
  4517. // The m_bLastSelWasMultiSel is used to determine if it is
  4518. // selection or de-selection.
  4519. //
  4520. // Arguments:
  4521. //
  4522. // Returns: SC
  4523. //
  4524. //--------------------------------------------------------------------
  4525. SC CAMCView::ScPostMultiSelectionChangesMessage ()
  4526. {
  4527. DECLARE_SC(sc, _T("CAMCView::ScPostMultiSelectionChangesMessage"));
  4528. /*
  4529. * This is a multi-selection, defer notification until we're quiescent
  4530. */
  4531. m_bProcessMultiSelectionChanges = true;
  4532. PostMessage (m_nProcessMultiSelectionChangesMsg);
  4533. // We need to disable all the toolbars, menubuttons
  4534. // during multiselect. Above PostMessage enables
  4535. // stdbar and MMC menubuttons.
  4536. CAMCViewToolbarsMgr* pAMCViewToolbarsMgr = m_ViewData.GetAMCViewToolbarsMgr();
  4537. CMenuButtonsMgr* pMenuBtnsMgr = m_ViewData.GetMenuButtonsMgr();
  4538. sc = ScCheckPointers(pAMCViewToolbarsMgr, pMenuBtnsMgr, E_UNEXPECTED);
  4539. if (sc)
  4540. return 0;
  4541. pAMCViewToolbarsMgr->ScDisableToolbars();
  4542. pMenuBtnsMgr->ScDisableMenuButtons();
  4543. return (sc);
  4544. }
  4545. void CAMCView::OpenResultItem(HNODE hNode)
  4546. {
  4547. /*
  4548. * Bug 139695: Make certain this function doesn't need to change the
  4549. * active view. We should only get here as a result of double- clicking
  4550. * or pressing Enter on a scope node in the result pane, in which case
  4551. * the result pane should already be the active view. If it is, we don't
  4552. * need to change the active view, which can cause the problems listed in
  4553. * the bug.
  4554. */
  4555. ASSERT (m_pListCtrl != NULL);
  4556. ASSERT (GetParentFrame() != NULL);
  4557. ASSERT (GetParentFrame()->GetActiveView() == m_pListCtrl->GetListViewPtr());
  4558. ASSERT(m_pTreeCtrl);
  4559. HTREEITEM htiParent = m_pTreeCtrl->GetSelectedItem();
  4560. ASSERT(htiParent != NULL);
  4561. m_pTreeCtrl->ExpandNode(htiParent);
  4562. m_pTreeCtrl->Expand(htiParent, TVE_EXPAND);
  4563. HTREEITEM hti = m_pTreeCtrl->GetChildItem(htiParent);
  4564. if (hti == NULL)
  4565. return;
  4566. while (hti)
  4567. {
  4568. if (m_pTreeCtrl->GetItemNode(hti) == hNode)
  4569. break;
  4570. hti = m_pTreeCtrl->GetNextItem(hti, TVGN_NEXT);
  4571. }
  4572. if (hti != 0)
  4573. {
  4574. m_pTreeCtrl->Expand(htiParent, TVE_EXPAND);
  4575. m_pTreeCtrl->SelectItem(hti);
  4576. }
  4577. }
  4578. BOOL CAMCView::OnListCtrlItemDblClk(void)
  4579. {
  4580. TRACE_METHOD(CAMCView, OnListCtrlItemDblClk);
  4581. LPARAM lvData = -1;
  4582. if (_GetLVSelectedItemData(&lvData) == -1)
  4583. lvData = LVDATA_BACKGROUND;
  4584. HNODE hNodeSel = GetSelectedNode();
  4585. INodeCallback* pNC = GetNodeCallback();
  4586. ASSERT(pNC != NULL);
  4587. if (!pNC)
  4588. return FALSE;
  4589. HRESULT hr = pNC->Notify(hNodeSel, NCLBK_DBLCLICK, lvData, 0);
  4590. if (hr == S_FALSE)
  4591. {
  4592. ASSERT(lvData != LVDATA_BACKGROUND);
  4593. if (!IsVirtualList())
  4594. {
  4595. CResultItem* pri = CResultItem::FromHandle (lvData);
  4596. if ((pri != NULL) && pri->IsScopeItem())
  4597. OpenResultItem (pri->GetScopeNode());
  4598. }
  4599. }
  4600. return TRUE;
  4601. }
  4602. BOOL CAMCView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  4603. {
  4604. DECLARE_SC(sc, TEXT("CAMCView::OnNotify"));
  4605. NMHDR *pNmHdr = reinterpret_cast<NMHDR*>(lParam);
  4606. sc = ScCheckPointers(pNmHdr, pResult);
  4607. if (sc)
  4608. {
  4609. sc.TraceAndClear();
  4610. return CView::OnNotify(wParam, lParam, pResult);
  4611. }
  4612. *pResult = TRUE; // init
  4613. switch(pNmHdr->code)
  4614. {
  4615. case HDN_ENDTRACKA: // Save the column width changes.
  4616. case HDN_ENDTRACKW: // HDN_BEGINTRACK handles dis-allowing hidden column dragging.
  4617. {
  4618. NMHEADER* nmh = (NMHEADER*)lParam;
  4619. CAMCListView *pAMCListView = m_pListCtrl->GetListViewPtr();
  4620. SC sc = ScCheckPointers(pAMCListView, E_UNEXPECTED);
  4621. if (sc)
  4622. {
  4623. sc.TraceAndClear();
  4624. return FALSE;
  4625. }
  4626. sc = pAMCListView->ScOnColumnsAttributeChanged(nmh, HDN_ENDTRACK);
  4627. if (sc)
  4628. {
  4629. sc.TraceAndClear();
  4630. return FALSE;
  4631. }
  4632. // S_FALSE : dont allow the change
  4633. if (sc == SC(S_FALSE))
  4634. return TRUE;
  4635. return CView::OnNotify(wParam, lParam, pResult);
  4636. }
  4637. break;
  4638. case HDN_ENDDRAG: // Column order changes.
  4639. {
  4640. NMHEADER* nmh = (NMHEADER*)lParam;
  4641. if (nmh->pitem->mask & HDI_ORDER)
  4642. {
  4643. CAMCListView *pAMCListView = m_pListCtrl->GetListViewPtr();
  4644. SC sc = ScCheckPointers(pAMCListView, E_UNEXPECTED);
  4645. if (sc)
  4646. {
  4647. sc.TraceAndClear();
  4648. return FALSE;
  4649. }
  4650. sc = pAMCListView->ScOnColumnsAttributeChanged(nmh, HDN_ENDDRAG);
  4651. if (sc)
  4652. {
  4653. sc.TraceAndClear();
  4654. return FALSE;
  4655. }
  4656. // S_FALSE : dont allow the change
  4657. if (sc = SC(S_FALSE))
  4658. return TRUE;
  4659. }
  4660. return CView::OnNotify(wParam, lParam, pResult);
  4661. }
  4662. break;
  4663. case TVN_BEGINLABELEDIT:
  4664. {
  4665. TV_DISPINFO* ptvdi = (TV_DISPINFO*)lParam;
  4666. if ((ptvdi->item.lParam == CAMCTreeView::LParamFromNode (GetSelectedNode())) &&
  4667. (IsVerbEnabled(MMC_VERB_RENAME) == FALSE))
  4668. {
  4669. return TRUE;
  4670. }
  4671. CMainFrame* pFrame = AMCGetMainWnd();
  4672. if (pFrame != NULL)
  4673. pFrame->SetInRenameMode(true);
  4674. return FALSE;
  4675. }
  4676. case TVN_ENDLABELEDIT:
  4677. {
  4678. TV_DISPINFO* ptvdi = (TV_DISPINFO*)lParam;
  4679. CMainFrame* pFrame = AMCGetMainWnd();
  4680. if (pFrame != NULL)
  4681. pFrame->SetInRenameMode(false);
  4682. USES_CONVERSION;
  4683. return RenameItem(CAMCTreeView::NodeFromLParam (ptvdi->item.lParam), TRUE, 0,
  4684. T2W(ptvdi->item.pszText), pResult);
  4685. }
  4686. case TVN_KEYDOWN:
  4687. {
  4688. TV_KEYDOWN* ptvkd = reinterpret_cast<TV_KEYDOWN*>(lParam);
  4689. if (ptvkd->wVKey == VK_TAB)
  4690. {
  4691. ScSetFocusToResultPane();
  4692. return TRUE;
  4693. }
  4694. else
  4695. {
  4696. return OnSharedKeyDown(ptvkd->wVKey);
  4697. }
  4698. }
  4699. }
  4700. if (UsingDefColumns() &&
  4701. (pNmHdr->code == HDN_ENDTRACKA || pNmHdr->code == HDN_ENDTRACKW))
  4702. {
  4703. // WARNING: If HD_NOTIFY::pitem::pszText needs to be used you should cast
  4704. // lParam to either HD_NOTIFYA or HD_NOTIFYW depending on the pNmHdr->code
  4705. HD_NOTIFY* phdn = reinterpret_cast<HD_NOTIFY*>(lParam);
  4706. ASSERT(phdn != NULL);
  4707. if (phdn->pitem->mask & HDI_WIDTH)
  4708. {
  4709. int alWidths[2] = {0, 0};
  4710. GetDefaultColumnWidths(alWidths);
  4711. alWidths[phdn->iItem] = phdn->pitem->cxy;
  4712. SetDefaultColumnWidths(alWidths, FALSE);
  4713. return TRUE;
  4714. }
  4715. }
  4716. #ifdef DBG
  4717. if (m_pTreeCtrl && m_pTreeCtrl->m_hWnd == pNmHdr->hwndFrom)
  4718. {
  4719. switch (pNmHdr->code)
  4720. {
  4721. case NM_CLICK: Dbg(DEB_USER2, "\t Tree item clicked\n"); break;
  4722. case NM_DBLCLK: Dbg(DEB_USER2, "\t Tree item dbl-clicked\n"); break;
  4723. case NM_RCLICK: Dbg(DEB_USER2, "\t Tree item R-clicked\n"); break;
  4724. default: break;
  4725. }
  4726. }
  4727. #endif
  4728. // HasList() is added to prevent dispatching notifications, when AMCView thinks
  4729. // it does not have a list. This lead to wrong assumptions about the list type
  4730. // and as a result - AV handling messages like GetDisplayInfo
  4731. // See BUG 451896
  4732. if (m_pListCtrl && HasListOrListPad())
  4733. {
  4734. if (m_pListCtrl->GetListViewHWND() == pNmHdr->hwndFrom)
  4735. {
  4736. if (DispatchListCtrlNotificationMsg(lParam, pResult) == TRUE)
  4737. return TRUE;
  4738. }
  4739. else if (m_pListCtrl->GetHeaderCtrl() && m_pListCtrl->GetHeaderCtrl()->m_hWnd == pNmHdr->hwndFrom)
  4740. {
  4741. switch(pNmHdr->code)
  4742. {
  4743. case HDN_ITEMCLICKA:
  4744. case HDN_ITEMCLICKW:
  4745. {
  4746. HNODE hNodeSel = GetSelectedNode();
  4747. HD_NOTIFY* phdn = reinterpret_cast<HD_NOTIFY*>(lParam);
  4748. ASSERT(phdn != NULL);
  4749. int nCol = phdn->iItem;
  4750. sc = m_spNodeCallback->Notify(hNodeSel, NCLBK_COLUMN_CLICKED, 0, nCol);
  4751. if (sc)
  4752. sc.TraceAndClear();
  4753. return TRUE;
  4754. }
  4755. // filter related code
  4756. case HDN_FILTERCHANGE:
  4757. {
  4758. HNODE hNodeSel = GetSelectedNode();
  4759. int nCol = ((NMHEADER*)lParam)->iItem;
  4760. sc = m_spNodeCallback->Notify(hNodeSel, NCLBK_FILTER_CHANGE, MFCC_VALUE_CHANGE, nCol);
  4761. if (sc)
  4762. sc.TraceAndClear();
  4763. return TRUE;
  4764. }
  4765. case HDN_FILTERBTNCLICK:
  4766. {
  4767. HNODE hNodeSel = GetSelectedNode();
  4768. int nCol = ((NMHDFILTERBTNCLICK*)lParam)->iItem;
  4769. RECT rc = ((NMHDFILTERBTNCLICK*)lParam)->rc;
  4770. // rect is relative to owning list box, convert to screen
  4771. ::MapWindowPoints(m_pListCtrl->GetListViewHWND(), NULL, (LPPOINT)&rc, 2);
  4772. sc = m_spNodeCallback->Notify(hNodeSel, NCLBK_FILTERBTN_CLICK, nCol, (LPARAM)&rc);
  4773. *pResult = (sc == SC(S_OK));
  4774. if (sc)
  4775. sc.TraceAndClear();
  4776. return TRUE;
  4777. }
  4778. }
  4779. }
  4780. }
  4781. return CView::OnNotify(wParam, lParam, pResult);
  4782. }
  4783. /*+-------------------------------------------------------------------------*
  4784. *
  4785. * CAMCView::ScOnMinimize
  4786. *
  4787. * PURPOSE: Send the NCLBK_MINIMIZED notification to the node manager.
  4788. *
  4789. * PARAMETERS:
  4790. * bool fMinimized : TRUE if the window is being minimized, false if maximized.
  4791. *
  4792. * RETURNS:
  4793. * SC
  4794. *
  4795. *+-------------------------------------------------------------------------*/
  4796. SC
  4797. CAMCView::ScOnMinimize(bool fMinimized)
  4798. {
  4799. DECLARE_SC(sc, TEXT("CAMCView::ScOnMinimize"));
  4800. HNODE hNode = GetSelectedNode();
  4801. if (hNode == NULL)
  4802. return (sc = E_FAIL);
  4803. INodeCallback* pNodeCallback = GetNodeCallback();
  4804. if (pNodeCallback == NULL)
  4805. return (sc = E_FAIL);
  4806. sc = pNodeCallback->Notify (hNode, NCLBK_MINIMIZED, fMinimized, 0);
  4807. return sc;
  4808. }
  4809. /*+-------------------------------------------------------------------------*
  4810. *
  4811. * CAMCView::ScOnSize
  4812. *
  4813. * PURPOSE: Send the size notification to all
  4814. *
  4815. * PARAMETERS:
  4816. * UINT nType :
  4817. * int cx :
  4818. * int cy :
  4819. *
  4820. * RETURNS:
  4821. * SC
  4822. *
  4823. *+-------------------------------------------------------------------------*/
  4824. SC
  4825. CAMCView::ScOnSize(UINT nType, int cx, int cy)
  4826. {
  4827. DECLARE_SC(sc, TEXT("CAMCView::ScOnSize"));
  4828. if (IsPersisted() && GetDocument())
  4829. GetDocument()->SetFrameModifiedFlag(true);
  4830. sc = ScFireEvent(CAMCViewObserver::ScOnViewResized, this, nType, cx, cy);
  4831. return sc;
  4832. }
  4833. /*+-------------------------------------------------------------------------*
  4834. *
  4835. * CAMCView::ScActivate
  4836. *
  4837. * PURPOSE: Sets the view as the active view.
  4838. *
  4839. * RETURNS:
  4840. * SC
  4841. *
  4842. *+-------------------------------------------------------------------------*/
  4843. SC
  4844. CAMCView::ScActivate()
  4845. {
  4846. DECLARE_SC(sc, TEXT("CAMCView::ScActivate"));
  4847. // get the child frame.
  4848. CChildFrame * pChildFrame = GetParentFrame();
  4849. sc = ScCheckPointers(pChildFrame);
  4850. if(sc)
  4851. return sc;
  4852. if (pChildFrame->IsIconic())
  4853. pChildFrame->MDIRestore();
  4854. else
  4855. pChildFrame->MDIActivate(); // activate the child frame.
  4856. return sc;
  4857. }
  4858. void CAMCView::OnContextMenu(CWnd* pWnd, CPoint point)
  4859. {
  4860. TRACE_METHOD(CAMCView, OnContextMenu);
  4861. /*
  4862. * make sure this child frame is active
  4863. */
  4864. GetParentFrame()->MDIActivate();
  4865. if (NULL == m_pTreeCtrl)
  4866. {
  4867. TRACE(_T("CAMCView::OnContextMenu: tree control not ready\n" ));
  4868. return;
  4869. }
  4870. // (-1,-1) => came from context menu key or Shift-F10
  4871. // Pop-up context for whatever has focus
  4872. if (point.x == -1 && point.y == -1)
  4873. {
  4874. OnShiftF10();
  4875. return;
  4876. }
  4877. switch (HitTestPane(point))
  4878. {
  4879. case ePane_Results:
  4880. {
  4881. CPoint pointListCtrlCoord = point;
  4882. CListView* pListView = m_pListCtrl->GetListViewPtr();
  4883. pListView->ScreenToClient(&pointListCtrlCoord);
  4884. CWnd* pwndHit = pListView->ChildWindowFromPoint (pointListCtrlCoord,
  4885. CWP_SKIPINVISIBLE);
  4886. /*
  4887. * if the hit window isn't the list view, it must be the list's
  4888. * header window; ignore the context menu request
  4889. */
  4890. if (pwndHit != pListView)
  4891. {
  4892. TRACE (_T("CAMCView::OnContextMenu: ignore right-click on result pane header\n"));
  4893. break;
  4894. }
  4895. if (NULL != m_pListCtrl && pWnd->m_hWnd == m_pListCtrl->GetListViewHWND())
  4896. OnListContextMenu(point);
  4897. else
  4898. TRACE(_T("CAMCView::OnContextMenu: result control not ready\n"));
  4899. // CODEWORK should do something here
  4900. break;
  4901. }
  4902. case ePane_ScopeTree:
  4903. {
  4904. TRACE(_T("CAMCView::OnContextMenu: handle right-click on scope pane\n"));
  4905. CPoint pointTreeCtrlCoord = point;
  4906. m_pTreeCtrl->ScreenToClient(&pointTreeCtrlCoord);
  4907. OnTreeContextMenu( point, pointTreeCtrlCoord, NULL );
  4908. break;
  4909. }
  4910. case ePane_Tasks:
  4911. // TO BE ADDED - put up taskpad context menu
  4912. break;
  4913. case ePane_None:
  4914. TRACE(_T("CAMCView::OnContextMenu: ignore right-click on splitter\n"));
  4915. break;
  4916. default:
  4917. TRACE(_T("CAMCView::OnContextMenu: unexpected return value from HitTestPane()\n"));
  4918. ASSERT(FALSE);
  4919. }
  4920. }
  4921. void CAMCView::OnTreeContextMenu(CPoint& point, CPoint& pointClientCoord, HTREEITEM htiRClicked)
  4922. {
  4923. TRACE_METHOD(CAMCView, OnTreeContextMenu);
  4924. if (NULL == m_pTreeCtrl)
  4925. {
  4926. TRACE(_T("CAMCTreeView::OnTreeContextMenu: IFrame not ready\n"));
  4927. return;
  4928. }
  4929. UINT fHitTestFlags = TVHT_ONITEM;
  4930. if (htiRClicked == NULL)
  4931. htiRClicked = m_pTreeCtrl->HitTest(pointClientCoord, &fHitTestFlags);
  4932. switch(fHitTestFlags)
  4933. {
  4934. case TVHT_ABOVE:
  4935. case TVHT_BELOW:
  4936. case TVHT_TOLEFT:
  4937. case TVHT_TORIGHT:
  4938. // Outside the tree view area so return without doing anything.
  4939. return;
  4940. default:
  4941. break;
  4942. }
  4943. if (NULL == htiRClicked || !(fHitTestFlags & TVHT_ONITEM))
  4944. {
  4945. OnContextMenuForTreeBackground(point);
  4946. }
  4947. else
  4948. {
  4949. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(htiRClicked);
  4950. ASSERT(hNode != 0);
  4951. OnContextMenuForTreeItem(INDEX_INVALID, hNode, point, CCT_SCOPE, htiRClicked);
  4952. }
  4953. }
  4954. void CAMCView::OnContextMenuForTreeItem(int iIndex, HNODE hNode,
  4955. CPoint& point, DATA_OBJECT_TYPES type_of_pane,
  4956. HTREEITEM htiRClicked, MMC_CONTEXT_MENU_TYPES eMenuType,
  4957. LPCRECT prcExclude, bool bAllowDefaultItem)
  4958. {
  4959. TRACE_METHOD(CAMCView, OnContextMenuForTreeItem);
  4960. DECLARE_SC (sc, _T("CAMCView::OnContextMenuForTreeItem"));
  4961. ASSERT(hNode != 0);
  4962. CContextMenuInfo contextInfo;
  4963. contextInfo.m_displayPoint.x = point.x;
  4964. contextInfo.m_displayPoint.y = point.y;
  4965. contextInfo.m_eContextMenuType = eMenuType;
  4966. contextInfo.m_eDataObjectType = CCT_SCOPE;
  4967. contextInfo.m_bBackground = FALSE;
  4968. contextInfo.m_bScopeAllowed = IsScopePaneAllowed();
  4969. contextInfo.m_hWnd = m_hWnd;
  4970. contextInfo.m_pConsoleView = this;
  4971. contextInfo.m_bAllowDefaultItem = bAllowDefaultItem;
  4972. contextInfo.m_hSelectedScopeNode = GetSelectedNode();
  4973. contextInfo.m_htiRClicked = htiRClicked;
  4974. contextInfo.m_iListItemIndex = iIndex;
  4975. /*
  4976. * if given, initialize the rectangle not to obscure
  4977. */
  4978. if (prcExclude != NULL)
  4979. contextInfo.m_rectExclude = *prcExclude;
  4980. // If selected scope node is same as node for which context menu is
  4981. // needed, then add savelist, view menus
  4982. if (contextInfo.m_hSelectedScopeNode == hNode)
  4983. {
  4984. // Show view owner items
  4985. contextInfo.m_dwFlags |= CMINFO_SHOW_VIEWOWNER_ITEMS;
  4986. // Don't need to remove temporary selection, since none was applied
  4987. contextInfo.m_pConsoleTree = NULL;
  4988. if (eMenuType == MMC_CONTEXT_MENU_DEFAULT)
  4989. contextInfo.m_dwFlags |= CMINFO_SHOW_VIEW_ITEMS;
  4990. if (HasListOrListPad())
  4991. contextInfo.m_dwFlags |= CMINFO_SHOW_SAVE_LIST;
  4992. }
  4993. else if (htiRClicked) // htiRClicked is NULL for tree items in list view.
  4994. {
  4995. // TempNodeSelect == TRUE -> menu is not for the node that owns the result pane
  4996. sc = m_pTreeCtrl->ScSetTempSelection (htiRClicked);
  4997. if (sc)
  4998. return;
  4999. contextInfo.m_pConsoleTree = m_pTreeCtrl;
  5000. contextInfo.m_dwFlags |= CMINFO_USE_TEMP_VERB;
  5001. }
  5002. if (htiRClicked)
  5003. contextInfo.m_dwFlags |= CMINFO_DO_SCOPEPANE_MENU;
  5004. else
  5005. contextInfo.m_dwFlags |= CMINFO_SCOPEITEM_IN_RES_PANE;
  5006. if (HasListOrListPad())
  5007. contextInfo.m_spListView = m_pListCtrl;
  5008. INodeCallback* spNodeCallback = GetNodeCallback();
  5009. ASSERT(spNodeCallback != NULL);
  5010. HRESULT hr = spNodeCallback->Notify(hNode, NCLBK_CONTEXTMENU, 0,
  5011. reinterpret_cast<LPARAM>(&contextInfo));
  5012. }
  5013. /*+-------------------------------------------------------------------------*
  5014. *
  5015. * CAMCView::GetTaskpadID
  5016. *
  5017. * PURPOSE: returns the GUID id of the currently selected taskpad.
  5018. *
  5019. * RETURNS:
  5020. * GUID : the taskpad, if any, else GUID_NULL.
  5021. *
  5022. *+-------------------------------------------------------------------------*/
  5023. void
  5024. CAMCView::GetTaskpadID(GUID &guidID)
  5025. {
  5026. ITaskCallback * pTaskCallback = m_ViewData.m_spTaskCallback;
  5027. if(pTaskCallback != NULL)
  5028. {
  5029. pTaskCallback->GetTaskpadID(&guidID);
  5030. }
  5031. else
  5032. {
  5033. guidID = GUID_NULL;
  5034. }
  5035. }
  5036. /*+-------------------------------------------------------------------------*
  5037. *
  5038. * CAMCView::ScInitializeMemento
  5039. *
  5040. * PURPOSE: Initializes the memento from the current view.
  5041. *
  5042. * PARAMETERS:
  5043. * CMemento & memento :
  5044. *
  5045. * RETURNS:
  5046. * SC
  5047. *
  5048. *+-------------------------------------------------------------------------*/
  5049. SC
  5050. CAMCView::ScInitializeMemento(CMemento &memento)
  5051. {
  5052. DECLARE_SC(sc, TEXT("CAMCView::ScInitializeMemento"));
  5053. sc = GetSelectedNodePath(&memento.GetBookmark());
  5054. if (sc)
  5055. return sc;
  5056. GUID guidTaskpad = GUID_NULL;
  5057. HNODE hNode = GetSelectedNode();
  5058. // get Result pane stuff from snapin
  5059. CResultViewType rvt;
  5060. sc = GetNodeCallback()->GetResultPane(hNode, rvt, &guidTaskpad /*this is not used*/);
  5061. if (sc)
  5062. return sc;
  5063. CViewSettings& viewSettings = memento.GetViewSettings();
  5064. // Initialize the CViewSettings.
  5065. sc = viewSettings.ScSetResultViewType(rvt);
  5066. if (sc)
  5067. return sc;
  5068. GUID guid;
  5069. GetTaskpadID(guid); // we use this guid instead of guidTaskpad because
  5070. // the memento should contain the taskpad that is currently being displayed.
  5071. sc = viewSettings.ScSetTaskpadID(guid);
  5072. return sc;
  5073. }
  5074. /*+-------------------------------------------------------------------------*
  5075. *
  5076. * CAMCView::OnAddToFavorites
  5077. *
  5078. * PURPOSE: Creates a memento from the currently configured view. Saves it into a
  5079. * shortcut.
  5080. *
  5081. * RETURNS:
  5082. * void
  5083. *
  5084. *+-------------------------------------------------------------------------*/
  5085. void CAMCView::OnAddToFavorites()
  5086. {
  5087. DECLARE_SC(sc , _T("CAMCView::OnAddToFavorites"));
  5088. USES_CONVERSION;
  5089. CAMCDoc* pDoc = GetDocument();
  5090. sc = ScCheckPointers(pDoc, E_UNEXPECTED);
  5091. if (sc)
  5092. return;
  5093. IScopeTree* const pScopeTree = GetScopeTreePtr();
  5094. sc = ScCheckPointers(pScopeTree, E_UNEXPECTED);
  5095. if (sc)
  5096. return;
  5097. CMemento memento;
  5098. sc = ScInitializeMemento(memento); // init the memento with the current view settings.
  5099. if(sc)
  5100. return;
  5101. HNODE hNode = GetSelectedNode();
  5102. tstring strName;
  5103. sc = GetNodeCallback()->GetDisplayName(hNode, strName);
  5104. if (sc)
  5105. return;
  5106. HMTNODE hmtNode;
  5107. sc = m_spNodeCallback->GetMTNode(hNode, &hmtNode);
  5108. if (sc)
  5109. return;
  5110. CCoTaskMemPtr<WCHAR> spszPath;
  5111. sc = pScopeTree->GetPathString(NULL, hmtNode, &spszPath);
  5112. if (sc)
  5113. return;
  5114. sc = ScCheckPointers(pDoc->GetFavorites(), E_UNEXPECTED);
  5115. if (sc)
  5116. return;
  5117. sc = pDoc->GetFavorites()->AddToFavorites(strName.data(), W2CT(spszPath), memento, this);
  5118. if (sc)
  5119. return;
  5120. pDoc->SetModifiedFlag();
  5121. }
  5122. void CAMCView::OnContextMenuForTreeBackground(CPoint& point, LPCRECT prcExclude, bool bAllowDefaultItem)
  5123. {
  5124. TRACE_METHOD(CAMCView, OnContextMenuForTreeBackground);
  5125. HNODE hNode = NULL;
  5126. CContextMenuInfo contextInfo;
  5127. contextInfo.m_displayPoint.x = point.x;
  5128. contextInfo.m_displayPoint.y = point.y;
  5129. contextInfo.m_eDataObjectType = CCT_SCOPE;
  5130. contextInfo.m_bBackground = TRUE;
  5131. contextInfo.m_bScopeAllowed = IsScopePaneAllowed();
  5132. contextInfo.m_hWnd = m_hWnd;
  5133. contextInfo.m_pConsoleView = this;
  5134. contextInfo.m_bAllowDefaultItem = bAllowDefaultItem;
  5135. /*
  5136. * if given, initialize the rectangle not to obscure
  5137. */
  5138. if (prcExclude != NULL)
  5139. contextInfo.m_rectExclude = *prcExclude;
  5140. INodeCallback* spNodeCallback = GetNodeCallback();
  5141. ASSERT(spNodeCallback != NULL);
  5142. HRESULT hr = spNodeCallback->Notify(hNode, NCLBK_CONTEXTMENU, 0,
  5143. reinterpret_cast<LPARAM>(&contextInfo));
  5144. }
  5145. SC CAMCView::ScWebCommand (WebCommand eCommand)
  5146. {
  5147. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5148. if (m_pWebViewCtrl == NULL)
  5149. {
  5150. ASSERT (m_pHistoryList);
  5151. if (!m_pHistoryList)
  5152. return FALSE;
  5153. // this is the case when we don't have a web control yet....
  5154. bool bHandled = false;
  5155. switch (eCommand)
  5156. {
  5157. case eWeb_Back:
  5158. m_pHistoryList->Back (bHandled);
  5159. ASSERT(bHandled);
  5160. break;
  5161. case eWeb_Forward:
  5162. m_pHistoryList->Forward (bHandled);
  5163. ASSERT(bHandled);
  5164. break;
  5165. default:
  5166. return FALSE;
  5167. }
  5168. return TRUE;
  5169. }
  5170. switch (eCommand)
  5171. {
  5172. case eWeb_Back: m_pWebViewCtrl->Back(); break;
  5173. case eWeb_Forward: m_pWebViewCtrl->Forward(); break;
  5174. case eWeb_Home: ASSERT(0 && "Should not come here! - remove all code related to Web_Home"); break;
  5175. case eWeb_Refresh: m_pWebViewCtrl->Refresh(); break;
  5176. case eWeb_Stop: m_pWebViewCtrl->Stop(); break;
  5177. default: ASSERT(0); return FALSE;
  5178. }
  5179. return TRUE;
  5180. }
  5181. /*+-------------------------------------------------------------------------*
  5182. *
  5183. * CAMCView::ScCreateTaskpadHost
  5184. *
  5185. * PURPOSE: Creates a legacy (snapin taskpad) host interface pointer
  5186. *
  5187. * NOTE: When a view containing a taskpad is navigated away from, the amcview
  5188. * forgets about the taskpad host pointer, but the html window does not.
  5189. * When the same view is re-navigated to using History, the amcview needs
  5190. * a taskpad host pointer, so a new instance is created. Thus at this point
  5191. * the amcview and the HTML have pointers to different taskpad host
  5192. * objects. This is OK, because both objects are initialized to the same
  5193. * amcview, and contain no other state
  5194. *
  5195. * RETURNS:
  5196. * SC
  5197. *
  5198. *+-------------------------------------------------------------------------*/
  5199. SC
  5200. CAMCView::ScCreateTaskpadHost()
  5201. {
  5202. DECLARE_SC(sc , _T("CAMCView::ScCreateTaskpadHost"));
  5203. if(m_spTaskPadHost != NULL)
  5204. return sc;
  5205. CComObject<CTaskPadHost>* pTaskPadHost = NULL;
  5206. sc = CComObject<CTaskPadHost>::CreateInstance(&pTaskPadHost);
  5207. if (sc)
  5208. return sc;
  5209. sc = ScCheckPointers (pTaskPadHost, E_UNEXPECTED);
  5210. if (sc)
  5211. return sc;
  5212. pTaskPadHost->Init (this);
  5213. m_spTaskPadHost = pTaskPadHost;
  5214. return sc;
  5215. }
  5216. LRESULT CAMCView::OnConnectToCIC (WPARAM wParam, LPARAM lParam)
  5217. {
  5218. DECLARE_SC (sc, _T("CAMCView::OnConnectToCIC"));
  5219. // fill out wparam, which is an IUnknown ** (alloc'd by CIC)
  5220. ASSERT (wParam != NULL);
  5221. IUnknown ** ppunk = (IUnknown **)wParam;
  5222. ASSERT (!IsBadReadPtr (ppunk, sizeof(IUnknown *)));
  5223. ASSERT (!IsBadWritePtr (ppunk, sizeof(IUnknown *)));
  5224. sc = ScCheckPointers (ppunk);
  5225. if (sc)
  5226. return (sc.ToHr());
  5227. // lParam holds MMCCtrl's IUnknown: we can hang onto this if we
  5228. // need it. Presently not saved or used.
  5229. sc = ScCreateTaskpadHost();
  5230. if(sc)
  5231. return sc.ToHr();
  5232. sc = ScCheckPointers(m_spTaskPadHost, E_UNEXPECTED);
  5233. if(sc)
  5234. return sc.ToHr();;
  5235. sc = m_spTaskPadHost->QueryInterface(IID_IUnknown, (void **)ppunk);
  5236. if (sc)
  5237. return (sc.ToHr());
  5238. return (sc.ToHr());
  5239. }
  5240. //+-------------------------------------------------------------------
  5241. //
  5242. // Member: CAMCView::OnGetIconInfoForSelectedNode
  5243. //
  5244. // Synopsis: Icon control sends this message to get the small icon
  5245. // for currently the selected node.
  5246. //
  5247. // Arguments: [wParam] - Out param, ptr to HICON handle.
  5248. // [lParam] - Unused
  5249. //
  5250. // Returns: LRESULT
  5251. //
  5252. //--------------------------------------------------------------------
  5253. LRESULT CAMCView::OnGetIconInfoForSelectedNode(WPARAM wParam, LPARAM lParam)
  5254. {
  5255. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5256. DECLARE_SC(sc, _T("CAMCView::OnGetIconInfoForSelectedNode"));
  5257. HICON *phIcon = (HICON*)wParam;
  5258. sc = ScCheckPointers(phIcon);
  5259. if (sc)
  5260. return sc.ToHr();
  5261. *phIcon = NULL;
  5262. sc = ScCheckPointers(m_pTreeCtrl, m_spNodeCallback, E_UNEXPECTED);
  5263. if (sc)
  5264. return sc.ToHr();
  5265. sc = m_pTreeCtrl->ScGetTreeItemIconInfo(GetSelectedNode(), phIcon);
  5266. return sc.ToHr();
  5267. }
  5268. HRESULT CAMCView::NotifyListPad (BOOL b)
  5269. {
  5270. if (b == TRUE) // attaching: save current node
  5271. m_ListPadNode = GetSelectedNode();
  5272. else if (m_ListPadNode == NULL) // detaching, but no hnode
  5273. return E_UNEXPECTED;
  5274. // send notify to snapin
  5275. INodeCallback* pNC = GetNodeCallback();
  5276. HRESULT hr = pNC->Notify (m_ListPadNode, NCLBK_LISTPAD, (long)b, (long)0);
  5277. if (b == FALSE) // if detaching, ensure that we do this only once
  5278. m_ListPadNode = NULL;
  5279. return hr;
  5280. }
  5281. /*+-------------------------------------------------------------------------*
  5282. *
  5283. * CAMCView::ScOnConnectToTPLV
  5284. *
  5285. * PURPOSE: Connects the listpad to the HTML frame
  5286. *
  5287. * PARAMETERS:
  5288. * WPARAM wParam : parent window
  5289. * LPARAM lParam : [OUT]: pointer to window to be created and filled out
  5290. *
  5291. * RETURNS:
  5292. * SC
  5293. *
  5294. *+-------------------------------------------------------------------------*/
  5295. SC
  5296. CAMCView::ScOnConnectToTPLV(WPARAM wParam, LPARAM lParam)
  5297. {
  5298. DECLARE_SC(sc, _T("CAMCView::ScOnConnectToTPLV"));
  5299. HWND hwnd = (HWND )wParam;
  5300. if(!IsWindow (hwnd))
  5301. return (sc = S_FALSE);
  5302. if (lParam == NULL) // detaching
  5303. {
  5304. SC sc = m_pListCtrl->ScAttachToListPad (hwnd, NULL);
  5305. if(sc)
  5306. return sc;
  5307. }
  5308. else
  5309. { // attaching
  5310. sc = ScCreateTaskpadHost();
  5311. if(sc)
  5312. return sc;
  5313. HWND* phwnd = (HWND*)lParam;
  5314. if (IsBadWritePtr (phwnd, sizeof(HWND *)))
  5315. return (sc = E_UNEXPECTED);
  5316. // Attach TaskPad's ListView to the NodeMgr
  5317. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  5318. if(sc)
  5319. return sc;
  5320. sc = m_pTreeCtrl->m_spNodeManager->SetTaskPadList(m_pListCtrl);
  5321. if(sc)
  5322. return sc;
  5323. // Attach TaskPad's ListView to the curr selected node
  5324. INodeCallback* pNC = GetNodeCallback();
  5325. sc = ScCheckPointers(pNC, E_UNEXPECTED);
  5326. if(sc)
  5327. return sc;
  5328. HNODE hNodeSel = GetSelectedNode();
  5329. sc = pNC->SetTaskPadList(hNodeSel, m_pListCtrl);
  5330. if(sc) // this test was commented out earlier. Uncommented it so we can figure out why.
  5331. return sc;
  5332. //
  5333. // Attach the listctrl to the list pad.
  5334. //
  5335. // First set the list view options.
  5336. SetListViewOptions(GetListOptions());
  5337. sc = m_pListCtrl->ScAttachToListPad (hwnd, phwnd);
  5338. if(sc)
  5339. return sc;
  5340. }
  5341. RecalcLayout();
  5342. return sc;
  5343. }
  5344. SC CAMCView::ScShowWebContextMenu ()
  5345. {
  5346. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5347. PostMessage (m_nShowWebContextMenuMsg);
  5348. return (S_OK);
  5349. }
  5350. LRESULT CAMCView::OnShowWebContextMenu (WPARAM /*wParam*/, LPARAM /*lParam*/)
  5351. {
  5352. INodeCallback* pNC = GetNodeCallback();
  5353. ASSERT(pNC != NULL);
  5354. if (pNC)
  5355. pNC->Notify (GetSelectedNode(), NCLBK_WEBCONTEXTMENU, 0, 0);
  5356. return (0);
  5357. }
  5358. SC CAMCView::ScSetDescriptionBarText (LPCTSTR pszDescriptionText)
  5359. {
  5360. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5361. GetRightDescCtrl().SetSnapinText (pszDescriptionText);
  5362. return (S_OK);
  5363. }
  5364. HWND CAMCView::CreateFavoriteObserver (HWND hwndParent, int nID)
  5365. {
  5366. DECLARE_SC (sc, _T("CAMCView::CreateFavoriteObserver"));
  5367. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5368. CFavTreeCtrl* pFavCtrl = CFavTreeCtrl::CreateInstance();
  5369. if (pFavCtrl != NULL)
  5370. {
  5371. pFavCtrl->Create (NULL, TEXT(""), WS_CHILD|WS_TABSTOP|WS_VISIBLE,
  5372. g_rectEmpty, CWnd::FromHandle(hwndParent), nID);
  5373. pFavCtrl->ModifyStyleEx (0, WS_EX_CLIENTEDGE, 0);
  5374. CAMCDoc* pDoc = GetDocument();
  5375. ASSERT(pDoc != NULL && pDoc->GetFavorites() != NULL);
  5376. sc = pFavCtrl->ScInitialize(pDoc->GetFavorites(), TOBSRV_HIDEROOT);
  5377. if (sc)
  5378. {
  5379. pFavCtrl->DestroyWindow(); // CFavTreeCtrl::PostNcDestroy will "delete this"
  5380. pFavCtrl = NULL;
  5381. }
  5382. }
  5383. return (pFavCtrl->GetSafeHwnd());
  5384. }
  5385. int CAMCView::GetListSize ()
  5386. {
  5387. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5388. return (m_pListCtrl->GetItemCount() * m_pListCtrl->GetColCount());
  5389. }
  5390. long CAMCView::GetListViewStyle()
  5391. {
  5392. DECLARE_SC(sc, _T("CAMCView::GetListViewStyle"));
  5393. sc = ScCheckPointers(m_pTreeCtrl, m_pTreeCtrl->m_spResultData, E_UNEXPECTED);
  5394. if (sc)
  5395. return 0;
  5396. if (HasList())
  5397. return 0;
  5398. long style = 0;
  5399. // First findout if the result view is properly
  5400. // set in the nodemgr by asking IFramePrivate.
  5401. IFramePrivatePtr spFrame = m_pTreeCtrl->m_spResultData;
  5402. sc = ScCheckPointers(spFrame, E_UNEXPECTED);
  5403. if (sc)
  5404. return 0;
  5405. BOOL bIsResultViewSet = FALSE;
  5406. sc = spFrame->IsResultViewSet(&bIsResultViewSet);
  5407. // The result view is set, clean it up.
  5408. if (bIsResultViewSet)
  5409. {
  5410. sc = m_pTreeCtrl->m_spResultData->GetListStyle(&style);
  5411. if (sc)
  5412. return 0;
  5413. }
  5414. return style;
  5415. }
  5416. void CAMCView::OnListContextMenu(CPoint& point)
  5417. {
  5418. DECLARE_SC(sc, TEXT("CAMCView::OnListContextMenu"));
  5419. ASSERT(m_pTreeCtrl != NULL);
  5420. ASSERT(m_pTreeCtrl->m_spResultData != NULL);
  5421. // Determine which item is affected
  5422. UINT fHitTestFlags = 0;
  5423. HRESULTITEM hHitTestItem = 0;
  5424. COMPONENTID componentID = 0;
  5425. int iIndex = -1;
  5426. do // not a loop
  5427. {
  5428. if (!HasList())
  5429. break;
  5430. int cSel = m_pListCtrl->GetSelectedCount();
  5431. ASSERT(cSel >= 0);
  5432. if (cSel == 0)
  5433. {
  5434. OnContextMenuForListItem(INDEX_BACKGROUND, NULL, point);
  5435. return;
  5436. }
  5437. else if (cSel > 1)
  5438. {
  5439. if (IsKeyPressed(VK_SHIFT) || IsKeyPressed(VK_CONTROL))
  5440. {
  5441. HNODE hNodeSel = GetSelectedNode();
  5442. ASSERT(hNodeSel != 0);
  5443. INodeCallback* pNC = GetNodeCallback();
  5444. ASSERT(pNC != NULL);
  5445. if (pNC != NULL)
  5446. {
  5447. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, true, 0);
  5448. if (sc)
  5449. sc.TraceAndClear(); // ignore & continue;
  5450. m_bLastSelWasMultiSel = true;
  5451. }
  5452. }
  5453. iIndex = INDEX_MULTISELECTION; // => MultiSelect
  5454. break;
  5455. }
  5456. else
  5457. {
  5458. LPARAM lvData = LVDATA_ERROR;
  5459. iIndex = _GetLVSelectedItemData(&lvData);
  5460. ASSERT(iIndex != -1);
  5461. ASSERT(lvData != LVDATA_ERROR);
  5462. if (IsVirtualList())
  5463. {
  5464. // for virtual list pass the item index rather than the lparam
  5465. OnContextMenuForListItem(iIndex, iIndex, point);
  5466. return;
  5467. }
  5468. else
  5469. {
  5470. CResultItem* pri = CResultItem::FromHandle (lvData);
  5471. if (pri != NULL)
  5472. {
  5473. if (pri->IsScopeItem())
  5474. OnContextMenuForTreeItem(iIndex, pri->GetScopeNode(), point, CCT_SCOPE);
  5475. else
  5476. OnContextMenuForListItem(iIndex, lvData, point);
  5477. }
  5478. return;
  5479. }
  5480. }
  5481. } while (0);
  5482. OnContextMenuForListItem(iIndex, hHitTestItem, point);
  5483. }
  5484. void CAMCView::OnContextMenuForListItem(int iIndex, HRESULTITEM hHitTestItem,
  5485. CPoint& point, MMC_CONTEXT_MENU_TYPES eMenuType,
  5486. LPCRECT prcExclude, bool bAllowDefaultItem)
  5487. {
  5488. CContextMenuInfo contextInfo;
  5489. contextInfo.m_displayPoint.x = point.x;
  5490. contextInfo.m_displayPoint.y = point.y;
  5491. contextInfo.m_eContextMenuType = eMenuType;
  5492. contextInfo.m_eDataObjectType = CCT_RESULT;
  5493. contextInfo.m_bBackground = (iIndex == INDEX_BACKGROUND);
  5494. contextInfo.m_bMultiSelect = (iIndex == INDEX_MULTISELECTION);
  5495. contextInfo.m_bAllowDefaultItem = bAllowDefaultItem;
  5496. if (iIndex >= 0)
  5497. contextInfo.m_resultItemParam = IsVirtualList() ? iIndex : hHitTestItem;
  5498. else if (contextInfo.m_bMultiSelect)
  5499. contextInfo.m_resultItemParam = LVDATA_MULTISELECT;
  5500. contextInfo.m_bScopeAllowed = IsScopePaneAllowed();
  5501. contextInfo.m_hWnd = m_hWnd;
  5502. contextInfo.m_pConsoleView = this;
  5503. contextInfo.m_hSelectedScopeNode = GetSelectedNode();
  5504. contextInfo.m_iListItemIndex = iIndex;
  5505. if (HasListOrListPad())
  5506. contextInfo.m_spListView = m_pListCtrl;
  5507. if ((INDEX_OCXPANE == iIndex) && HasOCX())
  5508. {
  5509. contextInfo.m_resultItemParam = LVDATA_CUSTOMOCX;
  5510. }
  5511. else if ((INDEX_WEBPANE == iIndex) && HasWebBrowser())
  5512. {
  5513. contextInfo.m_resultItemParam = LVDATA_CUSTOMWEB;
  5514. }
  5515. /*
  5516. * if given, initialize the rectangle not to obscure
  5517. */
  5518. if (prcExclude != NULL)
  5519. contextInfo.m_rectExclude = *prcExclude;
  5520. HNODE hNode = GetSelectedNode();
  5521. ASSERT(hNode != NULL);
  5522. INodeCallback* pNodeCallback = GetNodeCallback();
  5523. ASSERT(pNodeCallback != NULL);
  5524. HRESULT hr = pNodeCallback->Notify(hNode, NCLBK_CONTEXTMENU, 0,
  5525. reinterpret_cast<LPARAM>(&contextInfo));
  5526. }
  5527. HTREEITEM CAMCView::FindChildNode(HTREEITEM hti, DWORD dwItemDataKey)
  5528. {
  5529. hti = m_pTreeCtrl->GetChildItem(hti);
  5530. while (hti && (dwItemDataKey != m_pTreeCtrl->GetItemData(hti)))
  5531. {
  5532. hti = m_pTreeCtrl->GetNextItem(hti, TVGN_NEXT);
  5533. }
  5534. return hti;
  5535. }
  5536. ///////////////////////////////////////////////////////////////////////////////
  5537. /// Context Menu Handlers for Result View Item and Background
  5538. void CAMCView::ArrangeIcon(long style)
  5539. {
  5540. #ifdef OLD_STUFF
  5541. ASSERT(m_pTreeCtrl && m_pTreeCtrl->m_pNodeInstCurr);
  5542. if (!m_pTreeCtrl || !m_pTreeCtrl->m_pNodeInstCurr)
  5543. return;
  5544. IFrame* const pFrame = m_pTreeCtrl->m_pNodeInstCurr->GetIFrame();
  5545. ASSERT(pFrame);
  5546. if (!pFrame)
  5547. return;
  5548. IResultDataPrivatePtr pResult = pFrame;
  5549. ASSERT(static_cast<bool>(pResult));
  5550. if (pResult == NULL)
  5551. return ;
  5552. HRESULT hr = pResult->Arrange(style);
  5553. ASSERT(SUCCEEDED(style));
  5554. #endif // OLD_STUFF
  5555. }
  5556. ///////////////////////////////////////////////////////////////////////////////
  5557. /// Menu handlers
  5558. CAMCView::ViewPane CAMCView::GetFocusedPane ()
  5559. {
  5560. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5561. ASSERT_VALID (this);
  5562. CView* pActiveView = GetParentFrame()->GetActiveView();
  5563. for (ViewPane ePane = ePane_First; ePane <= ePane_Last; ePane = (ViewPane)(ePane+1))
  5564. {
  5565. if (GetPaneView (ePane) == pActiveView)
  5566. return (ePane);
  5567. }
  5568. return (ePane_None);
  5569. }
  5570. /*+-------------------------------------------------------------------------*
  5571. * CDeferredResultPaneActivation
  5572. *
  5573. *
  5574. * PURPOSE: If the result pane has the focus before and after the node was
  5575. * selected, then the last event snapin receives is scope selected which
  5576. * is incorrect. So we first set scope pane as active view but do not
  5577. * send notifications. Then we set result pane as active view which
  5578. * sends scope de-select and result pane select.
  5579. * But when we try to set result pane as active view, the listview may
  5580. * not be visible yet (if there is view extension, the behavior hides
  5581. * and then shows the listview).
  5582. * So we need to wait till listview is setup. We cannot use PostMessage
  5583. * as the resizing of listview happens using PostMessage which is sent
  5584. * later (race condition). Therefore we use the idle timer as shown below
  5585. * so that activation will occur after resizing occurs.
  5586. *
  5587. *+-------------------------------------------------------------------------*/
  5588. class CDeferredResultPaneActivation : public CIdleTask
  5589. {
  5590. public:
  5591. CDeferredResultPaneActivation(HWND hWndAMCView) :
  5592. m_atomTask (AddAtom (_T("CDeferredResultPaneActivation"))),
  5593. m_hWndAMCView(hWndAMCView)
  5594. {
  5595. }
  5596. ~CDeferredResultPaneActivation() {}
  5597. // IIdleTask methods
  5598. SC ScDoWork()
  5599. {
  5600. DECLARE_SC (sc, TEXT("CDeferredResultPaneActivation::ScDoWork"));
  5601. sc = ScCheckPointers((void*)m_hWndAMCView, E_UNEXPECTED);
  5602. if (sc)
  5603. return (sc);
  5604. CWnd *pWnd = CWnd::FromHandle(m_hWndAMCView);
  5605. sc = ScCheckPointers(pWnd, E_UNEXPECTED);
  5606. if (sc)
  5607. return sc;
  5608. CAMCView *pAMCView = dynamic_cast<CAMCView*>(pWnd);
  5609. // Since this method is called by IdleQueue, the target
  5610. // CAMCView may have gone by now, if it does not exist
  5611. // it is not an error (see bug 175737 related to SQL).
  5612. if (! pAMCView)
  5613. return sc;
  5614. sc = pAMCView->ScSetFocusToResultPane();
  5615. if (sc)
  5616. return sc;
  5617. return sc;
  5618. }
  5619. SC ScGetTaskID(ATOM* pID)
  5620. {
  5621. DECLARE_SC (sc, TEXT("CDeferredResultPaneActivation::ScGetTaskID"));
  5622. sc = ScCheckPointers(pID);
  5623. if(sc)
  5624. return sc;
  5625. *pID = m_atomTask;
  5626. return sc;
  5627. }
  5628. SC ScMerge(CIdleTask* pitMergeFrom) {return S_FALSE /*do not merge*/;}
  5629. private:
  5630. const ATOM m_atomTask;
  5631. HWND m_hWndAMCView;
  5632. };
  5633. /*+-------------------------------------------------------------------------*
  5634. * CAMCView::ScDeferSettingFocusToResultPane
  5635. *
  5636. * Synopsis: If the result pane has the focus before and after the node was
  5637. * selected, then the last event snapin receives is scope selected which
  5638. * is incorrect. So we first set scope pane as active view but do not
  5639. * send notifications. Then we set result pane as active view which
  5640. * sends scope de-select and result pane select.
  5641. * But when we try to set result pane as active view, the listview may
  5642. * not be visible yet (if there is view extension, the behavior hides
  5643. * and then shows the listview).
  5644. * So we need to wait till listview is setup. We cannot use PostMessage
  5645. * as the resizing of listview happens using PostMessage which is sent
  5646. * later (race condition). Therefore we use the idle timer as shown below
  5647. * so that activation will occur after resizing occurs.
  5648. *
  5649. * Returns: SC
  5650. *
  5651. *--------------------------------------------------------------------------*/
  5652. SC CAMCView::ScDeferSettingFocusToResultPane ()
  5653. {
  5654. AFX_MANAGE_STATE (AfxGetAppModuleState()); // not sure if we need this, but doesn't hurt to have it in here.
  5655. DECLARE_SC (sc, TEXT("CAMCView::ScDeferSettingFocusToResultPane"));
  5656. CIdleTaskQueue* pIdleTaskQueue = AMCGetIdleTaskQueue();
  5657. sc = ScCheckPointers(pIdleTaskQueue, E_UNEXPECTED);
  5658. if(sc)
  5659. return sc;
  5660. /*
  5661. * create the deferred page break task
  5662. */
  5663. CAutoPtr<CDeferredResultPaneActivation> spDeferredResultPaneActivation(new CDeferredResultPaneActivation (GetSafeHwnd()));
  5664. sc = ScCheckPointers(spDeferredResultPaneActivation, E_OUTOFMEMORY);
  5665. if(sc)
  5666. return sc;
  5667. /*
  5668. * put the task in the queue, which will take ownership of it
  5669. * Activation should happen at lower priority than layout.
  5670. */
  5671. sc = pIdleTaskQueue->ScPushTask (spDeferredResultPaneActivation, ePriority_Low);
  5672. if (sc)
  5673. return sc;
  5674. /*
  5675. * if we get here, the idle task queue owns the idle task, so
  5676. * we can detach it from our smart pointer
  5677. */
  5678. spDeferredResultPaneActivation.Detach();
  5679. /*
  5680. * jiggle the message pump so that it wakes up and checks idle tasks
  5681. */
  5682. PostMessage (WM_NULL);
  5683. return (S_OK);
  5684. }
  5685. //+-------------------------------------------------------------------
  5686. //
  5687. // Member: ScSetFocusToResultPane
  5688. //
  5689. // Synopsis: Set focus to result pane (list or ocx or web). If result
  5690. // is hidden then set to folder tab else set to tasks pane.
  5691. //
  5692. // Arguments:
  5693. //
  5694. // Returns: SC
  5695. //
  5696. //--------------------------------------------------------------------
  5697. SC CAMCView::ScSetFocusToResultPane ()
  5698. {
  5699. DECLARE_SC(sc, TEXT("CAMCView::ScSetFocusToResultPane"));
  5700. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5701. if (GetFocusedPane() == ePane_Results)
  5702. return (sc);
  5703. // Make active
  5704. // 1. ListView/OCX/Web if it exists else
  5705. // 2. Folder tab if it exists.
  5706. // 3. Tasks in console taskpad.
  5707. CView* rgActivationOrderEntry[] =
  5708. {
  5709. GetPaneView(ePane_Results), // results
  5710. m_pResultFolderTabView, // result tab control
  5711. m_pViewExtensionCtrl, // view extension web page
  5712. };
  5713. const int INDEX_RESULTS_PANE = 0;
  5714. ASSERT (rgActivationOrderEntry[INDEX_RESULTS_PANE] == GetPaneView(ePane_Results));
  5715. int cEntries = (sizeof(rgActivationOrderEntry) / sizeof(rgActivationOrderEntry[0]));
  5716. // get the currently active entry.
  5717. for(int i = 0; i< cEntries; i++)
  5718. {
  5719. CView *pView = rgActivationOrderEntry[i];
  5720. sc = ScCheckPointers(pView, E_UNEXPECTED);
  5721. if (sc)
  5722. continue;
  5723. if (IsWindow (pView->GetSafeHwnd()) &&
  5724. pView->IsWindowVisible() &&
  5725. pView->IsWindowEnabled())
  5726. {
  5727. GetParentFrame()->SetActiveView (pView);
  5728. return (sc);
  5729. }
  5730. }
  5731. return (sc);
  5732. }
  5733. //+-------------------------------------------------------------------
  5734. //
  5735. // Member: ScSetFocusToPane
  5736. //
  5737. // Synopsis: Call this member to set focus to any pane.
  5738. //
  5739. // Arguments:
  5740. //
  5741. // Returns:
  5742. //
  5743. //--------------------------------------------------------------------
  5744. SC CAMCView::ScSetFocusToPane (ViewPane ePane)
  5745. {
  5746. DECLARE_SC(sc, TEXT("CAMCView::ScSetFocusToPane"));
  5747. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5748. if (!IsValidPane (ePane))
  5749. {
  5750. ASSERT (false && "CAMCView::ScSetFocusToPane: Invalid pane specifier");
  5751. return (sc = E_FAIL);
  5752. }
  5753. if (GetFocusedPane() == ePane)
  5754. return (sc);
  5755. if (ePane == ePane_Results)
  5756. return (sc = ScSetFocusToResultPane());
  5757. CView* pView = GetPaneView(ePane);
  5758. if (!IsWindow (pView->GetSafeHwnd()) ||
  5759. !pView->IsWindowVisible() ||
  5760. !pView->IsWindowEnabled())
  5761. {
  5762. return (sc = E_FAIL);
  5763. }
  5764. GetParentFrame()->SetActiveView (pView);
  5765. return (sc);
  5766. }
  5767. //+-------------------------------------------------------------------
  5768. //
  5769. // Member: CAMCView::ScGetFocusedItem
  5770. //
  5771. // Synopsis: Get the currently selected item's context.
  5772. //
  5773. // Arguments: [hNode] - [out] The owner of result pane.
  5774. // [lCookie] - [out] If result pane selected the LVDATA.
  5775. // [fScope] - [out] scope or result
  5776. //
  5777. // Returns: SC
  5778. //
  5779. //--------------------------------------------------------------------
  5780. SC CAMCView::ScGetFocusedItem (HNODE& hNode, LPARAM& lCookie, bool& fScope)
  5781. {
  5782. DECLARE_SC(sc, TEXT("CAMCView::ScGetFocusedItem"));
  5783. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5784. ASSERT_VALID (this);
  5785. lCookie = LVDATA_ERROR;
  5786. hNode = GetSelectedNode();
  5787. if (hNode == NULL)
  5788. return (sc = E_UNEXPECTED);
  5789. switch (m_eCurrentActivePane)
  5790. {
  5791. case eActivePaneScope:
  5792. fScope = true;
  5793. break;
  5794. case eActivePaneResult:
  5795. {
  5796. fScope = false;
  5797. // Calculate the LPARAM for result item.
  5798. if (HasOCX())
  5799. lCookie = LVDATA_CUSTOMOCX;
  5800. else if (HasWebBrowser())
  5801. lCookie = LVDATA_CUSTOMWEB;
  5802. else if (HasListOrListPad())
  5803. {
  5804. int cSel = m_pListCtrl->GetSelectedCount();
  5805. ASSERT(cSel >= 0);
  5806. if (cSel == 0)
  5807. lCookie = LVDATA_BACKGROUND;
  5808. else if (cSel == 1)
  5809. _GetLVSelectedItemData (&lCookie);
  5810. else if (cSel > 1)
  5811. lCookie = LVDATA_MULTISELECT;
  5812. }
  5813. else
  5814. {
  5815. return (sc = E_FAIL); // dont know who has the focus???
  5816. }
  5817. }
  5818. break;
  5819. case eActivePaneNone:
  5820. default:
  5821. sc = E_UNEXPECTED;
  5822. break;
  5823. }
  5824. return (sc);
  5825. }
  5826. //+-------------------------------------------------------------------
  5827. //
  5828. // Member: CAMCView::PrivateChangeListViewMode
  5829. //
  5830. // Synopsis: Private function to change view mode. Consider using
  5831. // ScChangeViewMode instead of this function.
  5832. //
  5833. // Arguments: [nMode] - view mode to be set.
  5834. //
  5835. //--------------------------------------------------------------------
  5836. void CAMCView::PrivateChangeListViewMode(int nMode)
  5837. {
  5838. DECLARE_SC(sc, TEXT("CAMCView::PrivateChangeListViewMode"));
  5839. if ((nMode < 0) || (nMode > MMCLV_VIEWSTYLE_FILTERED) )
  5840. {
  5841. sc = E_INVALIDARG;
  5842. return;
  5843. }
  5844. // Add a history entry which will be same as current
  5845. // one except for view mode change.
  5846. sc = ScCheckPointers(m_pHistoryList, m_pListCtrl, E_UNEXPECTED);
  5847. if (sc)
  5848. return;
  5849. // change the current history list entry's view mode
  5850. sc = m_pHistoryList->ScChangeViewMode(nMode);
  5851. if(sc)
  5852. return;
  5853. // set the list control's view mode
  5854. sc = m_pListCtrl->SetViewMode(nMode);
  5855. if (!sc)
  5856. {
  5857. m_nViewMode = nMode;
  5858. SetDirty();
  5859. SetDefaultListViewStyle(GetListViewStyle());
  5860. }
  5861. }
  5862. //+-------------------------------------------------------------------
  5863. //
  5864. // Member: CAMCView::OnProcessMultiSelectionChanges
  5865. //
  5866. // Synopsis: message handler for m_nProcessMultiSelectionChangesMsg
  5867. // messages that are posted.
  5868. //
  5869. // Handles multi-item de-selection for list view and then
  5870. // send selection for list view items.
  5871. //
  5872. // This method knows that selection states of multiple items
  5873. // are changed but not if they are selected or de-selected.
  5874. // The m_bLastSelWasMultiSel is used to determine if it is
  5875. // selection or de-selection.
  5876. //
  5877. // Arguments: none used.
  5878. //
  5879. // Returns: LRESULT
  5880. //
  5881. //--------------------------------------------------------------------
  5882. LRESULT CAMCView::OnProcessMultiSelectionChanges (WPARAM, LPARAM)
  5883. {
  5884. DECLARE_SC(sc, _T("CAMCView::OnProcessMultiSelectionChanges"));
  5885. // Selection change so appropriately enable std-toolbar buttons
  5886. // back, forward, export-list, up-one-level, show/hide-scope, help
  5887. sc = ScUpdateStandardbarMMCButtons();
  5888. if (sc)
  5889. return (0);
  5890. if (! m_bProcessMultiSelectionChanges)
  5891. return (0);
  5892. m_bProcessMultiSelectionChanges = false;
  5893. INodeCallback* pNC = GetNodeCallback();
  5894. HNODE hNodeSel = GetSelectedNode();
  5895. sc = ScCheckPointers((void*) hNodeSel, pNC, m_pListCtrl, E_UNEXPECTED);
  5896. if (sc)
  5897. return (0);
  5898. // If some thing was selected previously send a deselection
  5899. // message before sending a selection message (single item de-select
  5900. // is already handled in OnListItemChanged so just handle multi item
  5901. // deselect here).
  5902. if (m_bLastSelWasMultiSel)
  5903. {
  5904. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, false, 0);
  5905. if (sc)
  5906. sc.TraceAndClear(); // ignore & continue;
  5907. m_bLastSelWasMultiSel = false;
  5908. }
  5909. // Now send a selection message
  5910. UINT cSel = m_pListCtrl->GetSelectedCount ();
  5911. if (cSel == 1)
  5912. {
  5913. SELECTIONINFO selInfo;
  5914. ZeroMemory(&selInfo, sizeof(selInfo));
  5915. selInfo.m_bScope = FALSE;
  5916. int iItem = _GetLVSelectedItemData(&selInfo.m_lCookie);
  5917. ASSERT(iItem != -1);
  5918. sc = ScNotifySelect (pNC, hNodeSel, false /*fMultiSelect*/, true, &selInfo);
  5919. if (sc)
  5920. sc.TraceAndClear(); // ignore & continue;
  5921. }
  5922. else if (cSel > 1)
  5923. {
  5924. Dbg(DEB_USER1, _T(" 5. LVN_SELCHANGE <MS> <0, 1>\n"));
  5925. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, true, 0);
  5926. if (sc)
  5927. sc.TraceAndClear(); // ignore & continue;
  5928. m_bLastSelWasMultiSel = true;
  5929. }
  5930. return (0);
  5931. }
  5932. SC CAMCView::ScRenameListPadItem() // obsolete?
  5933. {
  5934. DECLARE_SC (sc, _T("CAMCView::ScRenameListPadItem"));
  5935. AFX_MANAGE_STATE (AfxGetAppModuleState());
  5936. ASSERT(m_pListCtrl != NULL);
  5937. ASSERT(m_pListCtrl->GetListViewPtr() != NULL);
  5938. int cSel = m_pListCtrl->GetSelectedCount();
  5939. if (cSel != 1)
  5940. return (sc = E_FAIL);
  5941. LPARAM lParam;
  5942. int iItem = _GetLVSelectedItemData(&lParam);
  5943. ASSERT(iItem >= 0);
  5944. if (iItem >= 0)
  5945. {
  5946. m_bRenameListPadItem = true;
  5947. m_pListCtrl->GetListViewPtr()->SetFocus();
  5948. m_pListCtrl->GetListViewPtr()->GetListCtrl().EditLabel(iItem);
  5949. m_bRenameListPadItem = false;
  5950. }
  5951. return (sc);
  5952. }
  5953. /*+-------------------------------------------------------------------------*
  5954. *
  5955. * CAMCView::ScOrganizeFavorites
  5956. *
  5957. * PURPOSE: Display the "organize favorites" dialog.
  5958. *
  5959. * RETURNS:
  5960. * SC
  5961. *
  5962. *+-------------------------------------------------------------------------*/
  5963. SC
  5964. CAMCView::ScOrganizeFavorites()
  5965. {
  5966. DECLARE_SC (sc, TEXT("CAMCView::ScOrganizeFavorites"));
  5967. CAMCDoc* pDoc = GetDocument();
  5968. sc = ScCheckPointers(pDoc, E_UNEXPECTED);
  5969. if(sc)
  5970. return sc;
  5971. CFavorites *pFavorites = pDoc->GetFavorites();
  5972. sc = ScCheckPointers(pFavorites);
  5973. if(sc)
  5974. return sc;
  5975. pFavorites->OrganizeFavorites(this);
  5976. return sc;
  5977. }
  5978. /*+-------------------------------------------------------------------------*
  5979. *
  5980. * CAMCView::ScLineUpIcons
  5981. *
  5982. * PURPOSE: line up the icons in the list
  5983. *
  5984. * RETURNS:
  5985. * SC
  5986. *
  5987. *+-------------------------------------------------------------------------*/
  5988. SC
  5989. CAMCView::ScLineUpIcons()
  5990. {
  5991. DECLARE_SC (sc, TEXT("CAMCView::ScLineUpIcons"));
  5992. ArrangeIcon(LVA_SNAPTOGRID);
  5993. return sc;
  5994. }
  5995. /*+-------------------------------------------------------------------------*
  5996. *
  5997. * CAMCView::ScAutoArrangeIcons
  5998. *
  5999. * PURPOSE: auto arrange the icons in the list
  6000. *
  6001. * RETURNS:
  6002. * SC
  6003. *
  6004. *+-------------------------------------------------------------------------*/
  6005. SC
  6006. CAMCView::ScAutoArrangeIcons()
  6007. {
  6008. DECLARE_SC(sc, TEXT("CAMCView::ScAutoArrangeIcons"));
  6009. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  6010. if(sc)
  6011. return sc;
  6012. m_pListCtrl->SetListStyle(m_pListCtrl->GetListStyle() ^ LVS_AUTOARRANGE);
  6013. return sc;
  6014. }
  6015. /*+-------------------------------------------------------------------------*
  6016. *
  6017. * CAMCView::ScOnRefresh
  6018. *
  6019. * PURPOSE: Refreshes the view.
  6020. *
  6021. * RETURNS:
  6022. * SC
  6023. *
  6024. *+-------------------------------------------------------------------------*/
  6025. SC
  6026. CAMCView::ScOnRefresh(HNODE hNode, bool bScope, LPARAM lResultItemParam)
  6027. {
  6028. DECLARE_SC(sc, TEXT("CAMCView::ScOnRefresh"));
  6029. sc = ScCheckPointers((void*)hNode);
  6030. if (sc)
  6031. return sc;
  6032. HWND hwnd = ::GetFocus();
  6033. sc = ScProcessConsoleVerb(hNode, bScope, lResultItemParam, evRefresh);
  6034. ::SetFocus(hwnd);
  6035. if (sc)
  6036. return sc;
  6037. return sc;
  6038. }
  6039. /***************************************************************************\
  6040. *
  6041. * CLASS: CDeferredRenameListItem
  6042. *
  6043. * PURPOSE: This class encapsulates means to put a list control in the rename mode
  6044. * asynchronously. This is needed to assure all mesages are processed before
  6045. * and no-one will steel the focus ending unexpectidly the edit mode.
  6046. *
  6047. * USAGE:
  6048. * use CDeferredRenameListItem::ScDoRenameAsIdleTask() to invoke the operation
  6049. * asyncronously
  6050. *
  6051. \***************************************************************************/
  6052. class CDeferredRenameListItem : public CIdleTask
  6053. {
  6054. // constructor - used internally only
  6055. CDeferredRenameListItem( HWND hwndListCtrl, int iItemIndex ) :
  6056. m_atomTask (AddAtom (_T("CDeferredRenameListItem"))),
  6057. m_hwndListCtrl(hwndListCtrl), m_iItemIndex(iItemIndex)
  6058. {
  6059. }
  6060. protected:
  6061. // IIdleTask methods
  6062. SC ScDoWork()
  6063. {
  6064. DECLARE_SC (sc, TEXT("CDeferredRenameListItem::ScDoWork"));
  6065. // get the ListCtrl pointer
  6066. CListCtrl *pListCtrl = (CListCtrl *)CWnd::FromHandlePermanent(m_hwndListCtrl);
  6067. sc = ScCheckPointers( pListCtrl );
  6068. if (sc)
  6069. return sc;
  6070. // do what you are asked for - put LV in the rename mode
  6071. pListCtrl->SetFocus(); // set the focus first. Don't need to do a SetActiveView here, I believe (vivekj)
  6072. pListCtrl->EditLabel( m_iItemIndex );
  6073. return sc;
  6074. }
  6075. SC ScGetTaskID(ATOM* pID)
  6076. {
  6077. DECLARE_SC (sc, TEXT("CDeferredPageBreak::ScGetTaskID"));
  6078. sc = ScCheckPointers(pID);
  6079. if(sc)
  6080. return sc;
  6081. *pID = m_atomTask;
  6082. return sc;
  6083. }
  6084. SC ScMerge(CIdleTask* pitMergeFrom) { return S_FALSE /*do not merge*/; }
  6085. public:
  6086. // this method is called to invoke rename asyncronously.
  6087. // it constructs the idle task and puts it into the queue
  6088. static SC ScDoRenameAsIdleTask( HWND hwndListCtrl, int iItemIndex )
  6089. {
  6090. DECLARE_SC(sc, TEXT("CDeferredPageBreak::ScDoRenameAsIdleTask"));
  6091. CIdleTaskQueue* pIdleTaskQueue = AMCGetIdleTaskQueue();
  6092. sc = ScCheckPointers(pIdleTaskQueue, E_UNEXPECTED);
  6093. if(sc)
  6094. return sc;
  6095. // create the deferred task
  6096. CAutoPtr<CDeferredRenameListItem> spTask(new CDeferredRenameListItem (hwndListCtrl, iItemIndex));
  6097. sc = ScCheckPointers( spTask, E_OUTOFMEMORY);
  6098. if(sc)
  6099. return sc;
  6100. // put the task in the queue, which will take ownership of it
  6101. sc = pIdleTaskQueue->ScPushTask (spTask, ePriority_Normal);
  6102. if (sc)
  6103. return sc;
  6104. // ownership tranfered to the queue, get rid of control over the pointer
  6105. spTask.Detach();
  6106. return sc;
  6107. }
  6108. private:
  6109. const ATOM m_atomTask;
  6110. HWND m_hwndListCtrl;
  6111. int m_iItemIndex;
  6112. };
  6113. /*+-------------------------------------------------------------------------*
  6114. *
  6115. * CAMCView::ScOnRename
  6116. *
  6117. * PURPOSE: Allows the user to renames the scope or result item specified by pContextInfo
  6118. *
  6119. * PARAMETERS:
  6120. * CContextMenuInfo * pContextInfo :
  6121. *
  6122. * RETURNS:
  6123. * SC
  6124. *
  6125. *+-------------------------------------------------------------------------*/
  6126. SC
  6127. CAMCView::ScOnRename(CContextMenuInfo *pContextInfo)
  6128. {
  6129. DECLARE_SC(sc, TEXT("CAMCView::ScOnRename"));
  6130. sc = ScCheckPointers(pContextInfo, m_pTreeCtrl, m_pListCtrl);
  6131. if(sc)
  6132. return sc;
  6133. if (pContextInfo->m_htiRClicked != NULL)
  6134. {
  6135. m_pTreeCtrl->EditLabel(pContextInfo->m_htiRClicked);
  6136. }
  6137. else
  6138. {
  6139. ASSERT(pContextInfo->m_iListItemIndex >= 0);
  6140. sc = ScCheckPointers(m_pListCtrl->GetListCtrl());
  6141. if(sc)
  6142. return sc;
  6143. // Do this on idle - or else we'll suffer from someone steeling focus
  6144. // Syncronous operation fails in console task case.
  6145. sc = CDeferredRenameListItem::ScDoRenameAsIdleTask( m_pListCtrl->GetListCtrl().m_hWnd, pContextInfo->m_iListItemIndex );
  6146. if(sc)
  6147. return sc;
  6148. }
  6149. return sc;
  6150. }
  6151. /*+-------------------------------------------------------------------------*
  6152. *
  6153. * CAMCView::ScRenameScopeNode
  6154. *
  6155. * PURPOSE: put the specified scope node into rename mode.
  6156. *
  6157. * PARAMETERS:
  6158. * HMTNODE hMTNode : The scope node
  6159. *
  6160. * RETURNS:
  6161. * SC
  6162. *
  6163. *+-------------------------------------------------------------------------*/
  6164. SC
  6165. CAMCView::ScRenameScopeNode(HMTNODE hMTNode)
  6166. {
  6167. DECLARE_SC(sc, TEXT("CAMCView::ScRenameScopeNode"));
  6168. sc = ScCheckPointers(m_pTreeCtrl, E_FAIL);
  6169. if(sc)
  6170. return sc;
  6171. sc = m_pTreeCtrl->ScRenameScopeNode(hMTNode);
  6172. return sc;
  6173. }
  6174. /*+-------------------------------------------------------------------------*
  6175. *
  6176. * CAMCView::ScGetStatusBar
  6177. *
  6178. * PURPOSE: Returns the status bar
  6179. *
  6180. * PARAMETERS:
  6181. * CConsoleStatusBar ** ppStatusBar :
  6182. *
  6183. * RETURNS:
  6184. * SC
  6185. *
  6186. *+-------------------------------------------------------------------------*/
  6187. SC
  6188. CAMCView::ScGetStatusBar(CConsoleStatusBar **ppStatusBar)
  6189. {
  6190. DECLARE_SC(sc, TEXT("CAMCView::ScGetStatusBar"));
  6191. sc = ScCheckPointers(ppStatusBar);
  6192. if(sc)
  6193. return sc;
  6194. *ppStatusBar = m_ViewData.GetStatusBar();
  6195. return sc;
  6196. }
  6197. /*+-------------------------------------------------------------------------*
  6198. *
  6199. * CAMCView::ScGetProperty
  6200. *
  6201. * PURPOSE: Gets the property for a result item
  6202. *
  6203. * PARAMETERS:
  6204. * int m_iIndex : The index of the item in the list.
  6205. * BSTR bstrPropertyName :
  6206. * PBSTR pbstrPropertyValue :
  6207. *
  6208. * RETURNS:
  6209. * SC
  6210. *
  6211. *+-------------------------------------------------------------------------*/
  6212. SC
  6213. CAMCView::ScGetProperty(int iIndex, BSTR bstrPropertyName, PBSTR pbstrPropertyValue)
  6214. {
  6215. DECLARE_SC(sc, TEXT("CAMCView::ScGetProperty"));
  6216. sc = ScCheckPointers(GetNodeCallback(), m_pListCtrl, E_UNEXPECTED);
  6217. if(sc)
  6218. return sc;
  6219. LPARAM resultItemParam = iIndex; // the virtual list case
  6220. bool bScopeItem = false; // the virtual list case
  6221. if(!IsVirtualList())
  6222. {
  6223. CResultItem *pri = NULL;
  6224. sc = m_pListCtrl->GetLParam(iIndex, pri);
  6225. if(sc)
  6226. return sc;
  6227. resultItemParam = CResultItem::ToHandle(pri);
  6228. sc = ScCheckPointers(pri);
  6229. if(sc)
  6230. return sc;
  6231. bScopeItem = pri->IsScopeItem();
  6232. }
  6233. sc = GetNodeCallback()->GetProperty(GetSelectedNode(), bScopeItem, resultItemParam, bstrPropertyName, pbstrPropertyValue);
  6234. return sc;
  6235. }
  6236. /*+-------------------------------------------------------------------------*
  6237. *
  6238. * CAMCView::ScGetNodetype
  6239. *
  6240. * PURPOSE: Returns the nodetype for a list item
  6241. *
  6242. * PARAMETERS:
  6243. * int iIndex :
  6244. * PBSTR Nodetype :
  6245. *
  6246. * RETURNS:
  6247. * SC
  6248. *
  6249. *+-------------------------------------------------------------------------*/
  6250. SC
  6251. CAMCView::ScGetNodetype(int iIndex, PBSTR Nodetype)
  6252. {
  6253. DECLARE_SC(sc, TEXT("CAMCView::ScGetProperty"));
  6254. sc = ScCheckPointers(GetNodeCallback(), m_pListCtrl, E_UNEXPECTED);
  6255. if(sc)
  6256. return sc;
  6257. LPARAM resultItemParam = iIndex; // the virtual list case
  6258. bool bScopeItem = false; // the virtual list case
  6259. if(!IsVirtualList())
  6260. {
  6261. CResultItem *pri = NULL;
  6262. sc = m_pListCtrl->GetLParam(iIndex, pri);
  6263. if(sc)
  6264. return sc;
  6265. resultItemParam = CResultItem::ToHandle(pri);
  6266. sc = ScCheckPointers(pri);
  6267. if(sc)
  6268. return sc;
  6269. bScopeItem = pri->IsScopeItem();
  6270. }
  6271. sc = GetNodeCallback()->GetNodetypeForListItem(GetSelectedNode(), bScopeItem, resultItemParam, Nodetype);
  6272. return sc;
  6273. }
  6274. /*+-------------------------------------------------------------------------*
  6275. * CAMCView::ScAddViewExtension
  6276. *
  6277. *
  6278. *--------------------------------------------------------------------------*/
  6279. SC CAMCView::ScAddViewExtension (const CViewExtensionData& ved)
  6280. {
  6281. DECLARE_SC (sc, _T("CAMCView::ScAddViewExtension"));
  6282. return (sc);
  6283. }
  6284. void
  6285. CAMCView::OnChangedResultTab(NMHDR *nmhdr, LRESULT *pRes)
  6286. {
  6287. DECLARE_SC(sc, TEXT("CAMCView::OnChangedResultTab"));
  6288. NMFOLDERTAB* nmtab = static_cast<NMFOLDERTAB*>(nmhdr);
  6289. int iTab = nmtab->iItem;
  6290. CFolderTab &tab = m_pResultFolderTabView->GetItem(iTab);
  6291. GUID guidTaskpad = tab.GetClsid();
  6292. // check if we're moving to the same taskpad.
  6293. GUID guidCurrentTaskpad;
  6294. GetTaskpadID(guidCurrentTaskpad);
  6295. if(guidTaskpad == guidCurrentTaskpad)
  6296. return;
  6297. // lookup view extension URL
  6298. CViewExtensionURLs::iterator itVE = m_ViewExtensionURLs.find(guidTaskpad);
  6299. LPCTSTR url = (itVE != m_ViewExtensionURLs.end()) ? itVE->second.c_str() : NULL;
  6300. // apply URL
  6301. sc = ScApplyViewExtension(url);
  6302. if (sc)
  6303. sc.TraceAndClear();
  6304. GetNodeCallback()->SetTaskpad(GetSelectedNode(), &guidTaskpad); // if not found, guidTaskpad is set to GUID_NULL.
  6305. // After setting the taskpad enable/disable save list button
  6306. CStandardToolbar* pStdToolbar = GetStdToolbar();
  6307. ASSERT(NULL != pStdToolbar);
  6308. if (NULL != pStdToolbar)
  6309. {
  6310. pStdToolbar->ScEnableExportList(GetListSize() > 0 /*Enable only if LV has items*/);
  6311. }
  6312. // the taskpad changed. Create a new entry in the history list.
  6313. sc = m_pHistoryList->ScModifyViewTab( guidTaskpad );
  6314. if(sc)
  6315. sc.TraceAndClear();
  6316. }
  6317. HRESULT
  6318. CAMCView::GetRootNodePath(
  6319. CBookmark* pbm)
  6320. {
  6321. HTREEITEM htiRoot = m_pTreeCtrl->GetRootItem();
  6322. return GetNodePath(htiRoot, htiRoot, pbm);
  6323. }
  6324. HRESULT
  6325. CAMCView::GetSelectedNodePath(
  6326. CBookmark* pbm)
  6327. {
  6328. return GetNodePath(m_pTreeCtrl->GetSelectedItem(),
  6329. m_pTreeCtrl->GetRootItem(),
  6330. pbm);
  6331. }
  6332. HRESULT
  6333. CAMCView::GetNodePath(
  6334. HTREEITEM hti,
  6335. HTREEITEM htiRoot,
  6336. CBookmark* pbm)
  6337. {
  6338. TRACE_METHOD(CAMCView, GetRootNodeID);
  6339. if (hti == NULL)
  6340. return E_FAIL;
  6341. if (htiRoot == NULL)
  6342. return E_FAIL;
  6343. ASSERT(hti != NULL);
  6344. ASSERT(htiRoot != NULL);
  6345. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(hti);
  6346. HNODE hRootNode = (HNODE)m_pTreeCtrl->GetItemData(htiRoot);
  6347. HRESULT hr = m_spNodeCallback->GetPath(hNode, hRootNode, (LPBYTE) pbm);
  6348. return hr;
  6349. }
  6350. inline HMTNODE CAMCView::GetHMTNode(HTREEITEM hti)
  6351. {
  6352. TRACE_METHOD(CAMCView, GetHMTNode);
  6353. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(hti);
  6354. HMTNODE hMTNodeTemp;
  6355. HRESULT hr = m_spNodeCallback->GetMTNode(hNode, &hMTNodeTemp);
  6356. CHECK_HRESULT(hr);
  6357. return hMTNodeTemp;
  6358. }
  6359. HTREEITEM CAMCView::FindHTreeItem(HMTNODE hMTNode, HTREEITEM hti)
  6360. {
  6361. TRACE_METHOD(CAMCView, FindHTreeItem);
  6362. while (hti)
  6363. {
  6364. if (hMTNode == GetHMTNode(hti))
  6365. break;
  6366. hti = m_pTreeCtrl->GetNextItem(hti, TVGN_NEXT);
  6367. }
  6368. return hti;
  6369. }
  6370. UINT CAMCView::ClipPath(CHMTNODEList* pNodeList, POSITION& rpos, HNODE hNode)
  6371. {
  6372. TRACE_METHOD(CAMCView, ClipPath);
  6373. UINT uiReturn = ITEM_IS_IN_VIEW;
  6374. CCoTaskMemPtr<HMTNODE> sphMTNode;
  6375. long lLength = 0;
  6376. HRESULT hr = m_spNodeCallback->GetMTNodePath(hNode, &sphMTNode, &lLength);
  6377. CHECK_HRESULT(hr);
  6378. if (FAILED(hr))
  6379. return hr;
  6380. ASSERT(lLength == 0 || sphMTNode != NULL);
  6381. for (long i=0; rpos != 0 && i < lLength; i++)
  6382. {
  6383. HMTNODE hMTNode = pNodeList->GetNext(rpos);
  6384. if (hMTNode != sphMTNode[i])
  6385. {
  6386. uiReturn = ITEM_NOT_IN_VIEW;
  6387. break;
  6388. }
  6389. }
  6390. if (uiReturn == ITEM_NOT_IN_VIEW)
  6391. return ITEM_NOT_IN_VIEW;
  6392. return (rpos == 0 && lLength >= i) ? ITEM_IS_PARENT_OF_ROOT : ITEM_IS_IN_VIEW;
  6393. }
  6394. //
  6395. // GetTreeItem returns TRUE if it can find the htreeitem of the item
  6396. // whose HMTNode is equal to the last element in pNodeList. It returns
  6397. // FALSE if the node does not appear in the view name space or if the
  6398. // the node has not yet been created.
  6399. //
  6400. // "pNodeList" is a list of HMTNODEs such that pNodeList[n] is the parent
  6401. // of pNodeList[n+1].
  6402. //
  6403. UINT CAMCView::GetTreeItem(CHMTNODEList* pNodeList, HTREEITEM* phItem)
  6404. {
  6405. TRACE_METHOD(CAMCView, GetTreeItem);
  6406. ASSERT(pNodeList->IsEmpty() == FALSE);
  6407. HTREEITEM hti = NULL;
  6408. HMTNODE hMTNodeTemp = 0;
  6409. hti = m_pTreeCtrl->GetRootItem();
  6410. if (hti == NULL)
  6411. return ITEM_NOT_IN_VIEW;
  6412. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(hti);
  6413. POSITION pos = pNodeList->GetHeadPosition();
  6414. UINT uiReturn = ClipPath(pNodeList, pos, hNode);
  6415. if (uiReturn != ITEM_IS_IN_VIEW)
  6416. return uiReturn;
  6417. HTREEITEM htiTemp = NULL;
  6418. while (pos && hti)
  6419. {
  6420. hMTNodeTemp = (HMTNODE)pNodeList->GetNext(pos);
  6421. hti = FindHTreeItem(hMTNodeTemp, hti);
  6422. ASSERT(hti == NULL || hMTNodeTemp == GetHMTNode(hti));
  6423. htiTemp = hti;
  6424. if (hti != NULL)
  6425. hti = m_pTreeCtrl->GetChildItem(hti);
  6426. }
  6427. if (pos == 0 && htiTemp != NULL)
  6428. {
  6429. // Found the node.
  6430. ASSERT(hMTNodeTemp == pNodeList->GetTail());
  6431. ASSERT(hMTNodeTemp == GetHMTNode(htiTemp));
  6432. *phItem = htiTemp;
  6433. return ITEM_IS_IN_VIEW;
  6434. }
  6435. else
  6436. {
  6437. // The node has not yet been created.
  6438. *phItem = NULL;
  6439. return ITEM_NOT_IN_VIEW;
  6440. }
  6441. return ITEM_IS_IN_VIEW;
  6442. }
  6443. #define HMTNODE_FIRST reinterpret_cast<HMTNODE>(TVI_FIRST)
  6444. #define HMTNODE_LAST reinterpret_cast<HMTNODE>(TVI_LAST)
  6445. void CAMCView::OnAdd(SViewUpdateInfo *pvui)
  6446. {
  6447. TRACE_METHOD(CAMCView, OnAdd);
  6448. ASSERT(pvui->path.IsEmpty() == FALSE);
  6449. HTREEITEM htiParent;
  6450. if (GetTreeItem(&pvui->path, &htiParent) != ITEM_IS_IN_VIEW || htiParent == NULL)
  6451. return;
  6452. bool bFirstChild = (m_pTreeCtrl->GetChildItem(htiParent) == NULL);
  6453. HNODE hNodeParent = (HNODE)m_pTreeCtrl->GetItemData(htiParent);
  6454. if (m_spNodeCallback->Notify(hNodeParent, NCLBK_EXPAND, 0, 0) == S_FALSE)
  6455. {
  6456. m_pTreeCtrl->SetCountOfChildren(htiParent, 1);
  6457. return; // Don't add if it is not expanded.
  6458. }
  6459. // If the hNode was already expanded add the item.
  6460. IScopeTree* const pScopeTree = GetScopeTree();
  6461. ASSERT(pScopeTree != NULL);
  6462. HNODE hNodeNew = 0;
  6463. HRESULT hr = pScopeTree->CreateNode(pvui->newNode,
  6464. reinterpret_cast<LONG_PTR>(GetViewData()),
  6465. FALSE, &hNodeNew);
  6466. CHECK_HRESULT(hr);
  6467. if (FAILED(hr))
  6468. return;
  6469. HTREEITEM hInsertAfter = TVI_LAST;
  6470. int iInsertIndex = -1;
  6471. if (pvui->insertAfter != NULL)
  6472. {
  6473. hInsertAfter = reinterpret_cast<HTREEITEM>(pvui->insertAfter);
  6474. if (pvui->insertAfter == HMTNODE_LAST)
  6475. {
  6476. }
  6477. else if (pvui->insertAfter == HMTNODE_FIRST)
  6478. {
  6479. iInsertIndex = 0;
  6480. }
  6481. else
  6482. {
  6483. HTREEITEM hti = m_pTreeCtrl->GetChildItem(htiParent);
  6484. ASSERT(hti != NULL);
  6485. iInsertIndex = 1;
  6486. while (hti != NULL)
  6487. {
  6488. if (GetHMTNode(hti) == pvui->insertAfter)
  6489. break;
  6490. hti = m_pTreeCtrl->GetNextSiblingItem(hti);
  6491. iInsertIndex++;
  6492. }
  6493. if (hti)
  6494. {
  6495. hInsertAfter = hti;
  6496. }
  6497. else
  6498. {
  6499. hInsertAfter = TVI_LAST;
  6500. iInsertIndex = -1;
  6501. }
  6502. }
  6503. }
  6504. if (m_pTreeCtrl->InsertNode(htiParent, hNodeNew, hInsertAfter) == NULL)
  6505. return;
  6506. // if parent of the inserted item currently owns a non-virtual result list,
  6507. // add the item to result list too. Don't add the item if a node select is in
  6508. // progress because the tree control will automatically add all scope items
  6509. // as part of the select procedure.
  6510. if (OwnsResultList(htiParent) && CanInsertScopeItemInResultPane() )
  6511. {
  6512. // Ensure the node is enumerated
  6513. m_pTreeCtrl->ExpandNode(htiParent);
  6514. // Add to result pane.
  6515. RESULTDATAITEM tRDI;
  6516. ::ZeroMemory(&tRDI, sizeof(tRDI));
  6517. tRDI.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  6518. tRDI.nCol = 0;
  6519. tRDI.str = MMC_TEXTCALLBACK;
  6520. tRDI.nIndex = iInsertIndex;
  6521. int nImage;
  6522. int nSelectedImage;
  6523. hr = m_spNodeCallback->GetImages(hNodeNew, &nImage, &nSelectedImage);
  6524. ASSERT(hr == S_OK || nImage == 0);
  6525. tRDI.nImage = nImage;
  6526. tRDI.lParam = CAMCTreeView::LParamFromNode (hNodeNew);
  6527. LPRESULTDATA pResultData = m_pTreeCtrl->GetResultData();
  6528. ASSERT(pResultData != NULL);
  6529. hr = pResultData->InsertItem(&tRDI);
  6530. CHECK_HRESULT(hr);
  6531. if (SUCCEEDED(hr))
  6532. hr = m_spNodeCallback->SetResultItem(hNodeNew, tRDI.itemID);
  6533. }
  6534. if ((m_pTreeCtrl->GetRootItem() == htiParent) ||
  6535. ((bFirstChild == true) &&
  6536. (m_spNodeCallback->Notify(hNodeParent, NCLBK_GETEXPANDEDVISUALLY, 0, 0) == S_OK)))
  6537. {
  6538. m_pTreeCtrl->Expand(htiParent, TVE_EXPAND);
  6539. }
  6540. }
  6541. void CAMCView::OnDeleteEmptyView()
  6542. {
  6543. if (m_pTreeCtrl->GetRootItem() == NULL)
  6544. {
  6545. ++m_nReleaseViews;
  6546. if (m_nReleaseViews == 3)
  6547. {
  6548. // Ensure that there is at least one *persistable* view
  6549. CAMCDoc* pDoc = dynamic_cast<CAMCDoc*>(GetDocument());
  6550. ASSERT(pDoc != NULL);
  6551. int cViews = pDoc->GetNumberOfPersistedViews();
  6552. ASSERT(cViews >= 1);
  6553. if ((cViews == 1) && IsPersisted())
  6554. {
  6555. CMainFrame* pMain = dynamic_cast<CMainFrame*>(AfxGetMainWnd());
  6556. ASSERT(pMain != NULL);
  6557. if ( pMain != NULL )
  6558. pMain->SendMessage(WM_COMMAND, ID_WINDOW_NEW, 0);
  6559. }
  6560. DeleteView();
  6561. }
  6562. }
  6563. }
  6564. void CAMCView::OnDelete(SViewUpdateInfo *pvui)
  6565. {
  6566. TRACE_METHOD(CAMCView, OnDelete);
  6567. ASSERT(pvui->path.IsEmpty() == FALSE);
  6568. HTREEITEM hti;
  6569. UINT uiReturn = GetTreeItem(&pvui->path, &hti);
  6570. if (uiReturn == ITEM_NOT_IN_VIEW)
  6571. return;
  6572. ASSERT(uiReturn != ITEM_IS_IN_VIEW || pvui->path.GetTail() == GetHMTNode(hti));
  6573. HTREEITEM htiSel = m_pTreeCtrl->GetSelectedItem();
  6574. BOOL fDeleteThis = (pvui->flag & VUI_DELETE_THIS) ? TRUE : FALSE;
  6575. BOOL fExpandable = (pvui->flag & VUI_DELETE_SETAS_EXPANDABLE) ? TRUE : FALSE;
  6576. if (uiReturn == ITEM_IS_PARENT_OF_ROOT ||
  6577. NULL == hti)
  6578. {
  6579. hti = m_pTreeCtrl->GetRootItem();
  6580. fDeleteThis = TRUE;
  6581. fExpandable = FALSE;
  6582. }
  6583. ASSERT(hti != NULL);
  6584. // If deleted scope item is also shown in the result pane
  6585. // delete it there too. Can't happen with a virtual list.
  6586. // Don't try deleting item if selection is in progress because
  6587. // the scope items haven't been added yet.
  6588. if (fDeleteThis == TRUE &&
  6589. OwnsResultList(m_pTreeCtrl->GetParentItem(hti)) &&
  6590. CanInsertScopeItemInResultPane())
  6591. {
  6592. INodeCallback* pNC = GetNodeCallback();
  6593. HRESULTITEM itemID;
  6594. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(hti);
  6595. HRESULT hr = pNC->GetResultItem(hNode, &itemID);
  6596. if (SUCCEEDED(hr) && itemID != 0)
  6597. {
  6598. IResultData* pIRD = m_pTreeCtrl->GetResultData();
  6599. pIRD->DeleteItem(itemID, 0);
  6600. }
  6601. }
  6602. m_pTreeCtrl->DeleteNode(hti, fDeleteThis);
  6603. if (fDeleteThis == FALSE && fExpandable == TRUE)
  6604. m_pTreeCtrl->SetItemState(hti, 0, TVIS_EXPANDEDONCE | TVIS_EXPANDED);
  6605. }
  6606. /*+-------------------------------------------------------------------------*
  6607. *
  6608. * CAMCView::OnUpdateSelectionForDelete
  6609. *
  6610. * PURPOSE: Called when a scope node is deleted. If the node is an ancestor
  6611. * of the currently selected node, the selection is changed to the closest
  6612. * node of the deleted node. This is either the next sibling of the node that is being deleted,
  6613. * or, if there is no next sibling, the previous sibling, or, if there is none,
  6614. * the parent.
  6615. *
  6616. * PARAMETERS:
  6617. * SViewUpdateInfo* pvui :
  6618. *
  6619. * RETURNS:
  6620. * void
  6621. *
  6622. *+-------------------------------------------------------------------------*/
  6623. void
  6624. CAMCView::OnUpdateSelectionForDelete(SViewUpdateInfo* pvui)
  6625. {
  6626. DECLARE_SC(sc, TEXT("CAMCView::OnUpdateSelectionForDelete"));
  6627. // make sure we have a path to the deleted node.
  6628. if(pvui->path.IsEmpty())
  6629. {
  6630. sc = E_UNEXPECTED;
  6631. return;
  6632. }
  6633. HTREEITEM htiToDelete;
  6634. UINT uiReturn = GetTreeItem(&pvui->path, &htiToDelete);
  6635. if (uiReturn == ITEM_IS_IN_VIEW && NULL != htiToDelete)
  6636. {
  6637. HTREEITEM htiSel = m_pTreeCtrl->GetSelectedItem();
  6638. BOOL fDeleteThis = (pvui->flag & VUI_DELETE_THIS);
  6639. // Determine whether the selected node is a descendant of the
  6640. // node bring deleted.
  6641. HTREEITEM htiTemp = htiSel;
  6642. while (htiTemp != NULL && htiTemp != htiToDelete)
  6643. {
  6644. htiTemp = m_pTreeCtrl->GetParentItem(htiTemp);
  6645. }
  6646. if (htiToDelete == htiTemp)
  6647. {
  6648. // The selected node is a descendant of the
  6649. // node being deleted.
  6650. if (fDeleteThis == TRUE)
  6651. htiTemp = m_pTreeCtrl->GetParentItem(htiToDelete);
  6652. if (!htiTemp)
  6653. htiTemp = htiToDelete;
  6654. if (htiTemp != htiSel)
  6655. {
  6656. HNODE hNode = m_pTreeCtrl->GetItemNode(htiSel);
  6657. m_pTreeCtrl->OnDeSelectNode(hNode);
  6658. ASSERT(htiTemp != NULL);
  6659. if (htiTemp != NULL)
  6660. m_pTreeCtrl->SelectItem(htiTemp);
  6661. }
  6662. }
  6663. }
  6664. }
  6665. /*+-------------------------------------------------------------------------*
  6666. * CAMCView::OnUpdateTaskpadNavigation
  6667. *
  6668. * PURPOSE:
  6669. *
  6670. * PARAMETERS:
  6671. * SViewUpdateInfo * pvui:
  6672. *
  6673. * RETURNS:
  6674. * void
  6675. /*+-------------------------------------------------------------------------*/
  6676. void CAMCView::OnUpdateTaskpadNavigation(SViewUpdateInfo *pvui)
  6677. {
  6678. TRACE_METHOD(CAMCView, OnupdateTaskpadNavigation);
  6679. ASSERT(pvui->newNode != NULL);
  6680. //m_spNodeCallback->UpdateTaskpadNavigation(GetSelectedNode(), pvui->newNode);
  6681. }
  6682. /*+-------------------------------------------------------------------------*
  6683. * CAMCView::OnModify
  6684. *
  6685. * PURPOSE:
  6686. *
  6687. * PARAMETERS:
  6688. * SViewUpdateInfo * pvui:
  6689. *
  6690. * RETURNS:
  6691. * void
  6692. /*+-------------------------------------------------------------------------*/
  6693. void CAMCView::OnModify(SViewUpdateInfo *pvui)
  6694. {
  6695. TRACE_METHOD(CAMCView, OnModify);
  6696. ASSERT(pvui->path.IsEmpty() == FALSE);
  6697. HNODE hNode = 0;
  6698. HTREEITEM hti;
  6699. if (GetTreeItem(&pvui->path, &hti) == ITEM_IS_IN_VIEW && hti != NULL)
  6700. {
  6701. ASSERT(m_pTreeCtrl != NULL);
  6702. m_pTreeCtrl->ResetNode(hti);
  6703. /*
  6704. * The name of the selected node and all of its ancestors are
  6705. * displayed in the frame title. If the modified item is an
  6706. * ancestor of the selected node, we need to update the frame title.
  6707. */
  6708. HTREEITEM htiAncesctor;
  6709. for (htiAncesctor = m_pTreeCtrl->GetSelectedItem();
  6710. htiAncesctor != NULL;
  6711. htiAncesctor = m_pTreeCtrl->GetParentItem (htiAncesctor))
  6712. {
  6713. if (htiAncesctor == hti)
  6714. {
  6715. CChildFrame* pFrame = GetParentFrame();
  6716. if (pFrame)
  6717. pFrame->OnUpdateFrameTitle(TRUE);
  6718. break;
  6719. }
  6720. }
  6721. ASSERT(hti != NULL);
  6722. if (hti != NULL &&
  6723. OwnsResultList(m_pTreeCtrl->GetParentItem(hti)) &&
  6724. !IsVirtualList())
  6725. {
  6726. // Continue only if the currently selected item is the parent
  6727. // of the modified node. In this case we need to update the
  6728. // result view. Can't happen with a virtual list.
  6729. if (hNode == 0)
  6730. hNode = (HNODE)m_pTreeCtrl->GetItemData(hti);
  6731. ASSERT(hNode != NULL);
  6732. HRESULTITEM hri;
  6733. HRESULT hr = m_spNodeCallback->GetResultItem(hNode, &hri);
  6734. CHECK_HRESULT(hr);
  6735. // NOTE: the test for itemID != NULL below is related to bug 372242:
  6736. // MMC asserts on index server root node.
  6737. // What happens is that the snapin adds scope nodes on a SHOW event.
  6738. // These items have not yet been added to the result pane and so itemID
  6739. // comes back NULL.
  6740. if (SUCCEEDED(hr) && hri != NULL)
  6741. m_pListCtrl->OnModifyItem(CResultItem::FromHandle(hri));
  6742. }
  6743. }
  6744. }
  6745. void CAMCView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
  6746. {
  6747. Dbg(DEB_USER1, _T("CAMCView::OnUpdate<0x%08x, 0x%08x, 0x%08x>\n"),
  6748. pSender, lHint, pHint);
  6749. SViewUpdateInfo *pvui = reinterpret_cast<SViewUpdateInfo*>(pHint);
  6750. switch (lHint)
  6751. {
  6752. case 0:
  6753. // Sent by CView::OnInitialUpdate()
  6754. break;
  6755. case VIEW_UPDATE_ADD:
  6756. OnAdd(pvui);
  6757. break;
  6758. case VIEW_UPDATE_SELFORDELETE:
  6759. OnUpdateSelectionForDelete(pvui);
  6760. break;
  6761. case VIEW_UPDATE_DELETE:
  6762. OnDelete(pvui);
  6763. break;
  6764. case VIEW_UPDATE_DELETE_EMPTY_VIEW:
  6765. OnDeleteEmptyView();
  6766. break;
  6767. case VIEW_UPDATE_MODIFY:
  6768. OnModify(pvui);
  6769. break;
  6770. case VIEW_RESELECT:
  6771. if (m_ViewData.m_spControlbarsCache != NULL)
  6772. m_ViewData.m_spControlbarsCache->DetachControlbars();
  6773. m_pTreeCtrl->ScReselect();
  6774. break;
  6775. case VIEW_UPDATE_TASKPAD_NAVIGATION:
  6776. OnUpdateTaskpadNavigation(pvui);
  6777. break;
  6778. default:
  6779. ASSERT(0);
  6780. }
  6781. }
  6782. static int static_nViewID = 1;
  6783. UINT CAMCView::GetViewID(void)
  6784. {
  6785. if (m_nViewID)
  6786. return m_nViewID;
  6787. SetViewID(static_nViewID);
  6788. ++static_nViewID;
  6789. return m_nViewID;
  6790. //UINT const id = m_nViewID ? m_nViewID : m_nViewID = static_nViewID++;
  6791. //return id;
  6792. }
  6793. /*+-------------------------------------------------------------------------*
  6794. * CAMCView::ScCompleteInitialization
  6795. *
  6796. * This function completes the initialization process for CAMCView. It
  6797. * is called from OnInitialUpdate.
  6798. *--------------------------------------------------------------------------*/
  6799. SC CAMCView::ScCompleteInitialization()
  6800. {
  6801. DECLARE_SC (sc, _T("CAMCView::ScCompleteInitialization"));
  6802. IScopeTree* const pScopeTree = GetScopeTree();
  6803. sc = ScCheckPointers (pScopeTree, E_UNEXPECTED);
  6804. if (sc)
  6805. return (sc);
  6806. pScopeTree->QueryIterator(&m_spScopeTreeIter);
  6807. pScopeTree->QueryNodeCallback(&m_spNodeCallback);
  6808. m_ViewData.m_spNodeCallback = GetNodeCallback();
  6809. sc = ScCheckPointers (m_ViewData.m_spNodeCallback, E_UNEXPECTED);
  6810. if (sc)
  6811. return (sc);
  6812. CAMCDoc* const pDoc = GetDocument();
  6813. sc = ScCheckPointers (pDoc, E_UNEXPECTED);
  6814. if (sc)
  6815. return (sc);
  6816. if (m_hMTNode == NULL)
  6817. {
  6818. MTNODEID const nodeID = pDoc->GetMTNodeIDForNewView();
  6819. HRESULT hr = pScopeTree->Find(nodeID, &m_hMTNode);
  6820. if (FAILED(hr) || m_hMTNode == 0)
  6821. {
  6822. sc.FromMMC (IDS_ExploredWindowFailed);
  6823. return (sc);
  6824. }
  6825. }
  6826. sc = m_spStandardToolbar->ScInitializeStdToolbar(this);
  6827. if (sc)
  6828. return (sc);
  6829. // Set the iterator to the correct node
  6830. m_spScopeTreeIter->SetCurrent(m_hMTNode);
  6831. bool fShowScopePane = IsScopePaneAllowed();
  6832. // Intialize the iterator and the callback interface
  6833. SetViewID(pDoc->GetViewIDForNewView());
  6834. GetViewID(); // initialized the view id if GetViewIDForNewView returned 0
  6835. // Insert the root node for this view
  6836. HNODE hNode = 0;
  6837. sc = pScopeTree->CreateNode (m_hMTNode, reinterpret_cast<LONG_PTR>(GetViewData()),
  6838. TRUE, &hNode);
  6839. if (sc)
  6840. return (sc);
  6841. sc = ScCheckPointers (hNode, E_UNEXPECTED);
  6842. if (sc)
  6843. return (sc);
  6844. HTREEITEM hti = m_pTreeCtrl->InsertNode(TVI_ROOT, hNode);
  6845. m_htiStartingSelectedNode = hti;
  6846. // If the persisted state is expanded, call INodeCallback::Expand
  6847. m_pTreeCtrl->Expand(hti, TVE_EXPAND);
  6848. /*
  6849. * If a scope pane is permitted in this window, set the scope
  6850. * pane visible, and modify the scope pane & favorites toolbar
  6851. * buttons to the proper checked state.
  6852. */
  6853. sc = ScShowScopePane (fShowScopePane, true);
  6854. if (sc)
  6855. return (sc);
  6856. LPUNKNOWN pUnkResultsPane = NULL;
  6857. pUnkResultsPane = GetPaneUnknown(ePane_Results);
  6858. m_pTreeCtrl->m_spNodeManager->SetResultView(pUnkResultsPane);
  6859. DeferRecalcLayout();
  6860. m_pHistoryList->Clear();
  6861. IdentifyRootNode ();
  6862. // Select the root item
  6863. hti = m_pTreeCtrl->GetRootItem();
  6864. m_pTreeCtrl->SelectItem(hti);
  6865. /*
  6866. * if the document has a custom icon, use it on this window
  6867. */
  6868. if (pDoc->HasCustomIcon())
  6869. {
  6870. GetParentFrame()->SetIcon (pDoc->GetCustomIcon(true), true);
  6871. GetParentFrame()->SetIcon (pDoc->GetCustomIcon(false), false);
  6872. }
  6873. /*
  6874. * we just initialized, so the view isn't dirty
  6875. */
  6876. SetDirty (false);
  6877. return (sc);
  6878. }
  6879. void CAMCView::OnInitialUpdate()
  6880. {
  6881. DECLARE_SC (sc, _T("CAMCView::OnInitialUpdate"));
  6882. CView::OnInitialUpdate();
  6883. sc = ScCompleteInitialization ();
  6884. if (sc)
  6885. return;
  6886. }
  6887. //+-------------------------------------------------------------------
  6888. //
  6889. // Member: CAMCView::ScDocumentLoadCompleted
  6890. //
  6891. // Synopsis: The document is completely loaded so all the objects
  6892. // that initialize themself from document are in valid
  6893. // state. Any initialization performed earlier using invalid
  6894. // data can be now re-initialized with proper data.
  6895. //
  6896. // The above CAMCView::ScCompleteInitialization is called
  6897. // during the loading of views, thus the document is not
  6898. // completely loaded yet.
  6899. //
  6900. // Arguments: [pDoc] - [in] the CAMCDoc object
  6901. //
  6902. // Returns: SC
  6903. //
  6904. //--------------------------------------------------------------------
  6905. SC CAMCView::ScDocumentLoadCompleted (CAMCDoc *pDoc)
  6906. {
  6907. DECLARE_SC(sc, _T("CAMCView::ScDocumentLoadCompleted"));
  6908. sc = ScCheckPointers(pDoc);
  6909. if (sc)
  6910. return sc;
  6911. // 1. Need to hide toolbutton "Show/Hide scopetree".
  6912. // The FrameState is loaded after views when CAMCDoc loads document. And it contains
  6913. // whether the "View Customization" is enabled or not. If "View customization" is
  6914. // disabled then we need to disable "Show ScopeTree" button.
  6915. if (! pDoc->AllowViewCustomization())
  6916. {
  6917. CStandardToolbar* pStdToolbar = GetStdToolbar();
  6918. sc = ScCheckPointers(pStdToolbar, E_UNEXPECTED);
  6919. if (sc)
  6920. return (sc);
  6921. sc = pStdToolbar->ScEnableScopePaneBtn (false);
  6922. if (sc)
  6923. return (sc);
  6924. }
  6925. return (sc);
  6926. }
  6927. /*--------------------------------------------------------------------------*
  6928. * CAMCView::IdentifyRootNode
  6929. *
  6930. * This functions determines if this view is rooted at a non-persistent
  6931. * dynamic node. If so, we won't persist this view at save time.
  6932. *--------------------------------------------------------------------------*/
  6933. void CAMCView::IdentifyRootNode ()
  6934. {
  6935. // In order to get results from GetRootNodePath that are meaningful
  6936. // in this context, there needs to be a root item in the tree.
  6937. ASSERT (m_pTreeCtrl->GetRootItem() != NULL);
  6938. CBookmark bm;
  6939. HRESULT hr = GetRootNodePath (&bm);
  6940. ASSERT (SUCCEEDED (hr) == bm.IsValid());
  6941. m_fRootedAtNonPersistedDynamicNode = (hr != S_OK);
  6942. }
  6943. void GetFullPath(CAMCTreeView &ctc, HTREEITEM hti, CString &strPath)
  6944. {
  6945. TRACE_FUNCTION(GetFullPath);
  6946. if (hti == NULL)
  6947. {
  6948. strPath = _T("");
  6949. return;
  6950. }
  6951. GetFullPath(ctc, ctc.GetParentItem(hti), strPath);
  6952. if (strPath.GetLength() > 0)
  6953. strPath += _T('\\');
  6954. HNODE hNode = ctc.GetItemNode(hti);
  6955. INodeCallback* spCallback = ctc.GetNodeCallback();
  6956. ASSERT(spCallback != NULL);
  6957. tstring strName;
  6958. HRESULT const hr = spCallback->GetDisplayName(hNode, strName);
  6959. strPath += strName.data();
  6960. }
  6961. LPCTSTR CAMCView::GetWindowTitle(void)
  6962. {
  6963. TRACE_METHOD(CAMCView, GetWindowTitle);
  6964. if (HasCustomTitle() && (m_spNodeCallback != NULL))
  6965. {
  6966. HNODE hNode = GetSelectedNode();
  6967. if (hNode != NULL)
  6968. {
  6969. tstring strWindowTitle;
  6970. if (SUCCEEDED(m_spNodeCallback->GetWindowTitle(hNode, strWindowTitle)))
  6971. {
  6972. m_strWindowTitle = strWindowTitle.data();
  6973. return m_strWindowTitle;
  6974. }
  6975. }
  6976. }
  6977. if (m_pTreeCtrl == NULL)
  6978. {
  6979. m_strWindowTitle.Empty();
  6980. }
  6981. else
  6982. {
  6983. GetFullPath(*m_pTreeCtrl,
  6984. m_pTreeCtrl->GetSelectedItem(),
  6985. m_strWindowTitle);
  6986. }
  6987. return m_strWindowTitle;
  6988. }
  6989. void CAMCView::SelectNode(MTNODEID ID, GUID &guidTaskpad)
  6990. {
  6991. ScSelectNode(ID);
  6992. // After setting the taskpad enable/disable save list button
  6993. CStandardToolbar* pStdToolbar = GetStdToolbar();
  6994. ASSERT(NULL != pStdToolbar);
  6995. if (NULL != pStdToolbar)
  6996. {
  6997. pStdToolbar->ScEnableExportList(GetListSize() > 0 /*Enable only if LV has items*/);
  6998. }
  6999. }
  7000. //+-------------------------------------------------------------------
  7001. //
  7002. // Member: CAMCView::ScSelectNode
  7003. //
  7004. // Synopsis: Select the given node. Normally if the node is not available
  7005. // then we select nearest parent or child. But if bSelectExactNode
  7006. // is true then have to select the exact node else do not select any node.
  7007. //
  7008. // Arguments: [ID] - [in] node that needs to be selected.
  7009. // [bSelectExactNode] - [in] select exact node or not?
  7010. //
  7011. // Returns: SC
  7012. //
  7013. //--------------------------------------------------------------------
  7014. SC CAMCView::ScSelectNode (MTNODEID ID, bool bSelectExactNode)
  7015. {
  7016. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7017. DECLARE_SC (sc, _T("CAMCView::ScSelectNode"));
  7018. IScopeTree* pIST = GetScopeTreePtr();
  7019. sc = ScCheckPointers(pIST, m_pTreeCtrl, E_UNEXPECTED);
  7020. if (sc)
  7021. return sc;
  7022. long length = 0;
  7023. CCoTaskMemPtr<MTNODEID> spIDs;
  7024. sc = pIST->GetIDPath(ID, &spIDs, &length);
  7025. if (sc)
  7026. return (sc);
  7027. if ( (length < 1) || (spIDs == NULL) )
  7028. return (sc = E_FAIL);
  7029. sc = m_pTreeCtrl->ScSelectNode(spIDs, length, bSelectExactNode);
  7030. // If select exact node is specified and the node could not be
  7031. // selected then return error without tracing it.
  7032. if (bSelectExactNode && (sc == ScFromMMC(IDS_NODE_NOT_FOUND)) )
  7033. {
  7034. SC scNoTrace = sc;
  7035. sc.Clear();
  7036. return scNoTrace;
  7037. }
  7038. if (sc)
  7039. return sc;
  7040. SetDirty();
  7041. return (sc);
  7042. }
  7043. /*+-------------------------------------------------------------------------*
  7044. *
  7045. * CAMCView::ScExpandNode
  7046. *
  7047. * PURPOSE: Expands the tree up to the specified node. The expansion can occur
  7048. * either visually, where the user sees the expansion, or nonvisually,
  7049. * where all the child items are added but there is no visual effect.
  7050. *
  7051. * PARAMETERS:
  7052. * MTNODEID id : id of node to expand
  7053. * bool bExpand : true to expand the node, false to collapse
  7054. * bool bExpandVisually : true to show the changes, else false.
  7055. *
  7056. * RETURNS:
  7057. * SC
  7058. *
  7059. *+-------------------------------------------------------------------------*/
  7060. SC CAMCView::ScExpandNode (
  7061. MTNODEID id,
  7062. bool fExpand,
  7063. bool fExpandVisually)
  7064. {
  7065. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7066. DECLARE_SC (sc, _T("CAMCView::ScExpandNode"));
  7067. IScopeTree* pIST = GetScopeTreePtr();
  7068. ASSERT(pIST != NULL);
  7069. if (!pIST)
  7070. return (sc = E_NOINTERFACE);
  7071. long length = 0;
  7072. CCoTaskMemPtr<MTNODEID> spIDs;
  7073. sc = pIST->GetIDPath(id, &spIDs, &length);
  7074. if (sc)
  7075. return (sc);
  7076. ASSERT(length);
  7077. ASSERT(spIDs);
  7078. ASSERT(m_pTreeCtrl != NULL);
  7079. if (m_pTreeCtrl)
  7080. m_pTreeCtrl->ExpandNode(spIDs, length, fExpand, fExpandVisually);
  7081. return (sc);
  7082. }
  7083. ViewSettings::ViewSettings(CAMCView* v)
  7084. : m_nViewID(v->m_nViewID), m_bDescriptionbarVisible(v->IsDescBarVisible()),
  7085. m_nViewMode(v->m_nViewMode), m_nListViewStyle(v->GetDefaultListViewStyle()),
  7086. m_DefaultLVStyle(v->m_DefaultLVStyle), m_bScopePaneVisible(v->IsScopePaneVisible())
  7087. {
  7088. ASSERT(v != NULL);
  7089. v->GetPaneInfo (CConsoleView::ePane_ScopeTree, &m_Scope.cxWidth, &m_Scope.cxMin);
  7090. v->GetDefaultColumnWidths(m_DefaultColumnWidths);
  7091. }
  7092. /*
  7093. * The location and hidden fields of the scope structure were redundant and are
  7094. * no longer used. Both fields were used to indicate when the scope pane was
  7095. * hidden, which is also determined by the FLAG1_SCOPE_VISIBLE flag. The space
  7096. * has been retained to avoid changing the persisted structure.
  7097. */
  7098. struct PersistedViewData
  7099. {
  7100. WINDOWPLACEMENT windowPlacement;
  7101. struct
  7102. {
  7103. int location; // not used, but kept for compatibility
  7104. int min;
  7105. int ideal;
  7106. BOOL hidden; // not used, but kept for compatibility
  7107. } scope;
  7108. int viewMode;
  7109. long listViewStyle;
  7110. ULONG ulFlag1;
  7111. int viewID;
  7112. BOOL descriptionBarVisible;
  7113. int defaultColumnWidth[2];
  7114. };
  7115. /*
  7116. * The sense of the FLAG1_NO_xxx flags is negative. That is, when a
  7117. * FLAG1_NO_xxx flag is set, its corresponding UI element is *not*
  7118. * displayed. This is to maintain compatibility with console files
  7119. * created before the existence of the FLAG1_NO_xxx flags. These
  7120. * consoles always had all UI elements displayed, and the then-unused
  7121. * bits in their flags field were defaulted to 0. To maintain
  7122. * compatibility, we have to maintain that (0 == on).
  7123. */
  7124. #define FLAG1_SCOPE_PANE_VISIBLE 0x00000001
  7125. #define FLAG1_NO_STD_MENUS 0x00000002
  7126. #define FLAG1_NO_STD_BUTTONS 0x00000004
  7127. #define FLAG1_NO_SNAPIN_MENUS 0x00000008
  7128. #define FLAG1_NO_SNAPIN_BUTTONS 0x00000010
  7129. #define FLAG1_DISABLE_SCOPEPANE 0x00000020
  7130. #define FLAG1_DISABLE_STD_TOOLBARS 0x00000040
  7131. #define FLAG1_CUSTOM_TITLE 0x00000080
  7132. #define FLAG1_NO_STATUS_BAR 0x00000100
  7133. #define FLAG1_CREATED_IN_USER_MODE 0x00000200 // used to be named FLAG1_NO_AUTHOR_MODE
  7134. //#define FLAG1_FAVORITES_SELECTED 0x00000400 // unused, but don't recycle (for compatibility)
  7135. #define FLAG1_NO_TREE_ALLOWED 0x00000800 // used for compatibility with MMC1.2 in CAMCView::Load.
  7136. // Do not use for any other purposes.
  7137. #define FLAG1_NO_TASKPAD_TABS 0x00001000
  7138. /***************************************************************************\
  7139. *
  7140. * ARRAY: mappedViewModes
  7141. *
  7142. * PURPOSE: provides map to be used when persisting ViewMode enumeration
  7143. *
  7144. \***************************************************************************/
  7145. static const EnumLiteral mappedViewModes[] =
  7146. {
  7147. { MMCLV_VIEWSTYLE_ICON, XML_ENUM_LV_STYLE_ICON },
  7148. { MMCLV_VIEWSTYLE_REPORT, XML_ENUM_LV_STYLE_REPORT },
  7149. { MMCLV_VIEWSTYLE_SMALLICON, XML_ENUM_LV_STYLE_SMALLICON },
  7150. { MMCLV_VIEWSTYLE_LIST, XML_ENUM_LV_STYLE_LIST },
  7151. { MMCLV_VIEWSTYLE_FILTERED, XML_ENUM_LV_STYLE_FILTERED},
  7152. };
  7153. /***************************************************************************\
  7154. *
  7155. * ARRAY: mappedListStyles
  7156. *
  7157. * PURPOSE: provides map to be used when persisting ListView style flag
  7158. *
  7159. \***************************************************************************/
  7160. static const EnumLiteral mappedListStyles[] =
  7161. {
  7162. { LVS_SINGLESEL, XML_BITFLAG_LV_STYLE_SINGLESEL },
  7163. { LVS_SHOWSELALWAYS, XML_BITFLAG_LV_STYLE_SHOWSELALWAYS },
  7164. { LVS_SORTASCENDING, XML_BITFLAG_LV_STYLE_SORTASCENDING },
  7165. { LVS_SORTDESCENDING, XML_BITFLAG_LV_STYLE_SORTDESCENDING },
  7166. { LVS_SHAREIMAGELISTS, XML_BITFLAG_LV_STYLE_SHAREIMAGELISTS },
  7167. { LVS_NOLABELWRAP, XML_BITFLAG_LV_STYLE_NOLABELWRAP },
  7168. { LVS_AUTOARRANGE, XML_BITFLAG_LV_STYLE_AUTOARRANGE },
  7169. { LVS_EDITLABELS, XML_BITFLAG_LV_STYLE_EDITLABELS },
  7170. { LVS_OWNERDATA, XML_BITFLAG_LV_STYLE_OWNERDATA },
  7171. { LVS_NOSCROLL, XML_BITFLAG_LV_STYLE_NOSCROLL },
  7172. { LVS_ALIGNLEFT, XML_BITFLAG_LV_STYLE_ALIGNLEFT },
  7173. { LVS_OWNERDRAWFIXED, XML_BITFLAG_LV_STYLE_OWNERDRAWFIXED },
  7174. { LVS_NOCOLUMNHEADER, XML_BITFLAG_LV_STYLE_NOCOLUMNHEADER },
  7175. { LVS_NOSORTHEADER, XML_BITFLAG_LV_STYLE_NOSORTHEADER },
  7176. };
  7177. /***************************************************************************\
  7178. *
  7179. * ARRAY: mappedViewFlags
  7180. *
  7181. * PURPOSE: provides map to be used when persisting View flags
  7182. *
  7183. \***************************************************************************/
  7184. static const EnumLiteral mappedViewFlags[] =
  7185. {
  7186. { FLAG1_SCOPE_PANE_VISIBLE, XML_BITFLAG_VIEW_SCOPE_PANE_VISIBLE },
  7187. { FLAG1_NO_STD_MENUS, XML_BITFLAG_VIEW_NO_STD_MENUS },
  7188. { FLAG1_NO_STD_BUTTONS, XML_BITFLAG_VIEW_NO_STD_BUTTONS },
  7189. { FLAG1_NO_SNAPIN_MENUS, XML_BITFLAG_VIEW_NO_SNAPIN_MENUS },
  7190. { FLAG1_NO_SNAPIN_BUTTONS, XML_BITFLAG_VIEW_NO_SNAPIN_BUTTONS },
  7191. { FLAG1_DISABLE_SCOPEPANE, XML_BITFLAG_VIEW_DISABLE_SCOPEPANE },
  7192. { FLAG1_DISABLE_STD_TOOLBARS, XML_BITFLAG_VIEW_DISABLE_STD_TOOLBARS },
  7193. { FLAG1_CUSTOM_TITLE, XML_BITFLAG_VIEW_CUSTOM_TITLE },
  7194. { FLAG1_NO_STATUS_BAR, XML_BITFLAG_VIEW_NO_STATUS_BAR },
  7195. { FLAG1_CREATED_IN_USER_MODE, XML_BITFLAG_VIEW_CREATED_IN_USER_MODE },
  7196. { FLAG1_NO_TASKPAD_TABS, XML_BITFLAG_VIEW_NO_TASKPAD_TABS },
  7197. };
  7198. /***************************************************************************\
  7199. *
  7200. * ARRAY: mappedSWCommands
  7201. *
  7202. * PURPOSE: provides mapping to persist show commands as literals
  7203. *
  7204. \***************************************************************************/
  7205. static const EnumLiteral mappedSWCommands[] =
  7206. {
  7207. { SW_HIDE, XML_ENUM_SHOW_CMD_HIDE },
  7208. { SW_SHOWNORMAL, XML_ENUM_SHOW_CMD_SHOWNORMAL },
  7209. { SW_SHOWMINIMIZED, XML_ENUM_SHOW_CMD_SHOWMINIMIZED },
  7210. { SW_SHOWMAXIMIZED, XML_ENUM_SHOW_CMD_SHOWMAXIMIZED },
  7211. { SW_SHOWNOACTIVATE, XML_ENUM_SHOW_CMD_SHOWNOACTIVATE },
  7212. { SW_SHOW, XML_ENUM_SHOW_CMD_SHOW },
  7213. { SW_MINIMIZE, XML_ENUM_SHOW_CMD_MINIMIZE },
  7214. { SW_SHOWMINNOACTIVE, XML_ENUM_SHOW_CMD_SHOWMINNOACTIVE },
  7215. { SW_SHOWNA, XML_ENUM_SHOW_CMD_SHOWNA },
  7216. { SW_RESTORE, XML_ENUM_SHOW_CMD_RESTORE },
  7217. { SW_SHOWDEFAULT, XML_ENUM_SHOW_CMD_SHOWDEFAULT },
  7218. { SW_FORCEMINIMIZE, XML_ENUM_SHOW_CMD_FORCEMINIMIZE },
  7219. };
  7220. /***************************************************************************\
  7221. *
  7222. * ARRAY: mappedWPFlags
  7223. *
  7224. * PURPOSE: provides mapping to persist WP flags
  7225. *
  7226. \***************************************************************************/
  7227. static const EnumLiteral mappedWPFlags[] =
  7228. {
  7229. { WPF_SETMINPOSITION, XML_ENUM_WIN_PLACE_SETMINPOSITION },
  7230. { WPF_RESTORETOMAXIMIZED, XML_ENUM_WIN_PLACE_RESTORETOMAXIMIZED },
  7231. #ifdef WPF_ASYNCWINDOWPLACEMENT
  7232. { WPF_ASYNCWINDOWPLACEMENT, XML_ENUM_WIN_PLACE_ASYNCWINDOWPLACEMENT },
  7233. #else
  7234. { 4, XML_ENUM_WIN_PLACE_ASYNCWINDOWPLACEMENT },
  7235. #endif
  7236. };
  7237. /*+-------------------------------------------------------------------------*
  7238. * PersistViewData(CPersistor &persistor, PersistedViewData viewData)
  7239. *
  7240. *
  7241. * PURPOSE: Persists a PersistedViewData object to the specified persistor.
  7242. *
  7243. *+-------------------------------------------------------------------------*/
  7244. void PersistViewData(CPersistor &persistor, PersistedViewData& viewData)
  7245. {
  7246. persistor.PersistAttribute(XML_ATTR_VIEW_ID, viewData.viewID);
  7247. // write out the windowPlacement structure.
  7248. persistor.Persist(CXMLWindowPlacement(viewData.windowPlacement));
  7249. // write out the scope structure
  7250. persistor.PersistAttribute(XML_ATTR_VIEW_SCOPE_WIDTH, viewData.scope.ideal);
  7251. if (persistor.IsLoading())
  7252. {
  7253. // initialize for compatibility;
  7254. viewData.scope.hidden = true;
  7255. viewData.scope.location = 0;
  7256. viewData.scope.min = 50;
  7257. }
  7258. // write out the remaining fields
  7259. CPersistor persistorSettings(persistor, XML_TAG_VIEW_SETTINGS_2);
  7260. // create wrapper to persist enumeration values as strings
  7261. CXMLEnumeration viewModePersistor(viewData.viewMode, mappedViewModes, countof(mappedViewModes));
  7262. // persist the wrapper
  7263. persistorSettings.PersistAttribute(XML_ATTR_VIEW_SETNGS_VIEW_MODE, viewModePersistor);
  7264. // create wrapper to persist flag values as strings
  7265. CXMLBitFlags viewStylePersistor(viewData.listViewStyle, mappedListStyles, countof(mappedListStyles));
  7266. // persist the wrapper
  7267. persistorSettings.PersistAttribute(XML_ATTR_VIEW_SETNGS_LIST_STYLE, viewStylePersistor);
  7268. // create wrapper to persist flag values as strings
  7269. CXMLBitFlags flagPersistor(viewData.ulFlag1, mappedViewFlags, countof(mappedViewFlags));
  7270. // persist the wrapper
  7271. persistorSettings.PersistAttribute(XML_ATTR_VIEW_SETNGS_FLAG, flagPersistor);
  7272. persistorSettings.PersistAttribute(XML_ATTR_VIEW_SETNGS_DB_VISIBLE, CXMLBoolean(viewData.descriptionBarVisible));
  7273. persistorSettings.PersistAttribute(XML_ATTR_VIEW_SETNGS_DEF_COL_W0, viewData.defaultColumnWidth[0]);
  7274. persistorSettings.PersistAttribute(XML_ATTR_VIEW_SETNGS_DEF_COL_W1, viewData.defaultColumnWidth[1]);
  7275. }
  7276. /*+-------------------------------------------------------------------------*
  7277. *
  7278. * CAMCView::Persist
  7279. *
  7280. * PURPOSE: Persists the CAMCView object to the specified persistor. Based
  7281. * on CAMCView::Save.
  7282. *
  7283. * PARAMETERS:
  7284. * CPersistor& persistor :
  7285. *
  7286. * RETURNS:
  7287. * void
  7288. *
  7289. *+-------------------------------------------------------------------------*/
  7290. void
  7291. CAMCView::Persist(CPersistor& persistor)
  7292. {
  7293. DECLARE_SC(sc, TEXT("CAMCView::Persist"));
  7294. HRESULT hr;
  7295. CBookmark bmr;
  7296. CBookmark bms;
  7297. if (persistor.IsStoring())
  7298. {
  7299. sc = GetRootNodePath(&bmr);
  7300. if (sc)
  7301. sc.Throw();
  7302. persistor.Persist(bmr, XML_NAME_ROOT_NODE); // ... its too late for root node when loading
  7303. sc = GetSelectedNodePath(&bms);
  7304. if (sc)
  7305. sc.Throw();
  7306. }
  7307. persistor.Persist(bms, XML_NAME_SELECTED_NODE);
  7308. // mostly copied from CAMCView::Save
  7309. // Get the parent frame
  7310. CWnd* const pParent = GetParent();
  7311. sc = ScCheckPointers(pParent,E_POINTER);
  7312. if (sc)
  7313. sc.Throw();
  7314. // Get the frames state data
  7315. PersistedViewData vd;
  7316. vd.windowPlacement.length = sizeof(vd.windowPlacement);
  7317. const BOOL bGotPlacement = pParent->GetWindowPlacement(&vd.windowPlacement);
  7318. if (!bGotPlacement)
  7319. sc.Throw(E_FAIL);
  7320. if (persistor.IsStoring())
  7321. {
  7322. /*
  7323. * If this window is minimized, make sure we set things up so the
  7324. * WINDOWPLACEMENT.ptMinPosition will be restored by SetWindowPlacement
  7325. * when we load. If we don't do this, it'll get some random min
  7326. * position, likely not what we want.
  7327. */
  7328. if (vd.windowPlacement.showCmd == SW_SHOWMINIMIZED)
  7329. vd.windowPlacement.flags |= WPF_SETMINPOSITION;
  7330. GetPaneInfo(ePane_ScopeTree, &vd.scope.ideal, &vd.scope.min);
  7331. vd.viewMode = m_nViewMode;
  7332. vd.listViewStyle = GetDefaultListViewStyle();
  7333. vd.ulFlag1 = 0;
  7334. if (IsScopePaneVisible())
  7335. vd.ulFlag1 |= FLAG1_SCOPE_PANE_VISIBLE;
  7336. if (!IsAuthorModeView())
  7337. vd.ulFlag1 |= FLAG1_CREATED_IN_USER_MODE;
  7338. if (!(m_ViewData.m_dwToolbarsDisplayed & STD_MENUS))
  7339. vd.ulFlag1 |= FLAG1_NO_STD_MENUS;
  7340. if (!(m_ViewData.m_dwToolbarsDisplayed & STD_BUTTONS))
  7341. vd.ulFlag1 |= FLAG1_NO_STD_BUTTONS;
  7342. if (!(m_ViewData.m_dwToolbarsDisplayed & SNAPIN_MENUS))
  7343. vd.ulFlag1 |= FLAG1_NO_SNAPIN_MENUS;
  7344. if (!(m_ViewData.m_dwToolbarsDisplayed & SNAPIN_BUTTONS))
  7345. vd.ulFlag1 |= FLAG1_NO_SNAPIN_BUTTONS;
  7346. if (!(m_ViewData.m_dwToolbarsDisplayed & STATUS_BAR))
  7347. vd.ulFlag1 |= FLAG1_NO_STATUS_BAR;
  7348. if (!AreStdToolbarsAllowed ())
  7349. vd.ulFlag1 |= FLAG1_DISABLE_STD_TOOLBARS;
  7350. if (!IsScopePaneAllowed ())
  7351. vd.ulFlag1 |= FLAG1_DISABLE_SCOPEPANE;
  7352. if (HasCustomTitle ())
  7353. vd.ulFlag1 |= FLAG1_CUSTOM_TITLE;
  7354. if (!AreTaskpadTabsAllowed())
  7355. (vd.ulFlag1 |= FLAG1_NO_TASKPAD_TABS);
  7356. vd.viewID = GetViewID();
  7357. vd.descriptionBarVisible = IsDescBarVisible();
  7358. GetDefaultColumnWidths(vd.defaultColumnWidth);
  7359. }
  7360. PersistViewData(persistor,vd);
  7361. if (persistor.IsLoading())
  7362. {
  7363. ASSERT(int(m_nViewID) == vd.viewID);
  7364. m_ViewData.m_nViewID = m_nViewID = vd.viewID;
  7365. if (int(m_nViewID) >= static_nViewID)
  7366. static_nViewID = m_nViewID + 1;
  7367. //SetDefaultColumnWidths(vd.defaultColumnWidth);
  7368. SetDescBarVisible(vd.descriptionBarVisible);
  7369. // we shouldn't restore maximized window position
  7370. // since it may not be proper one for the current resolution
  7371. // related to bug #404118
  7372. WINDOWPLACEMENT orgPlacement;
  7373. ZeroMemory(&orgPlacement,sizeof(orgPlacement));
  7374. orgPlacement.length = sizeof(orgPlacement);
  7375. if (pParent->GetWindowPlacement(&orgPlacement))
  7376. {
  7377. vd.windowPlacement.ptMaxPosition = orgPlacement.ptMaxPosition;
  7378. }
  7379. m_ViewData.SetScopePaneVisible( 0 != (vd.ulFlag1 & FLAG1_SCOPE_PANE_VISIBLE) );
  7380. // Set the location and size of the frame
  7381. const BOOL bPlaced = pParent->SetWindowPlacement(&vd.windowPlacement);
  7382. if (!bPlaced)
  7383. sc.Throw(E_FAIL);
  7384. // Restore window settings
  7385. if (vd.ulFlag1 & FLAG1_DISABLE_SCOPEPANE)
  7386. m_ViewData.m_lWindowOptions |= MMC_NW_OPTION_NOSCOPEPANE;
  7387. if (vd.ulFlag1 & FLAG1_DISABLE_STD_TOOLBARS)
  7388. m_ViewData.m_lWindowOptions |= MMC_NW_OPTION_NOTOOLBARS;
  7389. if (vd.ulFlag1 & FLAG1_CUSTOM_TITLE)
  7390. m_ViewData.m_lWindowOptions |= MMC_NW_OPTION_CUSTOMTITLE;
  7391. SetAuthorModeView (!(vd.ulFlag1 & FLAG1_CREATED_IN_USER_MODE));
  7392. if ((vd.ulFlag1 & FLAG1_NO_TASKPAD_TABS))
  7393. SetTaskpadTabsAllowed(FALSE);
  7394. // Apply run time restrictions
  7395. // if at least one type of scope pane allowed then if the selected
  7396. // one is not allowed, switch to the other. If neither is allowed
  7397. // then keep the selection and hide the scope pane.
  7398. if (IsScopePaneAllowed())
  7399. {
  7400. // Restore scope pane settings
  7401. SetPaneInfo(ePane_ScopeTree, vd.scope.ideal, vd.scope.min);
  7402. sc = ScShowScopePane ( m_ViewData.IsScopePaneVisible() );
  7403. }
  7404. else
  7405. sc = ScShowScopePane (false);
  7406. if (sc)
  7407. sc.Throw();
  7408. // Force layout re-calculation
  7409. DeferRecalcLayout();
  7410. // Restore view style & view mode if persisted will be set by nodemgr.
  7411. SetDefaultListViewStyle(vd.listViewStyle);
  7412. DWORD dwToolbars = 0;
  7413. if (!(vd.ulFlag1 & FLAG1_NO_STD_MENUS))
  7414. dwToolbars |= STD_MENUS;
  7415. if (!(vd.ulFlag1 & FLAG1_NO_STD_BUTTONS))
  7416. dwToolbars |= STD_BUTTONS;
  7417. if (!(vd.ulFlag1 & FLAG1_NO_SNAPIN_MENUS))
  7418. dwToolbars |= SNAPIN_MENUS;
  7419. if (!(vd.ulFlag1 & FLAG1_NO_SNAPIN_BUTTONS))
  7420. dwToolbars |= SNAPIN_BUTTONS;
  7421. if (!(vd.ulFlag1 & FLAG1_NO_STATUS_BAR))
  7422. dwToolbars |= STATUS_BAR;
  7423. // display the status bar appropriately
  7424. if (StatusBarOf (m_ViewData.m_dwToolbarsDisplayed) != StatusBarOf (dwToolbars))
  7425. {
  7426. CChildFrame* pFrame = GetParentFrame ();
  7427. if (pFrame != NULL)
  7428. {
  7429. pFrame->ToggleStatusBar();
  7430. SetStatusBarVisible(!IsStatusBarVisible());
  7431. ASSERT (StatusBarOf (m_ViewData.m_dwToolbarsDisplayed) ==
  7432. StatusBarOf (dwToolbars));
  7433. }
  7434. }
  7435. // display the appropriate toolbars
  7436. if (ToolbarsOf (m_ViewData.m_dwToolbarsDisplayed) != ToolbarsOf (dwToolbars))
  7437. {
  7438. m_spNodeCallback->UpdateWindowLayout(
  7439. reinterpret_cast<LONG_PTR>(&m_ViewData), dwToolbars);
  7440. ASSERT (ToolbarsOf (m_ViewData.m_dwToolbarsDisplayed) ==
  7441. ToolbarsOf (dwToolbars));
  7442. }
  7443. // Update the status of MMC menus.
  7444. sc = ScUpdateMMCMenus();
  7445. if (sc)
  7446. sc.Throw();
  7447. SetDirty (false);
  7448. m_pHistoryList->Clear();
  7449. }
  7450. SaveStartingSelectedNode();
  7451. if (persistor.IsLoading())
  7452. {
  7453. SC sc;
  7454. IScopeTree* const pScopeTree = GetScopeTreePtr();
  7455. if(!pScopeTree)
  7456. {
  7457. sc = E_UNEXPECTED;
  7458. return;
  7459. }
  7460. MTNODEID idTemp = 0;
  7461. bool bExactMatchFound = false; // out value from GetNodeIDFromBookmark, unused
  7462. sc = pScopeTree->GetNodeIDFromBookmark(bms, &idTemp, bExactMatchFound);
  7463. if(sc)
  7464. return;
  7465. sc = ScSelectNode(idTemp);
  7466. if(sc)
  7467. return;
  7468. }
  7469. // if we've stored everything -we're clean
  7470. if (persistor.IsStoring())
  7471. SetDirty (false);
  7472. }
  7473. bool CAMCView::Load(IStream& stream)
  7474. // Caller is responsible for notifying user if false is returned
  7475. {
  7476. TRACE_METHOD(CAMCView, Load);
  7477. SetDirty (false);
  7478. // Read the view data from the stream.
  7479. ASSERT(&stream);
  7480. if (!&stream)
  7481. return false;
  7482. PersistedViewData pvd;
  7483. unsigned long bytesRead;
  7484. HRESULT hr = stream.Read(&pvd, sizeof(pvd), &bytesRead);
  7485. ASSERT(SUCCEEDED(hr) && bytesRead == sizeof(pvd));
  7486. if (FAILED(hr))
  7487. return false;
  7488. ASSERT(int(m_nViewID) == pvd.viewID);
  7489. m_ViewData.m_nViewID = m_nViewID = pvd.viewID;
  7490. if (int(m_nViewID) >= static_nViewID)
  7491. static_nViewID = m_nViewID + 1;
  7492. //SetDefaultColumnWidths(pvd.defaultColumnWidth);
  7493. SetDescBarVisible(pvd.descriptionBarVisible);
  7494. // Get the parent frame
  7495. CWnd* const pParent = GetParent();
  7496. ASSERT(pParent != NULL);
  7497. if (pParent == NULL)
  7498. return false;
  7499. // we shouldn't restore maximized window position
  7500. // since it may not be proper one for the current resolution
  7501. // related to bug #404118
  7502. WINDOWPLACEMENT orgPlacement;
  7503. ZeroMemory(&orgPlacement,sizeof(orgPlacement));
  7504. orgPlacement.length = sizeof(orgPlacement);
  7505. if (pParent->GetWindowPlacement(&orgPlacement))
  7506. {
  7507. pvd.windowPlacement.ptMaxPosition = orgPlacement.ptMaxPosition;
  7508. }
  7509. // Set the location and size of the frame
  7510. const BOOL bPlaced = pParent->SetWindowPlacement(&pvd.windowPlacement);
  7511. ASSERT(bPlaced != FALSE);
  7512. if (bPlaced == FALSE)
  7513. return false;
  7514. // Restore window settings
  7515. if (pvd.ulFlag1 & FLAG1_DISABLE_SCOPEPANE)
  7516. m_ViewData.m_lWindowOptions |= MMC_NW_OPTION_NOSCOPEPANE;
  7517. if (pvd.ulFlag1 & FLAG1_DISABLE_STD_TOOLBARS)
  7518. m_ViewData.m_lWindowOptions |= MMC_NW_OPTION_NOTOOLBARS;
  7519. if (pvd.ulFlag1 & FLAG1_CUSTOM_TITLE)
  7520. m_ViewData.m_lWindowOptions |= MMC_NW_OPTION_CUSTOMTITLE;
  7521. SetAuthorModeView (!(pvd.ulFlag1 & FLAG1_CREATED_IN_USER_MODE));
  7522. if ((pvd.ulFlag1 & FLAG1_NO_TASKPAD_TABS))
  7523. SetTaskpadTabsAllowed(FALSE);
  7524. // Restore scope pane settings
  7525. SetPaneInfo(ePane_ScopeTree, pvd.scope.ideal, pvd.scope.min);
  7526. // The FLAG1_NO_TREE_ALLOWED is used only for compatibility with MMC1.2 console files
  7527. // It is a relic from old console files that does not exist in MMC2.0 console files.
  7528. bool bScopeTreeNotAllowed = (pvd.ulFlag1 & FLAG1_NO_TREE_ALLOWED);
  7529. SC sc;
  7530. if ( (IsScopePaneAllowed()) && (! bScopeTreeNotAllowed) )
  7531. sc = ScShowScopePane ((pvd.ulFlag1 & FLAG1_SCOPE_PANE_VISIBLE) != 0);
  7532. else
  7533. sc = ScShowScopePane (false);
  7534. if (sc)
  7535. return (false);
  7536. // Force layout re-calculation
  7537. DeferRecalcLayout();
  7538. // Restore view style & view mode if persisted will be set by nodemgr.
  7539. SetDefaultListViewStyle(pvd.listViewStyle);
  7540. DWORD dwToolbars = 0;
  7541. if (!(pvd.ulFlag1 & FLAG1_NO_STD_MENUS))
  7542. dwToolbars |= STD_MENUS;
  7543. if (!(pvd.ulFlag1 & FLAG1_NO_STD_BUTTONS))
  7544. dwToolbars |= STD_BUTTONS;
  7545. if (!(pvd.ulFlag1 & FLAG1_NO_SNAPIN_MENUS))
  7546. dwToolbars |= SNAPIN_MENUS;
  7547. if (!(pvd.ulFlag1 & FLAG1_NO_SNAPIN_BUTTONS))
  7548. dwToolbars |= SNAPIN_BUTTONS;
  7549. if (!(pvd.ulFlag1 & FLAG1_NO_STATUS_BAR))
  7550. dwToolbars |= STATUS_BAR;
  7551. // display the status bar appropriately
  7552. if (StatusBarOf (m_ViewData.m_dwToolbarsDisplayed) != StatusBarOf (dwToolbars))
  7553. {
  7554. CChildFrame* pFrame = GetParentFrame ();
  7555. if (pFrame != NULL)
  7556. {
  7557. pFrame->ToggleStatusBar();
  7558. SetStatusBarVisible(!IsStatusBarVisible());
  7559. ASSERT (StatusBarOf (m_ViewData.m_dwToolbarsDisplayed) ==
  7560. StatusBarOf (dwToolbars));
  7561. }
  7562. }
  7563. // display the appropriate toolbars
  7564. if (ToolbarsOf (m_ViewData.m_dwToolbarsDisplayed) != ToolbarsOf (dwToolbars))
  7565. {
  7566. m_spNodeCallback->UpdateWindowLayout(
  7567. reinterpret_cast<LONG_PTR>(&m_ViewData), dwToolbars);
  7568. ASSERT (ToolbarsOf (m_ViewData.m_dwToolbarsDisplayed) ==
  7569. ToolbarsOf (dwToolbars));
  7570. }
  7571. // Update the status of MMC menus.
  7572. sc = ScUpdateMMCMenus();
  7573. if (sc)
  7574. return false;
  7575. SetDirty (false);
  7576. m_pHistoryList->Clear();
  7577. return true;
  7578. }
  7579. //+-------------------------------------------------------------------
  7580. //
  7581. // Member: ScSpecialResultpaneSelectionActivate
  7582. //
  7583. // Synopsis: Only the list(/Web/OCX) or the tree can be "active" from the point
  7584. // of view of selected items and MMCN_SELECT. This is not
  7585. // the same as the MFC concept of "active view". There are a couple
  7586. // of views that cannot be active in this sense, such as the taskpad
  7587. // and tab views.
  7588. // When the active view (according to this definition) changes, this
  7589. // function is called. Thus, ScTreeViewSelectionActivate and
  7590. // ScListViewSelectionActivate/ScSpecialResultpaneSelectionActivate
  7591. // are always called in pairs when the activation changes, one to handle
  7592. // deactivation, and one to handle activation.
  7593. //
  7594. // Consider the following scenario
  7595. // 1) The tree view has (MFC/windows style) focus.
  7596. // 2) The user clicks on the taskpad view
  7597. // Result - selection activation does not change from the tree. All verbs
  7598. // still correspond to the selected tree item.
  7599. // 3) The user clicks on the folder view
  7600. // Result - once again, selection activation does not chang
  7601. // 4) The user clicks on one of the result views eg the list
  7602. // Result - ScTreeViewSelectionActivate(false) and ScListViewSelectionActivate(true)
  7603. // Thus verbs and the toolbar now correspond to the selected list item(s).
  7604. // 5) The user clicks on the taskpad view.
  7605. // Result - as in step 2, nothing happens
  7606. // 6) The user clicks on the result view
  7607. // Result - because the active view has not changed, nothing happens.
  7608. //
  7609. // Arguments: [bActivate] - special result pane is selected/de-selected.
  7610. //
  7611. // Returns: SC
  7612. //
  7613. //--------------------------------------------------------------------
  7614. SC CAMCView::ScSpecialResultpaneSelectionActivate(bool bActivate)
  7615. {
  7616. DECLARE_SC(sc, TEXT("CAMCView::ScSpecialResultpaneSelectionActivate"));
  7617. /*
  7618. * Bug 331904: prevent recursion
  7619. */
  7620. if (m_fActivatingSpecialResultPane)
  7621. {
  7622. TRACE (_T("CAMCView:ScSpecialResultpaneSelectionActivate: shorting out of recursion\n"));
  7623. return sc;
  7624. }
  7625. do
  7626. {
  7627. m_fActivatingSpecialResultPane = true;
  7628. HNODE hNode = GetSelectedNode();
  7629. SELECTIONINFO selInfo;
  7630. ZeroMemory(&selInfo, sizeof(selInfo));
  7631. selInfo.m_bScope = FALSE;
  7632. selInfo.m_bDueToFocusChange = TRUE;
  7633. selInfo.m_bBackground = FALSE;
  7634. INodeCallback* pNodeCallBack = GetNodeCallback();
  7635. if (HasOCX())
  7636. {
  7637. selInfo.m_bResultPaneIsOCX = TRUE;
  7638. selInfo.m_lCookie = LVDATA_CUSTOMOCX;
  7639. }
  7640. else if (HasWebBrowser())
  7641. {
  7642. selInfo.m_bResultPaneIsWeb = TRUE;
  7643. selInfo.m_lCookie = LVDATA_CUSTOMWEB;
  7644. }
  7645. else
  7646. {
  7647. // Dont do anything. Just return.
  7648. m_fActivatingSpecialResultPane = false;
  7649. return sc;
  7650. }
  7651. sc = ScNotifySelect (pNodeCallBack, hNode, false /*fMultiSelect*/, bActivate, &selInfo);
  7652. if (sc)
  7653. sc.TraceAndClear(); // ignore & continue;
  7654. } while ( FALSE );
  7655. m_fActivatingSpecialResultPane = false;
  7656. return sc;
  7657. }
  7658. void CAMCView::CloseView()
  7659. {
  7660. DECLARE_SC(sc, TEXT("CAMCView::CloseView"));
  7661. TRACE_METHOD(CAMCView, CloseView);
  7662. // fire event to script
  7663. // this needs to be done while view is still 'alive'
  7664. sc = ScFireEvent(CAMCViewObserver::ScOnCloseView, this);
  7665. if (sc)
  7666. sc.TraceAndClear();
  7667. IScopeTree* const pScopeTree = GetScopeTreePtr();
  7668. ASSERT(pScopeTree != NULL);
  7669. if (pScopeTree != NULL)
  7670. {
  7671. HRESULT hr = pScopeTree->CloseView(m_nViewID);
  7672. ASSERT(hr == S_OK);
  7673. }
  7674. }
  7675. void CAMCView::OnDestroy()
  7676. {
  7677. TRACE_METHOD(CAMCView, OnDestroy);
  7678. // send the view destroy notification to all observers.
  7679. SC sc;
  7680. sc = ScFireEvent(CAMCViewObserver::ScOnViewDestroyed, this);
  7681. if(sc)
  7682. sc.TraceAndClear();
  7683. if (IsPersisted())
  7684. {
  7685. if(m_pDocument != NULL)
  7686. m_pDocument->SetModifiedFlag(TRUE);
  7687. SetDirty();
  7688. }
  7689. CDocument* pDoc = GetDocument();
  7690. ASSERT(pDoc != NULL);
  7691. // if we were in ListPad-mode....
  7692. // this must be detached before destroying the Scopetree,
  7693. // because we need to send a notify to the snapin,
  7694. // which we get from the hnode.
  7695. if (m_pListCtrl->IsListPad())
  7696. {
  7697. sc = m_pListCtrl->ScAttachToListPad (NULL, NULL);
  7698. if(sc)
  7699. sc.TraceAndClear();
  7700. }
  7701. // make sure to stop running scripts if we have a web browser
  7702. if( HasWebBrowser() )
  7703. {
  7704. ASSERT( m_pWebViewCtrl != NULL );
  7705. if ( m_pWebViewCtrl != NULL )
  7706. {
  7707. m_pWebViewCtrl->DestroyWindow();
  7708. m_pWebViewCtrl = NULL;
  7709. }
  7710. }
  7711. // make sure to stop running scripts if we have a view extension
  7712. if ( m_fViewExtended )
  7713. {
  7714. ASSERT( m_pViewExtensionCtrl != NULL );
  7715. if ( m_pViewExtensionCtrl != NULL )
  7716. {
  7717. m_pViewExtensionCtrl->DestroyWindow();
  7718. m_pViewExtensionCtrl = NULL;
  7719. }
  7720. }
  7721. if (m_pTreeCtrl != NULL)
  7722. {
  7723. HNODE hNode = GetSelectedNode();
  7724. if (hNode)
  7725. m_pTreeCtrl->OnDeSelectNode(hNode);
  7726. m_pTreeCtrl->DeleteScopeTree();
  7727. }
  7728. IScopeTree* const pScopeTree = GetScopeTreePtr();
  7729. ASSERT(pScopeTree != NULL);
  7730. if (pScopeTree != NULL)
  7731. {
  7732. HRESULT hr = pScopeTree->DeleteView(m_nViewID);
  7733. ASSERT(hr == S_OK);
  7734. }
  7735. CView::OnDestroy();
  7736. }
  7737. void CAMCView::OnUpdateFileSnapinmanager(CCmdUI* pCmdUI)
  7738. {
  7739. pCmdUI->Enable ();
  7740. }
  7741. void CAMCView::OnSize(UINT nType, int cx, int cy)
  7742. {
  7743. TRACE_METHOD(CAMCView, OnSize);
  7744. CView::OnSize(nType, cx, cy);
  7745. if (nType != SIZE_MINIMIZED)
  7746. RecalcLayout();
  7747. }
  7748. SC CAMCView::ScToggleDescriptionBar()
  7749. {
  7750. TRACE_METHOD(CAMCView, ScToggleDescriptionBar);
  7751. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7752. SetDescBarVisible (!IsDescBarVisible());
  7753. SetDirty();
  7754. /*
  7755. * Don't defer this layout. This may be called by the Customize View
  7756. * dialog which wants to see its updates in real time. It will be
  7757. * sitting in a modal message loop so we won't get a chance to precess
  7758. * our idle task.
  7759. */
  7760. RecalcLayout();
  7761. return (S_OK);
  7762. }
  7763. SC CAMCView::ScToggleStatusBar()
  7764. {
  7765. TRACE_METHOD(CAMCView, ScToggleStatusBar);
  7766. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7767. DECLARE_SC (sc, _T("CAMCView::ScToggleStatusBar"));
  7768. CChildFrame* pFrame = GetParentFrame();
  7769. sc = ScCheckPointers (pFrame, E_UNEXPECTED);
  7770. if (sc)
  7771. return (sc);
  7772. pFrame->ToggleStatusBar();
  7773. SetStatusBarVisible (!IsStatusBarVisible());
  7774. SetDirty();
  7775. return (sc);
  7776. }
  7777. SC CAMCView::ScToggleTaskpadTabs()
  7778. {
  7779. TRACE_METHOD(CAMCView, ScToggleTaskpadTabs);
  7780. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7781. SetTaskpadTabsAllowed (!AreTaskpadTabsAllowed());
  7782. SetDirty();
  7783. /*
  7784. * Don't defer this layout. This message will be sent by the
  7785. * Customize View dialog which wants to see its updates in
  7786. * real time. It will be sitting in a modal message loop so
  7787. * we won't get a chance to precess our idle task.
  7788. */
  7789. RecalcLayout();
  7790. return (S_OK);
  7791. }
  7792. SC CAMCView::ScToggleScopePane()
  7793. {
  7794. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7795. DECLARE_SC (sc, _T("CAMCView::ScToggleScopePane"));
  7796. sc = ScShowScopePane (!IsScopePaneVisible());
  7797. if (sc)
  7798. return (sc);
  7799. return (sc);
  7800. }
  7801. void CAMCView::OnActionMenu(CPoint point, LPCRECT prcExclude)
  7802. {
  7803. TRACE_METHOD(CAMCView, OnActionMenu);
  7804. UINT fHitTestFlags = 0;
  7805. HTREEITEM hTreeItem = m_pTreeCtrl->GetSelectedItem( );
  7806. ASSERT_VALID (this);
  7807. /*
  7808. * BUG: 99643
  7809. * Right now there is inconsistency between what you get by action menu & right click
  7810. * on a location in taskpad. The action menu always assumes it is tree or if result
  7811. * pane it is list or ocx or web or background. So if a taskpad is selected it assumes
  7812. * the corresponding list item is selected or tree item is selected or background.
  7813. * But right click on taskpad calls CAMCView::OnContextMenu which determines nothing
  7814. * is selected and does nothing. This needs to be addressed.
  7815. */
  7816. ASSERT(eActivePaneNone != m_eCurrentActivePane);
  7817. if (eActivePaneScope == m_eCurrentActivePane)
  7818. {
  7819. if (hTreeItem != NULL)
  7820. {
  7821. HNODE hNode = (HNODE)m_pTreeCtrl->GetItemData(hTreeItem);
  7822. OnContextMenuForTreeItem(INDEX_INVALID, hNode, point, CCT_SCOPE, hTreeItem, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7823. }
  7824. else
  7825. {
  7826. OnContextMenuForTreeBackground(point, prcExclude, false/*bAllowDefaultItem*/);
  7827. }
  7828. }
  7829. else
  7830. {
  7831. if (HasListOrListPad())
  7832. {
  7833. int cSel = m_pListCtrl->GetSelectedCount();
  7834. int nIndex = -1;
  7835. LPARAM lvData = LVDATA_ERROR;
  7836. if (cSel == 0)
  7837. lvData = LVDATA_BACKGROUND;
  7838. else if (cSel == 1)
  7839. nIndex = _GetLVSelectedItemData(&lvData);
  7840. else if (cSel > 1)
  7841. lvData = LVDATA_MULTISELECT;
  7842. ASSERT(lvData != LVDATA_ERROR);
  7843. if (lvData == LVDATA_ERROR)
  7844. return;
  7845. if (lvData == LVDATA_BACKGROUND)
  7846. {
  7847. // Find out which pane has focus to set the CMINFO_DO_SCOPEPANE_MENU flag.
  7848. HNODE hNode = GetSelectedNode();
  7849. DATA_OBJECT_TYPES ePaneType = (GetParentFrame()->GetActiveView() == m_pTreeCtrl) ? CCT_SCOPE : CCT_RESULT;
  7850. OnContextMenuForTreeItem(INDEX_BACKGROUND, hNode, point, ePaneType, hTreeItem, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7851. return;
  7852. }
  7853. else if (lvData == LVDATA_MULTISELECT)
  7854. {
  7855. OnContextMenuForListItem(INDEX_MULTISELECTION, NULL, point, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7856. }
  7857. else
  7858. {
  7859. if (IsVirtualList())
  7860. {
  7861. OnContextMenuForListItem(nIndex, (HRESULTITEM)NULL, point, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7862. }
  7863. else
  7864. {
  7865. CResultItem* pri = CResultItem::FromHandle (lvData);
  7866. if (pri != NULL)
  7867. {
  7868. if (pri->IsScopeItem())
  7869. OnContextMenuForTreeItem(nIndex, pri->GetScopeNode(), point, CCT_RESULT, NULL, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7870. else
  7871. OnContextMenuForListItem(nIndex, lvData, point, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7872. }
  7873. }
  7874. }
  7875. }
  7876. else
  7877. {
  7878. // The active window may be a web page or task pad or ocx.
  7879. LPARAM lvData = LVDATA_ERROR;
  7880. if (HasOCX())
  7881. {
  7882. lvData = LVDATA_CUSTOMOCX;
  7883. OnContextMenuForListItem(INDEX_OCXPANE, (HRESULTITEM)lvData, point, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7884. }
  7885. else if (HasWebBrowser())
  7886. {
  7887. lvData = LVDATA_CUSTOMWEB;
  7888. OnContextMenuForListItem(INDEX_WEBPANE, (HRESULTITEM)lvData, point, MMC_CONTEXT_MENU_ACTION, prcExclude, false/*bAllowDefaultItem*/);
  7889. }
  7890. else
  7891. {
  7892. // Some unknown window has the focus.
  7893. ASSERT(FALSE && "Unknown window has the focus");
  7894. }
  7895. }
  7896. }
  7897. }
  7898. SC CAMCView::ScUpOneLevel()
  7899. {
  7900. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7901. TRACE_METHOD(CAMCView, ScUpOneLevel);
  7902. DECLARE_SC (sc, _T("CAMCView::ScUpOneLevel"));
  7903. sc = E_FAIL;
  7904. if (m_pTreeCtrl)
  7905. {
  7906. HTREEITEM htiParent = m_pTreeCtrl->GetParentItem (m_pTreeCtrl->GetSelectedItem());
  7907. if (htiParent)
  7908. {
  7909. m_pTreeCtrl->SelectItem(htiParent);
  7910. m_pTreeCtrl->EnsureVisible(htiParent);
  7911. sc = S_OK;
  7912. }
  7913. }
  7914. return (sc);
  7915. }
  7916. void CAMCView::OnViewMenu(CPoint point, LPCRECT prcExclude)
  7917. {
  7918. TRACE_METHOD(CAMCView, OnViewMenu);
  7919. OnContextMenuForListItem (INDEX_BACKGROUND, NULL, point,
  7920. MMC_CONTEXT_MENU_VIEW, prcExclude,
  7921. false /*bAllowDefaultItem*/);
  7922. }
  7923. void CAMCView::OnDrawClipboard()
  7924. {
  7925. if (m_htiCut)
  7926. {
  7927. m_pTreeCtrl->SetItemState(m_htiCut, 0, TVIS_CUT);
  7928. }
  7929. else
  7930. {
  7931. m_pListCtrl->CutSelectedItems(FALSE);
  7932. }
  7933. }
  7934. /*+-------------------------------------------------------------------------*
  7935. *
  7936. * CAMCView::OnSettingChange
  7937. *
  7938. * PURPOSE: Handles WM_SETTINGCHANGE. Recalculates the layout. The
  7939. * result folder tab control needs this, for instance.
  7940. *
  7941. * PARAMETERS:
  7942. * UINT uFlags :
  7943. * LPCTSTR lpszSection :
  7944. *
  7945. * RETURNS:
  7946. * void
  7947. *
  7948. *+-------------------------------------------------------------------------*/
  7949. void
  7950. CAMCView::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  7951. {
  7952. DeferRecalcLayout();
  7953. }
  7954. void CAMCView::OnUpdatePasteBtn()
  7955. {
  7956. DECLARE_SC(sc, TEXT("CAMCView::OnUpdatePasteBtn"));
  7957. HNODE hNode = NULL;
  7958. LPARAM lvData = NULL;
  7959. bool bScope = FALSE;
  7960. sc = ScGetFocusedItem(hNode, lvData, bScope);
  7961. if (sc)
  7962. return;
  7963. INodeCallback* pNC = GetNodeCallback();
  7964. sc = ScCheckPointers(hNode, pNC, E_UNEXPECTED);
  7965. if (sc)
  7966. return;
  7967. sc = pNC->UpdatePasteButton(hNode, bScope, lvData);
  7968. if (sc)
  7969. return;
  7970. return;
  7971. }
  7972. void CAMCView::OnContextHelp()
  7973. {
  7974. ScContextHelp();
  7975. }
  7976. SC CAMCView::ScContextHelp ()
  7977. {
  7978. AFX_MANAGE_STATE (AfxGetAppModuleState());
  7979. m_fSnapinDisplayedHelp = false;
  7980. SC sc = SendGenericNotify(NCLBK_CONTEXTHELP);
  7981. // if snap-in hasn't called us to display a topic
  7982. // and it has not handled the notification then
  7983. // display MMC topic by default
  7984. if (!m_fSnapinDisplayedHelp && (sc.ToHr() != S_OK))
  7985. sc = ScHelpTopics ();
  7986. if (sc)
  7987. TraceError (_T("CAMCView::ScContextHelp"), sc);
  7988. return (sc);
  7989. }
  7990. void CAMCView::OnSnapInHelp()
  7991. {
  7992. SendGenericNotify(NCLBK_SNAPINHELP);
  7993. }
  7994. void CAMCView::OnSnapinAbout()
  7995. {
  7996. DECLARE_SC(sc, TEXT("CAMCView::OnSnapinAbout"));
  7997. HNODE hNode = GetSelectedNode();
  7998. sc = ScCheckPointers((void*) hNode, E_UNEXPECTED);
  7999. if (sc)
  8000. return;
  8001. INodeCallback *pNC = GetNodeCallback();
  8002. sc = ScCheckPointers(pNC, E_UNEXPECTED);
  8003. if (sc)
  8004. return;
  8005. sc = pNC->ShowAboutInformation(hNode);
  8006. if (sc)
  8007. return;
  8008. return;
  8009. }
  8010. void CAMCView::OnHelpTopics()
  8011. {
  8012. ScHelpTopics();
  8013. }
  8014. SC CAMCView::ScHelpWorker (LPCTSTR pszHelpTopic)
  8015. {
  8016. DECLARE_SC (sc, _T("CAMCView::ScShowSnapinHelpTopic"));
  8017. USES_CONVERSION;
  8018. /*
  8019. * generation of the help collection might take a while, so display
  8020. * a wait cursor
  8021. */
  8022. CWaitCursor wait;
  8023. INodeCallback* pNC = GetNodeCallback();
  8024. ASSERT(pNC != NULL);
  8025. CAMCDoc* pdoc = GetDocument();
  8026. // Point helpdoc info to current console file path
  8027. if (pdoc->GetPathName().IsEmpty())
  8028. pdoc->GetHelpDocInfo()->m_pszFileName = NULL;
  8029. else
  8030. pdoc->GetHelpDocInfo()->m_pszFileName = T2COLE(pdoc->GetPathName());
  8031. /*
  8032. * smart pointer for automatic deletion of the help file name
  8033. */
  8034. CCoTaskMemPtr<WCHAR> spszHelpFile;
  8035. sc = pNC->Notify (0, NCLBK_GETHELPDOC,
  8036. reinterpret_cast<LPARAM>(pdoc->GetHelpDocInfo()),
  8037. reinterpret_cast<LPARAM>(&spszHelpFile));
  8038. if (sc)
  8039. return (sc);
  8040. CAMCApp* pAMCApp = AMCGetApp();
  8041. if (NULL == pAMCApp)
  8042. return (sc = E_UNEXPECTED);
  8043. sc = pAMCApp->ScShowHtmlHelp(W2T(spszHelpFile), (DWORD_PTR) pszHelpTopic);
  8044. return (sc);
  8045. }
  8046. SC CAMCView::ScHelpTopics ()
  8047. {
  8048. AFX_MANAGE_STATE (AfxGetAppModuleState());
  8049. return (ScHelpWorker (NULL));
  8050. }
  8051. SC CAMCView::ScShowSnapinHelpTopic (LPCTSTR pszHelpTopic)
  8052. {
  8053. AFX_MANAGE_STATE (AfxGetAppModuleState());
  8054. CString strTopicPath;
  8055. // Add protocol prefix to topic string
  8056. if (pszHelpTopic != NULL)
  8057. {
  8058. strTopicPath = _T("ms-its:");
  8059. strTopicPath += pszHelpTopic;
  8060. }
  8061. SC sc = ScHelpWorker (strTopicPath);
  8062. if (!sc)
  8063. m_fSnapinDisplayedHelp = true;
  8064. return (sc);
  8065. }
  8066. //+-------------------------------------------------------------------
  8067. //
  8068. // Member: CAMCView::UpdateSnapInHelpMenus
  8069. //
  8070. // Synopsis: Update the following Help menu items
  8071. // a) Help on <Snapin> (if snapin does not support HTML help)
  8072. // b) About <Snapin> (if snapin supports about object)
  8073. //
  8074. // Arguments: [pMenu] - The help popup menu.
  8075. //
  8076. //--------------------------------------------------------------------
  8077. void CAMCView::UpdateSnapInHelpMenus(CMenu* pMenu)
  8078. {
  8079. DECLARE_SC(sc, TEXT("CAMCView::UpdateSnapInHelpMenus"));
  8080. sc = ScCheckPointers(pMenu);
  8081. if (sc)
  8082. return;
  8083. ASSERT_VALID (this);
  8084. HNODE hNode = GetSelectedNode();
  8085. INodeCallback* pNC = GetNodeCallback();
  8086. sc = ScCheckPointers(hNode, pNC, E_UNEXPECTED);
  8087. if (sc)
  8088. goto Error;
  8089. // Empty block for goto's
  8090. {
  8091. // First Make sure this is not a dummy substitute snapin.
  8092. bool bDummySnapin = false;
  8093. sc = pNC->IsDummySnapin (hNode, bDummySnapin);
  8094. if (sc)
  8095. goto Error;
  8096. if (bDummySnapin)
  8097. goto Error;
  8098. // Get the snapin name for "Help on <SnapinName>" or "About <SnapinName>" menus
  8099. CCoTaskMemPtr<WCHAR> spszName;
  8100. CString strMenu;
  8101. // Try to get name of snap-in for custom menu item
  8102. bool bSnapinNameValid = false;
  8103. sc = pNC->GetSnapinName(hNode, &spszName, bSnapinNameValid);
  8104. if (sc)
  8105. goto Error;
  8106. ASSERT( spszName != NULL || bSnapinNameValid );
  8107. USES_CONVERSION;
  8108. // if snapin supports html help, don't give it it's own help command
  8109. bool bStandardHelpExists = false;
  8110. sc = pNC->DoesStandardSnapinHelpExist(hNode, bStandardHelpExists);
  8111. if (sc)
  8112. goto Error;
  8113. if (bStandardHelpExists)
  8114. {
  8115. pMenu->DeleteMenu(ID_HELP_SNAPINHELP, MF_BYCOMMAND);
  8116. }
  8117. else
  8118. {
  8119. if (bSnapinNameValid)
  8120. {
  8121. // "Help on <SnapinName>"
  8122. LoadString(strMenu, IDS_HELP_ON);
  8123. AfxFormatString1(strMenu, IDS_HELP_ON, OLE2T(spszName));
  8124. }
  8125. else
  8126. {
  8127. // ""Help on Snap-in"
  8128. LoadString(strMenu, IDS_HELP_ON_SNAPIN);
  8129. }
  8130. // Either add or modify the custom help menu item
  8131. if (pMenu->GetMenuState(ID_HELP_SNAPINHELP, MF_BYCOMMAND) == (UINT)-1)
  8132. {
  8133. pMenu->InsertMenu(ID_HELP_HELPTOPICS, MF_BYCOMMAND|MF_ENABLED, ID_HELP_SNAPINHELP, strMenu);
  8134. }
  8135. else
  8136. {
  8137. pMenu->ModifyMenu(ID_HELP_SNAPINHELP, MF_BYCOMMAND|MF_ENABLED, ID_HELP_SNAPINHELP, strMenu);
  8138. }
  8139. }
  8140. /* Now add the About <Snapin> menu*/
  8141. bool bAboutExists = false;
  8142. SC scNoTrace = pNC->DoesAboutExist(hNode, &bAboutExists);
  8143. if ( (scNoTrace.IsError()) || (!bAboutExists) )
  8144. {
  8145. pMenu->DeleteMenu(ID_SNAPIN_ABOUT, MF_BYCOMMAND);
  8146. return;
  8147. }
  8148. if (bSnapinNameValid)
  8149. {
  8150. // "About on <SnapinName>"
  8151. AfxFormatString1(strMenu, IDS_ABOUT_ON, OLE2T(spszName));
  8152. }
  8153. else
  8154. {
  8155. // Cant get name just delete & return
  8156. pMenu->DeleteMenu(ID_SNAPIN_ABOUT, MF_BYCOMMAND);
  8157. return;
  8158. }
  8159. if (pMenu->GetMenuState(ID_SNAPIN_ABOUT, MF_BYCOMMAND) == (UINT)-1)
  8160. {
  8161. pMenu->InsertMenu(-1, MF_BYPOSITION|MF_ENABLED, ID_SNAPIN_ABOUT, strMenu);
  8162. }
  8163. else
  8164. {
  8165. pMenu->ModifyMenu(ID_SNAPIN_ABOUT, MF_BYCOMMAND|MF_ENABLED, ID_SNAPIN_ABOUT, strMenu);
  8166. }
  8167. }
  8168. Cleanup:
  8169. return;
  8170. Error:
  8171. pMenu->DeleteMenu(ID_HELP_SNAPINHELP, MF_BYCOMMAND);
  8172. pMenu->DeleteMenu(ID_SNAPIN_ABOUT, MF_BYCOMMAND);
  8173. goto Cleanup;
  8174. }
  8175. #ifdef IMPLEMENT_LIST_SAVE // See nodemgr.idl (t-dmarm)
  8176. /*
  8177. * Displays errors from the list save function and cleans up the file if necessary
  8178. */
  8179. void CAMCView::ListSaveErrorMes(EListSaveErrorType etype, HANDLE hfile, LPCTSTR lpFileName)
  8180. {
  8181. CString strMessage;
  8182. switch (etype)
  8183. {
  8184. case LSaveCantCreate:
  8185. //"ERROR: Unable to create file."
  8186. FormatString1 (strMessage, IDS_LISTSAVE_ER1, lpFileName);
  8187. break;
  8188. case LSaveCantWrite:
  8189. // ERROR: Created file but encountered an error while writing to it
  8190. FormatString1 (strMessage, IDS_LISTSAVE_ER2, lpFileName);
  8191. break;
  8192. case LSaveReadOnly:
  8193. //"ERROR: File to be overwritten is read only."
  8194. FormatString1 (strMessage, IDS_LISTSAVE_ER3, lpFileName);
  8195. break;
  8196. default:
  8197. // Should not make it here
  8198. ASSERT(0);
  8199. }
  8200. MMCMessageBox (strMessage);
  8201. }
  8202. // Saves a list and performs necessary dialog boxes and error checking
  8203. SC CAMCView::ScSaveList()
  8204. {
  8205. DECLARE_SC(sc, _T("ScSaveList"));
  8206. AFX_MANAGE_STATE (AfxGetAppModuleState());
  8207. sc = ScExportListWorker();
  8208. return (sc);
  8209. }
  8210. //+-------------------------------------------------------------------
  8211. //
  8212. // Member: CAMCView::ScGetExportListFile
  8213. //
  8214. // Synopsis: Get the filename, flags for save list.
  8215. //
  8216. // Arguments: [strFileName] - File Name retval.
  8217. // [bUnicode] - Unicode or ansi.
  8218. // [bTabDelimited] - Tab or Comma delimited.
  8219. // [bSelectedRowsOnly] - selected items only or all items.
  8220. //
  8221. // Returns: SC, S_FALSE if user cancels dialog.
  8222. //
  8223. //--------------------------------------------------------------------
  8224. SC CAMCView::ScGetExportListFile (CString& strFileName,
  8225. bool& bUnicode,
  8226. bool& bTabDelimited,
  8227. bool& bSelectedRowsOnly)
  8228. {
  8229. DECLARE_SC(sc, _T("CAMCView::ScGetExportListFile"));
  8230. CString strFilter;
  8231. LoadString(strFilter, IDS_ANSI_FILE_TYPE);
  8232. #ifdef UNICODE
  8233. { // limit the lifetime of strUniFilter
  8234. CString strUniFilter;
  8235. LoadString(strUniFilter, IDS_UNICODE_FILE_TYPE);
  8236. strFilter += strUniFilter;
  8237. }
  8238. #endif
  8239. // End of Filter char
  8240. strFilter += "|";
  8241. sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED);
  8242. if (sc)
  8243. return sc;
  8244. // See if there are any items selected else disable the "Selected items only" check-box.
  8245. CListCtrl& ctlList = m_pListCtrl->GetListCtrl();
  8246. int iItem = ctlList.GetNextItem( -1,LVNI_SELECTED);
  8247. bool bSomeRowSelected = (-1 != iItem);
  8248. // Create the dialog. File extensions are not localized.
  8249. CSaveFileDialog dlgFile(false, _T("txt"), NULL,
  8250. OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ENABLESIZING,
  8251. strFilter, bSomeRowSelected);
  8252. // Display the dialog
  8253. if (dlgFile.DoModal() == IDCANCEL)
  8254. return S_FALSE; // S_FALSE if user cancels dialog.
  8255. // Create a wait cursor and redraw the screen (necessary in saving big files)
  8256. CWaitCursor wait;
  8257. AfxGetMainWnd()->RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW );
  8258. // Retrieve the filename
  8259. strFileName = dlgFile.GetPathName();
  8260. bSelectedRowsOnly = (dlgFile.Getflags() & SELECTED);
  8261. switch (dlgFile.GetFileType())
  8262. {
  8263. case FILE_ANSI_TEXT:
  8264. bTabDelimited = true; // Tab delimited.
  8265. bUnicode = false;
  8266. break;
  8267. case FILE_ANSI_CSV:
  8268. bTabDelimited = false; // Comma delimited.
  8269. bUnicode = false;
  8270. break;
  8271. #ifdef UNICODE
  8272. case FILE_UNICODE_TEXT:
  8273. bTabDelimited = true; // tab delimited.
  8274. bUnicode = true;
  8275. break;
  8276. case FILE_UNICODE_CSV:
  8277. bTabDelimited = false; // comma delimited.
  8278. bUnicode = true;
  8279. break;
  8280. #endif
  8281. default:
  8282. sc = E_UNEXPECTED;
  8283. break;
  8284. }
  8285. return (sc);
  8286. }
  8287. //+-------------------------------------------------------------------
  8288. //
  8289. // Member: CAMCView::ScCreateExportListFile
  8290. //
  8291. // Synopsis: Create a file with given name & path. Write unicode marker if needed.
  8292. //
  8293. // Arguments: [strFileName] - file to create.
  8294. // [bUnicode] - unicode or ansi file.
  8295. // [bShowErrorDialogs] - Show error dialogs or not.
  8296. // [hFile] - Retval, handle to file.
  8297. //
  8298. // Returns: SC
  8299. //
  8300. //--------------------------------------------------------------------
  8301. SC CAMCView::ScCreateExportListFile(const CString& strFileName, bool bUnicode,
  8302. bool bShowErrorDialogs, HANDLE& hFile)
  8303. {
  8304. DECLARE_SC(sc, _T("CAMCView::ScCreateExportListFile"));
  8305. // Create a file according to specs
  8306. hFile = CreateFile(strFileName, GENERIC_WRITE,
  8307. 0, NULL, CREATE_ALWAYS,
  8308. FILE_ATTRIBUTE_NORMAL, NULL);
  8309. DWORD dwAttrib = GetFileAttributes(strFileName);
  8310. // If it did not fail and the file is read-only
  8311. // Not required. Used to determine if the file being overwritten is read only and display appropriate message
  8312. if ((dwAttrib != 0xFFFFFFFF) &&
  8313. (dwAttrib & FILE_ATTRIBUTE_READONLY))
  8314. {
  8315. if (bShowErrorDialogs)
  8316. ListSaveErrorMes(LSaveReadOnly, hFile, strFileName);
  8317. return (sc = E_FAIL);
  8318. }
  8319. // Creation failed
  8320. if (hFile == INVALID_HANDLE_VALUE)
  8321. {
  8322. if (bShowErrorDialogs)
  8323. ListSaveErrorMes(LSaveCantCreate, NULL, strFileName);
  8324. sc.FromWin32(::GetLastError());
  8325. return sc;
  8326. }
  8327. /*
  8328. * for Unicode files, write the Unicode prefix
  8329. */
  8330. if (bUnicode)
  8331. {
  8332. const WCHAR chPrefix = 0xFEFF;
  8333. const DWORD cbToWrite = sizeof (chPrefix);
  8334. DWORD cbWritten;
  8335. if (!WriteFile (hFile, &chPrefix, cbToWrite, &cbWritten, NULL) ||
  8336. (cbToWrite != cbWritten))
  8337. {
  8338. CloseHandle(hFile);
  8339. DeleteFile( strFileName );
  8340. if (bShowErrorDialogs)
  8341. ListSaveErrorMes(LSaveCantWrite, hFile, strFileName);
  8342. return (sc = E_FAIL);
  8343. }
  8344. }
  8345. return (sc);
  8346. }
  8347. //+-------------------------------------------------------------------
  8348. //
  8349. // Member: CAMCView::ScExportListWorker
  8350. //
  8351. // Synopsis: Prompt for a file name & write the ListView data to it.
  8352. //
  8353. // Returns: SC
  8354. //
  8355. //--------------------------------------------------------------------
  8356. SC CAMCView::ScExportListWorker()
  8357. {
  8358. DECLARE_SC(sc, _T("CAMCView::ScExportListWorker"));
  8359. CString strFileName;
  8360. bool bUnicode = false;
  8361. bool bTabDelimited = false;
  8362. bool bSelectedRowsOnly = false;
  8363. sc = ScGetExportListFile(strFileName, bUnicode, bTabDelimited, bSelectedRowsOnly);
  8364. if (sc.ToHr() == S_FALSE) // if user cancels dialog.
  8365. return sc;
  8366. sc = ScWriteExportListData(strFileName, bUnicode, bTabDelimited, bSelectedRowsOnly);
  8367. if (sc)
  8368. return sc;
  8369. return sc;
  8370. }
  8371. //+-------------------------------------------------------------------
  8372. //
  8373. // Member: CAMCView::ScWriteExportListData
  8374. //
  8375. // Synopsis: Write ListView data to given file.
  8376. //
  8377. // Arguments: [strFileName] - File to create & write to.
  8378. // [bUnicode] - Unicode or ansi.
  8379. // [bTabDelimited] - Tab or Comma separated values.
  8380. // [bSelectedRowsOnly] - like Selected rows only.
  8381. // [bShowErrorDialogs] - Show error dialogs or not.
  8382. //
  8383. // Returns: SC
  8384. //
  8385. //--------------------------------------------------------------------
  8386. SC CAMCView::ScWriteExportListData (const CString& strFileName,
  8387. bool bUnicode,
  8388. bool bTabDelimited,
  8389. bool bSelectedRowsOnly,
  8390. bool bShowErrorDialogs /*true*/)
  8391. {
  8392. DECLARE_SC(sc, _T("CAMCView::ScWriteExportListData"));
  8393. // Get number of rows and columns
  8394. const int cRows = m_pListCtrl->GetItemCount();
  8395. const int cCols = m_pListCtrl->GetColCount();
  8396. // If there are no columns inserted then there cannot be any
  8397. // items inserted into the listview. So error out.
  8398. if (cCols <= 0)
  8399. return (sc = E_UNEXPECTED);
  8400. HANDLE hFile = NULL;
  8401. sc = ScCreateExportListFile(strFileName, bUnicode, bShowErrorDialogs, hFile);
  8402. if (sc)
  8403. return sc;
  8404. // Retrieve the flags
  8405. CString strEol( _T("\r\n") );
  8406. LPCTSTR pszSeparator = _T("\t");
  8407. if (!bTabDelimited)
  8408. pszSeparator = _T(",");
  8409. // Determine how many columns must be printed
  8410. int printcols = 1;
  8411. struct ColInfo
  8412. {
  8413. CString strColName;
  8414. BOOL bHidden;
  8415. };
  8416. ColInfo* rgColumns = NULL;
  8417. int* pnColOrder = NULL;
  8418. // If it is LVS_REPORT, get the list of column names, order
  8419. // and hidden or not flag.
  8420. if ( (m_pListCtrl->GetViewMode() == LVS_REPORT) ||
  8421. (m_pListCtrl->GetViewMode() == MMCLV_VIEWSTYLE_FILTERED) )
  8422. {
  8423. printcols = cCols;
  8424. // Allocate mem to store col names, order, hidden states
  8425. rgColumns = new ColInfo[printcols];
  8426. if (! rgColumns)
  8427. {
  8428. sc = E_OUTOFMEMORY;
  8429. goto Error;
  8430. }
  8431. pnColOrder = new int[printcols];
  8432. if (! pnColOrder)
  8433. {
  8434. sc = E_OUTOFMEMORY;
  8435. goto Error;
  8436. }
  8437. CHeaderCtrl* pHeader = m_pListCtrl->GetHeaderCtrl();
  8438. sc = ScCheckPointers(pHeader, E_UNEXPECTED);
  8439. if (sc)
  8440. goto Error;
  8441. // Get the order
  8442. if (!Header_GetOrderArray(pHeader->GetSafeHwnd(), printcols, pnColOrder))
  8443. {
  8444. goto Error;
  8445. }
  8446. // Get the name and hidden state of cols
  8447. for (int i = 0; i < printcols ; i++)
  8448. {
  8449. TCHAR szColName[MAX_PATH * 2];
  8450. HDITEM hdItem;
  8451. hdItem.mask = HDI_TEXT | HDI_LPARAM;
  8452. hdItem.pszText = szColName;
  8453. hdItem.cchTextMax = countof (szColName);
  8454. if (pHeader->GetItem (i, &hdItem))
  8455. {
  8456. CHiddenColumnInfo hci (hdItem.lParam);
  8457. rgColumns[i].strColName = hdItem.pszText;
  8458. rgColumns[i].bHidden = hci.fHidden;
  8459. }
  8460. else
  8461. {
  8462. goto Error;
  8463. }
  8464. }
  8465. for (int i = 0; i < printcols ; i++)
  8466. {
  8467. // Print the column name according to the order
  8468. if (rgColumns[pnColOrder[i]].bHidden)
  8469. continue;
  8470. if ( (!Write2File(hFile, rgColumns[pnColOrder[i]].strColName, bUnicode)) ||
  8471. ((i < printcols - 1) && (!Write2File(hFile, pszSeparator, bUnicode))))
  8472. {
  8473. goto CantWriteError;
  8474. }
  8475. }
  8476. // Write an EOL character if necessary
  8477. if (!Write2File(hFile, strEol, bUnicode))
  8478. {
  8479. goto CantWriteError;
  8480. }
  8481. }
  8482. {
  8483. // Data for use in the writing stage
  8484. CString strData;
  8485. CListCtrl& ctlList = m_pListCtrl->GetListCtrl();
  8486. // Set iNextType to 0 if all items will be saved or LVNI_SELECTED if only selected ones will be saved
  8487. int iNextType = 0;
  8488. if (bSelectedRowsOnly)
  8489. iNextType = LVNI_SELECTED;
  8490. // Find the first item in the list
  8491. int iItem = ctlList.GetNextItem( -1,iNextType);
  8492. // Iterate until there are no more items to save
  8493. while (iItem != -1)
  8494. {
  8495. for(int ind2 = 0; ind2 < printcols ; ind2++)
  8496. {
  8497. if (rgColumns)
  8498. {
  8499. // If not hidden get the item
  8500. if (rgColumns[pnColOrder[ind2]].bHidden)
  8501. continue;
  8502. else
  8503. strData = ctlList.GetItemText( iItem, pnColOrder[ind2]);
  8504. }
  8505. else
  8506. strData = ctlList.GetItemText( iItem, ind2);
  8507. // Write the text and if necessary a comma
  8508. // If either one fails, then delete the file and return
  8509. if ( (!Write2File(hFile, strData, bUnicode)) ||
  8510. ((ind2 < printcols - 1) && (!Write2File(hFile, pszSeparator, bUnicode))))
  8511. {
  8512. goto CantWriteError;
  8513. }
  8514. }
  8515. // Write an EOL character if necessary
  8516. if (!Write2File(hFile, strEol, bUnicode))
  8517. {
  8518. goto CantWriteError;
  8519. }
  8520. // Find the next item to save
  8521. iItem = ctlList.GetNextItem( iItem, iNextType);
  8522. }
  8523. }
  8524. Cleanup:
  8525. if (rgColumns)
  8526. delete[] rgColumns;
  8527. if (pnColOrder)
  8528. delete[] pnColOrder;
  8529. CloseHandle(hFile);
  8530. return (sc);
  8531. CantWriteError:
  8532. if (bShowErrorDialogs)
  8533. ListSaveErrorMes(LSaveCantWrite, hFile, strFileName);
  8534. Error:
  8535. DeleteFile( strFileName );
  8536. goto Cleanup;
  8537. }
  8538. // Write out a string to the given file
  8539. // Used as a separate function to preserve memory
  8540. // Returns true if successful, false otherwise
  8541. bool CAMCView::Write2File(HANDLE hfile, LPCTSTR strwrite, BOOL fUnicode)
  8542. {
  8543. DECLARE_SC(sc, TEXT("CAMCView::Write2File"));
  8544. // parameter check;
  8545. sc = ScCheckPointers( strwrite );
  8546. if (sc)
  8547. return false;
  8548. // Initializes Macro
  8549. USES_CONVERSION;
  8550. // The number of bytes written
  8551. DWORD cbWritten;
  8552. DWORD cbToWrite;
  8553. if (fUnicode)
  8554. {
  8555. // Convert the string to Unicode and write it to hfile
  8556. LPCWSTR Ustring = T2CW( strwrite );
  8557. cbToWrite = wcslen (Ustring) * sizeof (WCHAR);
  8558. WriteFile(hfile, Ustring, cbToWrite, &cbWritten, NULL);
  8559. }
  8560. else
  8561. {
  8562. // Convert the string to ANSI and write it to hfile
  8563. const unsigned char* Astring = (const unsigned char*) T2CA( strwrite );
  8564. cbToWrite = _mbsnbcnt (Astring, _mbslen (Astring));
  8565. WriteFile(hfile, Astring, cbToWrite, &cbWritten, NULL);
  8566. }
  8567. // Make sure that the correct number of bytes were written
  8568. return (cbWritten == cbToWrite);
  8569. }
  8570. #endif // IMPLEMENT_LIST_SAVE See nodemgr.idl (t-dmarm)
  8571. // Refreshes all panes and HTML
  8572. void CAMCView::OnRefresh()
  8573. {
  8574. HWND hwnd = ::GetFocus();
  8575. if (IsVerbEnabled(MMC_VERB_REFRESH))
  8576. {
  8577. ScConsoleVerb(evRefresh);
  8578. }
  8579. else if (HasWebBrowser())
  8580. {
  8581. ScWebCommand(eWeb_Refresh);
  8582. }
  8583. ::SetFocus(hwnd);
  8584. }
  8585. void CAMCView::OnVerbAccelKey(UINT nID)
  8586. {
  8587. DECLARE_SC(sc, TEXT("CAMCView::OnVerbAccelKey"));
  8588. switch (nID)
  8589. {
  8590. case ID_MMC_CUT:
  8591. if (IsVerbEnabled(MMC_VERB_CUT))
  8592. sc = ScConsoleVerb(evCut);
  8593. break;
  8594. case ID_MMC_COPY:
  8595. if (IsVerbEnabled(MMC_VERB_COPY))
  8596. sc = ScConsoleVerb(evCopy);
  8597. break;
  8598. case ID_MMC_PASTE:
  8599. if (IsVerbEnabled(MMC_VERB_PASTE))
  8600. {
  8601. // Check if the dataobject in clipboard can be
  8602. // pasted into the selected node.
  8603. // Then only we send MMCN_PASTE notification to snapin.
  8604. HNODE hNode = NULL;
  8605. LPARAM lvData = NULL;
  8606. bool bScope = FALSE;
  8607. sc = ScGetFocusedItem(hNode, lvData, bScope);
  8608. if (sc)
  8609. break;
  8610. INodeCallback* pNC = GetNodeCallback();
  8611. sc = ScCheckPointers(pNC, hNode, E_UNEXPECTED);
  8612. if (sc)
  8613. break;
  8614. bool bPasteAllowed = false;
  8615. sc = pNC->QueryPasteFromClipboard(hNode, bScope, lvData, bPasteAllowed);
  8616. if (sc)
  8617. break;
  8618. if (bPasteAllowed)
  8619. sc = ScConsoleVerb(evPaste);
  8620. }
  8621. break;
  8622. case ID_MMC_PRINT:
  8623. if (IsVerbEnabled(MMC_VERB_PRINT))
  8624. sc = ScConsoleVerb(evPrint);
  8625. break;
  8626. case ID_MMC_RENAME:
  8627. if (IsVerbEnabled(MMC_VERB_RENAME))
  8628. sc = ScConsoleVerb(evRename);
  8629. break;
  8630. case ID_MMC_REFRESH:
  8631. OnRefresh();
  8632. break;
  8633. default:
  8634. ASSERT(FALSE);
  8635. }
  8636. if (sc)
  8637. return;
  8638. }
  8639. //
  8640. // Handle accelerator keys shared by result and scope panes
  8641. //
  8642. BOOL CAMCView::OnSharedKeyDown(WORD wVKey)
  8643. {
  8644. BOOL bReturn = TRUE;
  8645. if (::GetKeyState(VK_CONTROL) < 0)
  8646. {
  8647. switch (wVKey)
  8648. {
  8649. case 'C':
  8650. case 'c':
  8651. case VK_INSERT:
  8652. OnVerbAccelKey(ID_MMC_COPY); // Ctrl-C, Ctrl-Insert
  8653. break;
  8654. case 'V':
  8655. case 'v':
  8656. OnVerbAccelKey(ID_MMC_PASTE); // Ctrl-V
  8657. break;
  8658. case 'X':
  8659. case 'x':
  8660. OnVerbAccelKey(ID_MMC_CUT); // Ctrl-X
  8661. break;
  8662. default:
  8663. bReturn = FALSE;
  8664. }
  8665. }
  8666. else if (::GetKeyState(VK_SHIFT) < 0)
  8667. {
  8668. switch (wVKey)
  8669. {
  8670. case VK_DELETE:
  8671. OnVerbAccelKey(ID_MMC_CUT); // Shift-Delete
  8672. break;
  8673. case VK_INSERT:
  8674. OnVerbAccelKey(ID_MMC_PASTE); // Shift -Insert
  8675. break;
  8676. default:
  8677. bReturn = FALSE;
  8678. }
  8679. }
  8680. else
  8681. {
  8682. switch (wVKey)
  8683. {
  8684. case VK_F2:
  8685. OnVerbAccelKey(ID_MMC_RENAME); // F2
  8686. break;
  8687. default:
  8688. bReturn = FALSE;
  8689. }
  8690. }
  8691. return bReturn;
  8692. }
  8693. //+-------------------------------------------------------------------
  8694. //
  8695. // Member: ScConsoleVerb
  8696. //
  8697. // Synopsis: Execute the Console verb.
  8698. //
  8699. // Arguments: [nVerb] - The verb to be executed.
  8700. //
  8701. // Note: The verb is executed in the context of
  8702. // currently focused item (scope or result).
  8703. //
  8704. // Returns: SC
  8705. //
  8706. //--------------------------------------------------------------------
  8707. SC CAMCView::ScConsoleVerb (int nVerb)
  8708. {
  8709. AFX_MANAGE_STATE (AfxGetAppModuleState());
  8710. ASSERT_VALID (this);
  8711. DECLARE_SC (sc, _T("CAMCView::ScConsoleVerb"));
  8712. HNODE hNode = NULL;
  8713. LPARAM lvData = 0;
  8714. bool bScope = false;
  8715. // Get the focused item to process the console verb.
  8716. sc = ScGetFocusedItem(hNode, lvData, bScope);
  8717. if (sc)
  8718. return sc;
  8719. sc = ScProcessConsoleVerb(hNode, bScope, lvData, nVerb);
  8720. return (sc);
  8721. }
  8722. //+-------------------------------------------------------------------
  8723. //
  8724. // Member: ScProcessConsoleVerb
  8725. //
  8726. // Synopsis: Execute the Console verb with given context.
  8727. //
  8728. // Arguments: [hNode] - The tree node context.
  8729. // [bScope] - Scope or Result pane.
  8730. // [lvData] - LPARAM of result item (if result pane has focus).
  8731. // [nVerb] - The verb to be executed.
  8732. //
  8733. // Returns: SC
  8734. //
  8735. //--------------------------------------------------------------------
  8736. SC CAMCView::ScProcessConsoleVerb(HNODE hNode, bool bScope, LPARAM lvData, int nVerb)
  8737. {
  8738. DECLARE_SC (sc, _T("CAMCView::ScProcessConsoleVerb"));
  8739. AFX_MANAGE_STATE (AfxGetAppModuleState());
  8740. ASSERT_VALID (this);
  8741. // To maintain compatibility with MMC1.2 (This is init to LVERROR which
  8742. // nodemgr process differently).
  8743. if (bScope)
  8744. lvData = 0;
  8745. if (lvData == LVDATA_BACKGROUND)
  8746. {
  8747. switch (nVerb)
  8748. {
  8749. case evCut:
  8750. case evCopy:
  8751. case evDelete:
  8752. case evRename:
  8753. sc = E_UNEXPECTED;
  8754. return sc;
  8755. }
  8756. }
  8757. NCLBK_NOTIFY_TYPE nclbk = NCLBK_NONE;
  8758. switch (nVerb)
  8759. {
  8760. case evCut: nclbk = NCLBK_CUT; break;
  8761. case evCopy: nclbk = NCLBK_COPY; break;
  8762. case evDelete: nclbk = NCLBK_DELETE; break;
  8763. case evProperties: nclbk = NCLBK_PROPERTIES; break;
  8764. case evPrint: nclbk = NCLBK_PRINT; break;
  8765. case evPaste:
  8766. {
  8767. INodeCallback* pNC = GetNodeCallback();
  8768. sc = ScCheckPointers(pNC, E_UNEXPECTED);
  8769. if (sc)
  8770. return sc;
  8771. sc = pNC->Paste(hNode, bScope, lvData);
  8772. if (sc)
  8773. return sc;
  8774. sc = ScPaste ();
  8775. if (sc)
  8776. return sc;
  8777. break;
  8778. }
  8779. case evRefresh:
  8780. // if web page on view, send it a refresh first
  8781. if (HasWebBrowser())
  8782. sc = ScWebCommand(eWeb_Refresh);
  8783. if (sc)
  8784. return sc;
  8785. nclbk = NCLBK_REFRESH;
  8786. break;
  8787. case evRename:
  8788. // Enable edit for the item.
  8789. if (bScope == TRUE)
  8790. {
  8791. if (sc = ScCheckPointers(m_pTreeCtrl, E_UNEXPECTED))
  8792. return sc;
  8793. HTREEITEM hti = m_pTreeCtrl->GetSelectedItem();
  8794. if (sc = ScCheckPointers(hti, E_UNEXPECTED))
  8795. return sc;
  8796. m_pTreeCtrl->EditLabel(hti);
  8797. }
  8798. else
  8799. {
  8800. if ( sc = ScCheckPointers(m_pListCtrl, E_UNEXPECTED))
  8801. return sc;
  8802. CAMCListView* pListView = m_pListCtrl->GetListViewPtr();
  8803. if (NULL == pListView)
  8804. {
  8805. sc = E_UNEXPECTED;
  8806. return sc;
  8807. }
  8808. int iItem = _GetLVSelectedItemData(&lvData);
  8809. ASSERT(iItem >= 0);
  8810. CListCtrl& listCtrl = pListView->GetListCtrl();
  8811. listCtrl.EditLabel(iItem);
  8812. }
  8813. break;
  8814. default:
  8815. sc = E_UNEXPECTED;
  8816. return sc;
  8817. }
  8818. if (nclbk != NCLBK_NONE)
  8819. {
  8820. // Ask the nodemgr to process the verb.
  8821. INodeCallback* pNC = GetNodeCallback();
  8822. if (pNC == NULL)
  8823. {
  8824. sc = E_UNEXPECTED;
  8825. return sc;
  8826. }
  8827. sc = pNC->Notify(hNode, nclbk, bScope, lvData);
  8828. if (sc)
  8829. return sc;
  8830. }
  8831. if (nclbk == NCLBK_CUT)
  8832. sc = ScCut (bScope ? m_pTreeCtrl->GetSelectedItem() : 0);
  8833. if (sc)
  8834. return sc;
  8835. return (sc);
  8836. }
  8837. //+-------------------------------------------------------------------
  8838. //
  8839. // Member: CAMCView::ScListViewSelectionActivate
  8840. //
  8841. // Synopsis: Only the list(/Web/OCX) or the tree can be "active" from the point
  8842. // of view of selected items and MMCN_SELECT. This is not
  8843. // the same as the MFC concept of "active view". There are a couple
  8844. // of views that cannot be active in this sense, such as the taskpad
  8845. // and tab views.
  8846. // When the active view (according to this definition) changes, this
  8847. // function is called. Thus, ScTreeViewSelectionActivate and
  8848. // ScListViewSelectionActivate/ScSpecialResultpaneSelectionActivate
  8849. // are always called in pairs when the activation changes, one to handle
  8850. // deactivation, and one to handle activation.
  8851. //
  8852. // Consider the following scenario
  8853. // 1) The tree view has (MFC/windows style) focus.
  8854. // 2) The user clicks on the taskpad view
  8855. // Result - selection activation does not change from the tree. All verbs
  8856. // still correspond to the selected tree item.
  8857. // 3) The user clicks on the folder view
  8858. // Result - once again, selection activation does not chang
  8859. // 4) The user clicks on one of the result views eg the list
  8860. // Result - ScTreeViewSelectionActivate(false) and ScListViewSelectionActivate(true)
  8861. // Thus verbs and the toolbar now correspond to the selected list item(s).
  8862. // 5) The user clicks on the taskpad view.
  8863. // Result - as in step 2, nothing happens
  8864. // 6) The user clicks on the result view
  8865. // Result - because the active view has not changed, nothing happens.
  8866. //
  8867. // Arguments: [bActivate] - [in]
  8868. //
  8869. // Returns: SC
  8870. //
  8871. //--------------------------------------------------------------------
  8872. SC CAMCView::ScListViewSelectionActivate(bool bActivate)
  8873. {
  8874. DECLARE_SC(sc, TEXT("CAMCView::ScListViewSelectionActivate"));
  8875. if (m_pListCtrl == NULL)
  8876. return sc;
  8877. INodeCallback* pNC = GetNodeCallback();
  8878. sc = ScCheckPointers(pNC, E_UNEXPECTED);
  8879. if (sc)
  8880. {
  8881. sc.TraceAndClear();
  8882. return sc;
  8883. }
  8884. HNODE hNodeSel = GetSelectedNode();
  8885. SELECTIONINFO selInfo;
  8886. ZeroMemory(&selInfo, sizeof(selInfo));
  8887. selInfo.m_bScope = FALSE;
  8888. selInfo.m_bDueToFocusChange = TRUE;
  8889. #ifdef DBG
  8890. if (bActivate == TRUE)
  8891. {
  8892. ASSERT(m_bProcessMultiSelectionChanges == false);
  8893. }
  8894. #endif // DBG
  8895. /*
  8896. * The below block can never execute. When m_bProcessMultiSelectionChanges is
  8897. * set to true messages are posted to handle multiselection changes. So the
  8898. * handler OnProcessMultiSelectionChanges should have processed the message and the
  8899. * m_bProcessMultiSelectionChanges should have been reset by now. If there is
  8900. * some unknown way to make de-activate the listview before processing the message
  8901. * then below block will be executed that will send de-select notification.
  8902. *
  8903. * The below block sends a de-select multi-select items.
  8904. */
  8905. if (m_bProcessMultiSelectionChanges)
  8906. {
  8907. ASSERT(false); // Would like to know when this block is hit.
  8908. ASSERT(bActivate == false);
  8909. m_bProcessMultiSelectionChanges = false;
  8910. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, false, 0);
  8911. if (sc)
  8912. sc.TraceAndClear(); // ignore & continue;
  8913. // Focus change so appropriately enable std-toolbar buttons
  8914. // back, forward, export-list, up-one-level, show/hide-scope, help
  8915. sc = ScUpdateStandardbarMMCButtons();
  8916. if (sc)
  8917. sc.TraceAndClear();
  8918. }
  8919. bool bSelect = bActivate;
  8920. do
  8921. {
  8922. //
  8923. // Multi select
  8924. //
  8925. int cSelected = m_pListCtrl->GetSelectedCount();
  8926. if (cSelected > 1)
  8927. {
  8928. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, bSelect, 0);
  8929. if (sc)
  8930. sc.TraceAndClear(); // ignore & continue;
  8931. m_bLastSelWasMultiSel = bSelect;
  8932. break;
  8933. }
  8934. //
  8935. // Zero or Single select
  8936. //
  8937. if (cSelected == 0)
  8938. {
  8939. selInfo.m_bBackground = TRUE;
  8940. selInfo.m_lCookie = LVDATA_BACKGROUND;
  8941. }
  8942. else
  8943. {
  8944. #include "pushwarn.h"
  8945. #pragma warning(disable: 4552) // ">=" operator has no effect
  8946. VERIFY(_GetLVSelectedItemData(&selInfo.m_lCookie) >= 0);
  8947. #include "popwarn.h"
  8948. }
  8949. ASSERT(cSelected >= 0);
  8950. ASSERT(cSelected <= 1);
  8951. sc = ScNotifySelect (pNC, hNodeSel, false /*fMultiSelect*/, bSelect, &selInfo);
  8952. if (sc)
  8953. sc.TraceAndClear(); // ignore & continue;
  8954. } while (0);
  8955. return sc;
  8956. }
  8957. void CAMCView::OnShowWindow(BOOL bShow, UINT nStatus)
  8958. {
  8959. CView::OnShowWindow(bShow, nStatus);
  8960. }
  8961. int CAMCView::_GetLVItemData(LPARAM *plParam, UINT flags)
  8962. {
  8963. HWND hwnd = m_pListCtrl->GetListViewHWND();
  8964. int iItem = ::SendMessage(hwnd, LVM_GETNEXTITEM, (WPARAM) (int) -1,
  8965. MAKELPARAM(flags, 0));
  8966. if (iItem >= 0)
  8967. {
  8968. if (IsVirtualList())
  8969. {
  8970. *plParam = iItem;
  8971. }
  8972. else
  8973. {
  8974. LV_ITEM lvi;
  8975. ZeroMemory(&lvi, sizeof(lvi));
  8976. lvi.iItem = iItem;
  8977. lvi.mask = LVIF_PARAM;
  8978. #include "pushwarn.h"
  8979. #pragma warning(disable: 4553) // "==" operator has no effect
  8980. VERIFY(::SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM)&lvi) == TRUE);
  8981. #include "popwarn.h"
  8982. *plParam = lvi.lParam;
  8983. }
  8984. }
  8985. return iItem;
  8986. }
  8987. int CAMCView::_GetLVFocusedItemData(LPARAM *plParam)
  8988. {
  8989. return (_GetLVItemData (plParam, LVNI_FOCUSED));
  8990. }
  8991. int CAMCView::_GetLVSelectedItemData(LPARAM *plParam)
  8992. {
  8993. return (_GetLVItemData (plParam, LVNI_SELECTED));
  8994. }
  8995. void CAMCView::SetListViewMultiSelect(BOOL bMultiSelect)
  8996. {
  8997. long lStyle = m_pListCtrl->GetListStyle();
  8998. if (bMultiSelect == FALSE)
  8999. lStyle |= LVS_SINGLESEL;
  9000. else
  9001. lStyle &= ~LVS_SINGLESEL;
  9002. m_pListCtrl->SetListStyle(lStyle);
  9003. }
  9004. /*+-------------------------------------------------------------------------*
  9005. *
  9006. * CAMCView::ScOnItemDeselected
  9007. *
  9008. * PURPOSE: Tree observer method. Called when a tree item is deselected.
  9009. *
  9010. * PARAMETERS:
  9011. * HNODE hNode : The node that was deselected.
  9012. *
  9013. * NOTE: This function can be merged with the next.
  9014. *
  9015. * RETURNS:
  9016. * SC
  9017. *
  9018. *+-------------------------------------------------------------------------*/
  9019. SC
  9020. CAMCView::ScOnItemDeselected(HNODE hNode)
  9021. {
  9022. DECLARE_SC (sc, TEXT("CAMCView::ScOnItemDeselected"));
  9023. DeSelectResultPane(hNode);
  9024. if (!hNode)
  9025. return sc;
  9026. SELECTIONINFO selInfo;
  9027. ZeroMemory(&selInfo, sizeof(selInfo));
  9028. // Ask the SnapIn to cleanup any items it has inserted.
  9029. INodeCallback* spNodeCallBack = GetNodeCallback();
  9030. ASSERT(spNodeCallBack != NULL);
  9031. selInfo.m_bScope = TRUE;
  9032. selInfo.m_pView = NULL;
  9033. Dbg(DEB_USER6, _T("T1. CAMCTreeView::OnDeSelectNode<1, 0>\n"));
  9034. sc = ScNotifySelect (spNodeCallBack, hNode, false /*fMultiSelect*/, false, &selInfo);
  9035. if (sc)
  9036. sc.TraceAndClear(); // ignore & continue;
  9037. return sc;
  9038. }
  9039. /*+-------------------------------------------------------------------------*
  9040. *
  9041. * CAMCView::DeSelectResultPane
  9042. *
  9043. * PURPOSE: Deselects the result pane and sets the view type to invalid.
  9044. *
  9045. * PARAMETERS:
  9046. * HNODE hNodeSel :
  9047. *
  9048. * RETURNS:
  9049. * void
  9050. *
  9051. *+-------------------------------------------------------------------------*/
  9052. void
  9053. CAMCView::DeSelectResultPane(HNODE hNodeSel)
  9054. {
  9055. DECLARE_SC(sc, TEXT("CAMCView::DeSelectResultPane"));
  9056. if (m_spTaskPadHost.GetInterfacePtr() != NULL)
  9057. {
  9058. CTaskPadHost *pTaskPadHost = dynamic_cast<CTaskPadHost *>(m_spTaskPadHost.GetInterfacePtr());
  9059. m_spTaskPadHost = NULL;
  9060. }
  9061. INodeCallback* pNC = GetNodeCallback();
  9062. ASSERT(pNC != NULL);
  9063. if (hNodeSel == 0)
  9064. return;
  9065. // If there was no list view being displayed return.
  9066. if (HasListOrListPad())
  9067. {
  9068. // if we were in ListPad-mode, undo that.
  9069. if (m_pListCtrl->IsListPad())
  9070. {
  9071. sc = m_pListCtrl->ScAttachToListPad (NULL, NULL);
  9072. if(sc)
  9073. sc.TraceAndClear(); //ignore
  9074. }
  9075. // If we are in edit mode cancel it.
  9076. m_pListCtrl->GetListCtrl().EditLabel(-1);
  9077. SELECTIONINFO selInfo;
  9078. ZeroMemory(&selInfo, sizeof(selInfo));
  9079. selInfo.m_bScope = FALSE;
  9080. /*
  9081. * The below block can never execute. When m_bProcessMultiSelectionChanges is
  9082. * set to true messages are posted to handle multiselection changes. So the
  9083. * handler OnProcessMultiSelectionChanges should have processed the message and the
  9084. * m_bProcessMultiSelectionChanges should have been reset by now. If there is
  9085. * some unknown way to make select different node (to deselect result pane)
  9086. * before processing the message then below block will be executed that will
  9087. * send de-select notification.
  9088. *
  9089. * The below block sends a de-select multi-select items.
  9090. */
  9091. if (m_bProcessMultiSelectionChanges)
  9092. {
  9093. ASSERT(false); // Would like to know when this block is hit.
  9094. m_bProcessMultiSelectionChanges = false;
  9095. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, false, 0);
  9096. if (sc)
  9097. sc.TraceAndClear(); // ignore & continue;
  9098. }
  9099. else
  9100. {
  9101. UINT cSel = m_pListCtrl->GetSelectedCount();
  9102. if (cSel == 1)
  9103. {
  9104. if (cSel)
  9105. {
  9106. int iItem = _GetLVSelectedItemData(&selInfo.m_lCookie);
  9107. ASSERT(iItem != -1);
  9108. sc = ScNotifySelect (pNC, hNodeSel, false /*fMultiSelect*/, false, &selInfo);
  9109. if (sc)
  9110. sc.TraceAndClear(); // ignore & continue;
  9111. }
  9112. }
  9113. else if (cSel > 1)
  9114. {
  9115. sc = ScNotifySelect (pNC, hNodeSel, true /*fMultiSelect*/, false, 0);
  9116. if (sc)
  9117. sc.TraceAndClear(); // ignore & continue;
  9118. m_bLastSelWasMultiSel = false;
  9119. }
  9120. }
  9121. }
  9122. else
  9123. {
  9124. // If it is OCX or Web send de-select notifications.
  9125. sc = ScSpecialResultpaneSelectionActivate(FALSE);
  9126. }
  9127. }
  9128. LRESULT CAMCView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  9129. {
  9130. switch (message)
  9131. {
  9132. // NATHAN
  9133. case WM_NOTIFYFORMAT:
  9134. {
  9135. int id = ::GetDlgCtrlID ((HWND)wParam);
  9136. //if (m_pTreeCtrl == NULL || ((HWND)wParam != m_pTreeCtrl->m_hWnd))
  9137. if (id == IDC_ListView)
  9138. return NFR_UNICODE;
  9139. }
  9140. break;
  9141. #ifdef DBG
  9142. case WM_KEYUP:
  9143. {
  9144. switch (wParam)
  9145. {
  9146. case VK_SHIFT:
  9147. case VK_CONTROL:
  9148. // We removed some code that will work if m_bProcessMultiSelectionChanges
  9149. // is true. I dont see any way the bool being true. Still let us have below
  9150. // assert. If this gets fired then we should call OnProcessMultiSelectionChanges.
  9151. ASSERT(m_bProcessMultiSelectionChanges == false);
  9152. break;
  9153. }
  9154. break;
  9155. }
  9156. break;
  9157. #endif
  9158. }
  9159. return CView::WindowProc(message, wParam, lParam);
  9160. }
  9161. /*+-------------------------------------------------------------------------*
  9162. * CAMCView::ChangePane
  9163. *
  9164. * Moves the activation from pane to pane. The (forward) tab order is
  9165. *
  9166. * Scope pane (either tree or favorites)
  9167. * Result pane
  9168. * Task view (if visible)
  9169. *--------------------------------------------------------------------------*/
  9170. class CTabOrderEntry
  9171. {
  9172. public:
  9173. CView* const m_pView;
  9174. const bool m_bValid; // is this entry valid
  9175. CTabOrderEntry(CView *pView)
  9176. : m_pView (pView),
  9177. m_bValid ((pView != NULL) && IsWindowVisible (pView->m_hWnd))
  9178. {}
  9179. };
  9180. void CAMCView::ChangePane(AMCNavDir eDir)
  9181. {
  9182. ASSERT_VALID (this);
  9183. CFrameWnd* pFrame = GetParentFrame();
  9184. CView* pActiveView = pFrame->GetActiveView();
  9185. HWND hWndActive = ::GetFocus();
  9186. CTabOrderEntry rgOrderEntry[] =
  9187. {
  9188. CTabOrderEntry(GetPaneView(ePane_ScopeTree)), // tree has focus
  9189. CTabOrderEntry(GetPaneView(ePane_Results)), // results has focus - note the value of INDEX_RESULTS_PANE below.
  9190. CTabOrderEntry(m_pViewExtensionCtrl), // view extension web page has focus
  9191. CTabOrderEntry(m_pResultFolderTabView), // result tab control has focus
  9192. };
  9193. /*
  9194. * this is the index of the result pane entry in rgOrderEntry,
  9195. * used for default focus placement if something unexpected happens
  9196. */
  9197. const int INDEX_RESULTS_PANE = 1;
  9198. ASSERT (rgOrderEntry[INDEX_RESULTS_PANE].m_pView == GetPaneView(ePane_Results));
  9199. // Get the navigator if one exists. If so, use it and bail.
  9200. CAMCNavigator* pNav = dynamic_cast<CAMCNavigator*>(pActiveView);
  9201. if (pNav && pNav->ChangePane(eDir))
  9202. return;
  9203. int cEntries = (sizeof(rgOrderEntry) / sizeof(rgOrderEntry[0]));
  9204. // get the currently active entry.
  9205. for(int i = 0; i< cEntries; i++)
  9206. {
  9207. if( (rgOrderEntry[i].m_pView == pActiveView) )
  9208. break;
  9209. }
  9210. ASSERT(i < cEntries);
  9211. if(i>= cEntries)
  9212. {
  9213. // if we don't know where we are, a bit of defensive coding puts the focus back
  9214. // on the results pane, ie into a known state.
  9215. i = INDEX_RESULTS_PANE;
  9216. }
  9217. int iPrev = i;
  9218. // at this point we've found the right entry.
  9219. int increment = (eDir==AMCNAV_PREV) ? -1 : 1;
  9220. int sanityCount = 0;
  9221. while(true)
  9222. {
  9223. i = (i+increment+cEntries) % cEntries;
  9224. if(rgOrderEntry[i].m_bValid)
  9225. break;
  9226. sanityCount++;
  9227. if(sanityCount == cEntries)
  9228. {
  9229. ASSERT(0 && "Something's seriously messed up!!");
  9230. return;
  9231. }
  9232. }
  9233. // update the active view
  9234. if (i != iPrev)
  9235. pFrame->SetActiveView(rgOrderEntry[i].m_pView);
  9236. else
  9237. {
  9238. // if view retains focus and has a navigator,
  9239. // tell navigator to take the focus
  9240. if (pNav)
  9241. pNav->TakeFocus(eDir);
  9242. }
  9243. // if there is a special focus handler, call it.
  9244. CFocusHandler *pFocusHandler = dynamic_cast<CFocusHandler *>(rgOrderEntry[i].m_pView);
  9245. if(pFocusHandler != NULL)
  9246. {
  9247. pFocusHandler->OnKeyboardFocus (LVIS_FOCUSED | LVIS_SELECTED,
  9248. LVIS_FOCUSED | LVIS_SELECTED);
  9249. }
  9250. }
  9251. void CAMCView::OnNextPane()
  9252. {
  9253. ChangePane(AMCNAV_NEXT);
  9254. }
  9255. void CAMCView::OnPrevPane()
  9256. {
  9257. ChangePane(AMCNAV_PREV);
  9258. }
  9259. void CAMCView::OnUpdateNextPane(CCmdUI* pCmdUI)
  9260. {
  9261. pCmdUI->Enable(TRUE);
  9262. }
  9263. void CAMCView::OnUpdatePrevPane(CCmdUI* pCmdUI)
  9264. {
  9265. pCmdUI->Enable(TRUE);
  9266. }
  9267. void RestrictPointToWindow (CWnd* pwnd, CPoint* ppt)
  9268. {
  9269. CRect rectWnd;
  9270. pwnd->GetClientRect (rectWnd);
  9271. if (ppt->x < rectWnd.left)
  9272. ppt->x = rectWnd.left;
  9273. else if (ppt->x > rectWnd.right)
  9274. ppt->x = rectWnd.right;
  9275. if (ppt->y < rectWnd.top)
  9276. ppt->y = rectWnd.top;
  9277. else if (ppt->y > rectWnd.bottom)
  9278. ppt->y = rectWnd.bottom;
  9279. }
  9280. void CAMCView::OnShiftF10()
  9281. {
  9282. CRect rect;
  9283. CWnd* pwndFocus = GetFocus();
  9284. CListCtrl& lc = m_pListCtrl->GetListCtrl();
  9285. ASSERT_VALID (this);
  9286. if (pwndFocus == &lc)
  9287. {
  9288. int iItem = lc.GetNextItem (-1, LVNI_SELECTED);
  9289. CPoint pt = 0;
  9290. if (iItem != -1)
  9291. {
  9292. VERIFY (lc.GetItemRect (iItem, rect, LVIR_ICON));
  9293. pt = rect.CenterPoint ();
  9294. }
  9295. else
  9296. {
  9297. CHeaderCtrl* pHeader = m_pListCtrl->GetHeaderCtrl();
  9298. if (pHeader != NULL && pHeader->IsWindowVisible())
  9299. {
  9300. pHeader->GetClientRect(&rect);
  9301. pt.y = rect.Height();
  9302. ASSERT (pt.y >= 0);
  9303. }
  9304. }
  9305. /*
  9306. * make sure the context menu doesn't show up outside the window
  9307. */
  9308. RestrictPointToWindow (&lc, &pt);
  9309. m_pListCtrl->GetListViewPtr()->ClientToScreen(&pt);
  9310. OnListContextMenu(pt);
  9311. }
  9312. else if (pwndFocus == m_pTreeCtrl)
  9313. {
  9314. HTREEITEM hTreeItem = m_pTreeCtrl->GetSelectedItem();
  9315. if (hTreeItem == NULL)
  9316. return;
  9317. m_pTreeCtrl->GetItemRect (hTreeItem, rect, TRUE);
  9318. CPoint ptClient (rect.left, rect.bottom-1);
  9319. /*
  9320. * make sure the context menu doesn't show up outside the window
  9321. */
  9322. RestrictPointToWindow (m_pTreeCtrl, &ptClient);
  9323. CPoint ptScreen = ptClient;
  9324. m_pTreeCtrl->ClientToScreen(&ptScreen);
  9325. OnTreeContextMenu(ptScreen, ptClient, hTreeItem);
  9326. }
  9327. }
  9328. void CAMCView::OnUpdateShiftF10(CCmdUI* pCmdUI)
  9329. {
  9330. pCmdUI->Enable(TRUE);
  9331. }
  9332. BOOL CAMCView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  9333. {
  9334. if (nHitTest == HTCLIENT && pWnd == this && !IsTracking())
  9335. {
  9336. CPoint pt (GetMessagePos());
  9337. ScreenToClient (&pt);
  9338. if (m_rectVSplitter.PtInRect (pt))
  9339. {
  9340. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
  9341. return TRUE;
  9342. }
  9343. }
  9344. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  9345. }
  9346. SC CAMCView::ScCut (HTREEITEM htiCut)
  9347. {
  9348. AFX_MANAGE_STATE (AfxGetAppModuleState());
  9349. DECLARE_SC (sc, _T("CAMCView::ScCut"));
  9350. CMainFrame* pMain = AMCGetMainWnd();
  9351. sc = ScCheckPointers (pMain, E_UNEXPECTED);
  9352. if (sc)
  9353. return (sc);
  9354. pMain->SetWindowToNotifyCBChange(m_hWnd);
  9355. if (htiCut)
  9356. m_pTreeCtrl->SetItemState (htiCut, TVIS_CUT, TVIS_CUT);
  9357. else
  9358. m_pListCtrl->CutSelectedItems (TRUE);
  9359. m_htiCut = htiCut;
  9360. return (S_OK);
  9361. }
  9362. SC CAMCView::ScPaste ()
  9363. {
  9364. AFX_MANAGE_STATE (AfxGetAppModuleState());
  9365. DECLARE_SC (sc, _T("CAMCView::ScPaste"));
  9366. if (!m_htiCut)
  9367. m_pListCtrl->CutSelectedItems(FALSE);
  9368. CMainFrame* pMain = AMCGetMainWnd();
  9369. sc = ScCheckPointers (pMain, E_UNEXPECTED);
  9370. if (sc)
  9371. return (sc);
  9372. pMain->SetWindowToNotifyCBChange(NULL);
  9373. return (S_OK);
  9374. }
  9375. HRESULT CAMCView::SendGenericNotify(NCLBK_NOTIFY_TYPE nclbk)
  9376. {
  9377. BOOL bScope = TRUE;
  9378. MMC_COOKIE lCookie = 0;
  9379. int iItem = -1;
  9380. ASSERT_VALID (this);
  9381. if (m_pListCtrl && m_pListCtrl->GetListViewHWND() == ::GetFocus())
  9382. {
  9383. iItem = _GetLVSelectedItemData(&lCookie);
  9384. if (iItem != -1)
  9385. bScope = FALSE;
  9386. }
  9387. INodeCallback* pNC = GetNodeCallback();
  9388. ASSERT(pNC != NULL);
  9389. if (pNC == NULL)
  9390. return E_FAIL;
  9391. HNODE hNodeSel = GetSelectedNode();
  9392. ASSERT(hNodeSel != NULL);
  9393. if (hNodeSel == NULL)
  9394. return E_FAIL;
  9395. // selection notifications should use ScNotifySelect()
  9396. ASSERT ((nclbk != NCLBK_SELECT) && (nclbk != NCLBK_MULTI_SELECT));
  9397. return pNC->Notify(hNodeSel, nclbk, bScope, lCookie);
  9398. }
  9399. void CAMCView::SaveStartingSelectedNode()
  9400. {
  9401. m_htiStartingSelectedNode = m_pTreeCtrl->GetSelectedItem();
  9402. }
  9403. bool CAMCView::HasNodeSelChanged()
  9404. {
  9405. return (m_pTreeCtrl->GetSelectedItem() != m_htiStartingSelectedNode);
  9406. }
  9407. //+---------------------------------------------------------------------------
  9408. //
  9409. // Function: OnSysKeyDown
  9410. //
  9411. // Synopsis: Handles WM_SYSKEYDOWN message.
  9412. // CAMCTreeView::OnSysKeyDown handles the Tree view so
  9413. // here we handle only the list view (or Result pane)
  9414. //
  9415. // Returns: none
  9416. //
  9417. //+---------------------------------------------------------------------------
  9418. void CAMCView::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  9419. {
  9420. switch (nChar)
  9421. {
  9422. case VK_LEFT:
  9423. ScWebCommand(eWeb_Back);
  9424. break;
  9425. case VK_RIGHT:
  9426. ScWebCommand(eWeb_Forward);
  9427. break;
  9428. }
  9429. }
  9430. /*+-------------------------------------------------------------------------*
  9431. * CAMCView::OnAppCommand
  9432. *
  9433. * WM_APPCOMMAND handler for CAMCView. This is used to handle to forward
  9434. * and backward buttons on the IntelliMouse Explorer and the Microsoft
  9435. * Natural Keyboards
  9436. *--------------------------------------------------------------------------*/
  9437. LRESULT CAMCView::OnAppCommand(WPARAM wParam, LPARAM lParam)
  9438. {
  9439. DECLARE_SC (sc, _T("CAMCView::OnAppCommand"));
  9440. switch (GET_APPCOMMAND_LPARAM (lParam))
  9441. {
  9442. case APPCOMMAND_BROWSER_BACKWARD:
  9443. sc = ScWebCommand (eWeb_Back);
  9444. if (sc)
  9445. break;
  9446. return (TRUE); // handled here
  9447. case APPCOMMAND_BROWSER_FORWARD:
  9448. sc = ScWebCommand (eWeb_Forward);
  9449. if (sc)
  9450. break;
  9451. return (TRUE); // handled here
  9452. case APPCOMMAND_BROWSER_REFRESH:
  9453. OnRefresh ();
  9454. return (TRUE); // handled here
  9455. }
  9456. return (Default());
  9457. }
  9458. void CAMCView::OnPaletteChanged(CWnd* pwndFocus)
  9459. {
  9460. // if displaying a web page, forward the palette change to the shell
  9461. if (HasWebBrowser() && m_pWebViewCtrl != NULL)
  9462. {
  9463. if (m_pWebViewCtrl->m_hWnd != NULL)
  9464. {
  9465. HWND hwndShell = ::GetWindow(m_pWebViewCtrl->m_hWnd, GW_CHILD);
  9466. if (hwndShell != NULL)
  9467. ::SendMessage(hwndShell, WM_PALETTECHANGED, (WPARAM)pwndFocus->m_hWnd, (LPARAM)0);
  9468. }
  9469. }
  9470. }
  9471. BOOL CAMCView::OnQueryNewPalette()
  9472. {
  9473. // if displaying a web page, forward the palette query to the shell
  9474. if (HasWebBrowser() && m_pWebViewCtrl != NULL)
  9475. {
  9476. if (m_pWebViewCtrl->m_hWnd != NULL)
  9477. {
  9478. HWND hwndShell = ::GetWindow(m_pWebViewCtrl->m_hWnd, GW_CHILD);
  9479. if (hwndShell != NULL)
  9480. return ::SendMessage(hwndShell, WM_QUERYNEWPALETTE, (WPARAM)0, (LPARAM)0);
  9481. }
  9482. }
  9483. return 0;
  9484. }
  9485. BOOL CAMCView::OwnsResultList(HTREEITEM hti)
  9486. {
  9487. if (hti == NULL)
  9488. return (false);
  9489. // if result list is active
  9490. if (HasListOrListPad())
  9491. {
  9492. // Get selected node and query node
  9493. HNODE hnodeSelected = GetSelectedNode();
  9494. HNODE hnode = m_pTreeCtrl ? m_pTreeCtrl->GetItemNode(hti) : NULL;
  9495. if (hnodeSelected && hnode)
  9496. {
  9497. INodeCallback* pNC = GetNodeCallback();
  9498. ASSERT(pNC != NULL);
  9499. // See if the selected node uses the query node as a target
  9500. // S_OK - yes
  9501. // S_FALSE - uses a different target node
  9502. // E_FAIL - doesn't use a target node
  9503. HRESULT hr = pNC->IsTargetNodeOf(hnodeSelected, hnode);
  9504. if (hr == S_OK)
  9505. return TRUE;
  9506. else if (hr == S_FALSE)
  9507. return FALSE;
  9508. else
  9509. return (hnodeSelected == hnode);
  9510. }
  9511. }
  9512. return FALSE;
  9513. }
  9514. /*+-------------------------------------------------------------------------*
  9515. * CAMCView::OnSysColorChange
  9516. *
  9517. * WM_SYSCOLORCHANGE handler for CAMCView.
  9518. *--------------------------------------------------------------------------*/
  9519. void CAMCView::OnSysColorChange()
  9520. {
  9521. CView::OnSysColorChange();
  9522. /*
  9523. * the list control isn't a window but rather a wrapper on a window,
  9524. * so we need to manually forward on the WM_SYSCOLORCHANGE
  9525. */
  9526. m_pListCtrl->OnSysColorChange();
  9527. }
  9528. /*+-------------------------------------------------------------------------*
  9529. * TrackerCallback function
  9530. *
  9531. * Called by CViewTracker when tracking of splitter bar is completed. This
  9532. * function applies the changes if the AcceptChange flag is set.
  9533. *--------------------------------------------------------------------------*/
  9534. void CALLBACK TrackerCallback(
  9535. TRACKER_INFO* pInfo,
  9536. bool bAcceptChange,
  9537. bool bSyncLayout)
  9538. {
  9539. DECLARE_SC (sc, _T("TrackerCallback"));
  9540. if (bAcceptChange)
  9541. {
  9542. CAMCView* pView = dynamic_cast<CAMCView*>(pInfo->pView);
  9543. sc = ScCheckPointers (pView, E_UNEXPECTED);
  9544. if (sc)
  9545. return;
  9546. // Set new width and recompute layout
  9547. pView->m_PaneInfo[CConsoleView::ePane_ScopeTree].cx = pInfo->rectTracker.left;
  9548. pView->SetDirty();
  9549. if (bSyncLayout)
  9550. {
  9551. Trace (tagSplitterTracking, _T("Synchronous layout"));
  9552. pView->RecalcLayout();
  9553. pView->UpdateWindow();
  9554. }
  9555. else
  9556. {
  9557. Trace (tagSplitterTracking, _T("Deferred layout"));
  9558. pView->DeferRecalcLayout();
  9559. }
  9560. }
  9561. }
  9562. /*+-------------------------------------------------------------------------*
  9563. * PtInWindow
  9564. *
  9565. * Test if point is in a window (pt is in screen coordinates)
  9566. *--------------------------------------------------------------------------*/
  9567. BOOL PtInWindow(CWnd* pWnd, CPoint pt)
  9568. {
  9569. if (!pWnd->IsWindowVisible())
  9570. return FALSE;
  9571. CRect rect;
  9572. pWnd->GetWindowRect(&rect);
  9573. return rect.PtInRect(pt);
  9574. }
  9575. /*+-------------------------------------------------------------------------*
  9576. * CAMCView::ScJiggleListViewFocus
  9577. *
  9578. * Bug 345402: Make sure the focus rect is on the list control (if it
  9579. * actually has the focus) to wake up any accessibility tools that might
  9580. * be watching for input and focus changes.
  9581. *
  9582. * We post a message here rather than doing it synchronously so we can
  9583. * allow any other processing in the list (like sorting) to happen
  9584. * before we put the focus on the 1st item. If we didn't wait until after
  9585. * the sort, the item we put the focus on might not be the first item
  9586. * in the list.
  9587. *--------------------------------------------------------------------------*/
  9588. SC CAMCView::ScJiggleListViewFocus ()
  9589. {
  9590. AFX_MANAGE_STATE (AfxGetAppModuleState());
  9591. PostMessage (m_nJiggleListViewFocusMsg);
  9592. return (S_OK);
  9593. }
  9594. LRESULT CAMCView::OnJiggleListViewFocus (WPARAM, LPARAM)
  9595. {
  9596. CAMCListView* pListView = m_pListCtrl->GetListViewPtr();
  9597. /*
  9598. * If the focus is on the list control, make sure that at least one item
  9599. * has the focus rect. Doing this will wake up any accessibility tools
  9600. * that might be watching (Bug 345402).
  9601. */
  9602. if ((GetFocusedPane() == ePane_Results) &&
  9603. (GetResultView() == pListView))
  9604. {
  9605. pListView->OnKeyboardFocus (LVIS_FOCUSED, LVIS_FOCUSED);
  9606. }
  9607. return (0);
  9608. }
  9609. /*+-------------------------------------------------------------------------*
  9610. * CAMCView::OnDeferRecalcLayout
  9611. *
  9612. * CAMCView::m_nDeferRecalcLayoutMsg registered message handler for CAMCView.
  9613. *
  9614. * Parameters:
  9615. * bDoArrange - if non-zero need to call Arrange on list-view so that
  9616. * common-control can layout items properly.
  9617. *
  9618. *--------------------------------------------------------------------------*/
  9619. LRESULT CAMCView::OnDeferRecalcLayout (WPARAM bDoArrange, LPARAM)
  9620. {
  9621. Trace (tagLayout, _T("CAMCView::OnDeferRecalcLayout"));
  9622. RecalcLayout();
  9623. if (bDoArrange && m_pListCtrl)
  9624. {
  9625. int nViewMode = m_pListCtrl->GetViewMode();
  9626. // Arrange is only for large & small icon modes.
  9627. if ( (nViewMode == MMCLV_VIEWSTYLE_ICON) ||
  9628. (nViewMode == MMCLV_VIEWSTYLE_SMALLICON) )
  9629. m_pListCtrl->Arrange(LVA_DEFAULT);
  9630. }
  9631. return (0);
  9632. }
  9633. /*+-------------------------------------------------------------------------*
  9634. * CDeferredPageBreak
  9635. *
  9636. *
  9637. * PURPOSE: Used to delay sending a web page break until an idle timeout.
  9638. * This used to be sent via PostMessage, but resulted in multiple
  9639. * ScDoPageBreak calls on the same stack, since the latter has
  9640. * its own message loop. By using the idle timer, we guarantee that
  9641. * there are no reentrant problems.
  9642. *
  9643. *+-------------------------------------------------------------------------*/
  9644. class CDeferredPageBreak : public CIdleTask
  9645. {
  9646. public:
  9647. CDeferredPageBreak(UINT nAddPageBreakAndNavigateMsg, HWND hWnd, WPARAM wParam, LPCTSTR szURL) :
  9648. m_atomTask (AddAtom (_T("CDeferredPageBreak"))),
  9649. m_nAddPageBreakAndNavigateMsg(nAddPageBreakAndNavigateMsg),
  9650. m_hWnd(hWnd),
  9651. m_wParam(wParam),
  9652. m_strURL(szURL ? szURL : _T(""))
  9653. {
  9654. }
  9655. ~CDeferredPageBreak() {}
  9656. // IIdleTask methods
  9657. SC ScDoWork()
  9658. {
  9659. DECLARE_SC (sc, TEXT("CDeferredPageBreak::ScDoWork"));
  9660. ::SendMessage(m_hWnd, m_nAddPageBreakAndNavigateMsg, m_wParam,
  9661. reinterpret_cast<LPARAM>( m_strURL.data() )); // do this synchronously
  9662. return sc;
  9663. }
  9664. SC ScGetTaskID(ATOM* pID)
  9665. {
  9666. DECLARE_SC (sc, TEXT("CDeferredPageBreak::ScGetTaskID"));
  9667. sc = ScCheckPointers(pID);
  9668. if(sc)
  9669. return sc;
  9670. *pID = m_atomTask;
  9671. return sc;
  9672. }
  9673. SC ScMerge(CIdleTask* pitMergeFrom) {return S_FALSE /*do not merge*/;}
  9674. private:
  9675. const ATOM m_atomTask;
  9676. const UINT m_nAddPageBreakAndNavigateMsg;
  9677. const HWND m_hWnd;
  9678. const WPARAM m_wParam;
  9679. const tstring m_strURL;
  9680. };
  9681. /*+-------------------------------------------------------------------------*
  9682. * CAMCView::ScAddPageBreakAndNavigate
  9683. *
  9684. * Adds a page break to the history list. This needs to occur asynchronously,
  9685. * so we post a private message to ourselves and return.
  9686. *--------------------------------------------------------------------------*/
  9687. SC CAMCView::ScAddPageBreakAndNavigate (bool fAddPageBreak, bool fNavigate, LPCTSTR szURL)
  9688. {
  9689. AFX_MANAGE_STATE (AfxGetAppModuleState()); // not sure if we need this, but doesn't hurt to have it in here.
  9690. DECLARE_SC (sc, TEXT("CAMCView::ScAddPageBreakAndNavigate"));
  9691. CIdleTaskQueue* pIdleTaskQueue = AMCGetIdleTaskQueue();
  9692. sc = ScCheckPointers(pIdleTaskQueue, E_UNEXPECTED);
  9693. if(sc)
  9694. return sc;
  9695. if ( fNavigate && szURL == NULL )
  9696. return sc = E_INVALIDARG;
  9697. /*
  9698. * create the deferred page break task
  9699. */
  9700. CAutoPtr<CDeferredPageBreak> spDeferredPageBreak (new CDeferredPageBreak (m_nAddPageBreakAndNavigateMsg, m_hWnd,
  9701. MAKEWPARAM(fAddPageBreak, fNavigate),
  9702. szURL));
  9703. sc = ScCheckPointers(spDeferredPageBreak, E_OUTOFMEMORY);
  9704. if(sc)
  9705. return sc;
  9706. /*
  9707. * put the task in the queue, which will take ownership of it
  9708. */
  9709. sc = pIdleTaskQueue->ScPushTask (spDeferredPageBreak, ePriority_Normal);
  9710. if (sc)
  9711. return sc;
  9712. /*
  9713. * if we get here, the idle task queue owns the idle task, so
  9714. * we can detach it from our smart pointer
  9715. */
  9716. spDeferredPageBreak.Detach();
  9717. /*
  9718. * jiggle the message pump so that it wakes up and checks idle tasks
  9719. */
  9720. PostMessage (WM_NULL);
  9721. return (S_OK);
  9722. }
  9723. /***************************************************************************\
  9724. *
  9725. * METHOD: CAMCView::OnAddPageBreakAndNavigate
  9726. *
  9727. * PURPOSE: Puts a page break and/or navigates to a new webapge
  9728. * This method will be called to perfor 3 kinds of the jobs:
  9729. * 1. Add a pagebreak (used when selection changes from the web page to list view)
  9730. * 2. Add a pagebreak and navigate
  9731. * (a. when selection changes from web page to another web page)
  9732. * (b. when selection changes from list view to the webpage
  9733. * and it is the first web page in the history)
  9734. * 3. Navigate only. ( when navigating from list view to the webpage -
  9735. * if pagebreak had to be added when leaving the previos web page)
  9736. *
  9737. * PARAMETERS:
  9738. * LOWORD(wParam) - nonzero if page break needs to be added
  9739. * HIWORD(wParam) - nonzero if navigation should take place
  9740. * LPARAM lParam - not used
  9741. *
  9742. * RETURNS:
  9743. * SC - result code
  9744. *
  9745. \***************************************************************************/
  9746. LRESULT CAMCView::OnAddPageBreakAndNavigate (WPARAM wParam, LPARAM lParam)
  9747. {
  9748. DECLARE_SC(sc, TEXT("CAMCView::OnAddPageBreakAndNavigate"));
  9749. BOOL bAddPageBreak = (BOOL)LOWORD(wParam);
  9750. BOOL bNavigate = (BOOL)HIWORD(wParam);
  9751. // check the pointer we will need here
  9752. CHistoryList* pHistoryList = GetHistoryList();
  9753. sc = ScCheckPointers( pHistoryList, m_pWebViewCtrl, E_UNEXPECTED);
  9754. if (sc)
  9755. return 0;
  9756. if (bAddPageBreak)
  9757. {
  9758. sc = pHistoryList->ScDoPageBreak();
  9759. if (sc)
  9760. return 0;
  9761. }
  9762. if (bNavigate)
  9763. {
  9764. LPCTSTR szURL = reinterpret_cast<LPCTSTR>(lParam);
  9765. sc = ScCheckPointers( szURL );
  9766. if (sc)
  9767. return 0;
  9768. m_pWebViewCtrl->Navigate( szURL, NULL );
  9769. }
  9770. return 0;
  9771. }
  9772. //############################################################################
  9773. //############################################################################
  9774. //
  9775. // Implementation of class CViewTemplate
  9776. //
  9777. //############################################################################
  9778. //############################################################################
  9779. /***************************************************************************\
  9780. *
  9781. * METHOD: CViewTemplateList::Persist
  9782. *
  9783. * PURPOSE: Used when loading XML. Persist enough information to create a view
  9784. * The rest of view peristence is dome by CAMCView
  9785. *
  9786. * PARAMETERS:
  9787. * CPersistor& persistor - persistor to load from
  9788. *
  9789. * RETURNS:
  9790. * SC - result code
  9791. *
  9792. \***************************************************************************/
  9793. void CViewTemplateList::Persist(CPersistor& persistor)
  9794. {
  9795. // the view should be stored instead
  9796. ASSERT (persistor.IsLoading());
  9797. // delegate to the base class
  9798. XMLListCollectionBase::Persist(persistor);
  9799. }
  9800. /***************************************************************************\
  9801. *
  9802. * METHOD: CViewTemplateList::OnNewElement
  9803. *
  9804. * PURPOSE: Called by XMLListCollectionBase to request persisting of new element
  9805. * Each new element is created and persisted in this function.
  9806. *
  9807. * PARAMETERS:
  9808. * CPersistor& persistor - persisto from which the element should be loaded
  9809. *
  9810. * RETURNS:
  9811. * SC - result code
  9812. *
  9813. \***************************************************************************/
  9814. void CViewTemplateList::OnNewElement(CPersistor& persistor)
  9815. {
  9816. CBookmark bm;
  9817. int iViewId = -1;
  9818. // load information byte for new view
  9819. CPersistor persistorView(persistor, CAMCView::_GetXMLType());
  9820. persistorView.Persist(bm, XML_NAME_ROOT_NODE);
  9821. persistorView.PersistAttribute(XML_ATTR_VIEW_ID, iViewId);
  9822. // store information to the list
  9823. m_ViewsList.push_back(ViewTempl_Type(iViewId, ViewTemplB_Type(bm, persistorView)));
  9824. }
  9825. //+-------------------------------------------------------------------
  9826. //
  9827. // Member: ScUpdateStandardbarMMCButtons
  9828. //
  9829. // Synopsis: Appropriately enable/disable std-toolbar buttons
  9830. // that are owned by MMC (not verb buttons that snapins own) like
  9831. // back, forward, export-list, up-one-level, show/hide-scope, help.
  9832. //
  9833. // Arguments: None.
  9834. //
  9835. //--------------------------------------------------------------------
  9836. SC CAMCView::ScUpdateStandardbarMMCButtons()
  9837. {
  9838. DECLARE_SC (sc, _T("CAMCView::ScUpdateStandardbarMMCButtons"));
  9839. // Get the standard toolbar and change the states.
  9840. CStandardToolbar* pStdToolbar = GetStdToolbar();
  9841. if (NULL == pStdToolbar)
  9842. return (sc = E_UNEXPECTED);
  9843. CAMCDoc *pDoc = GetDocument();
  9844. sc = ScCheckPointers(pDoc, E_UNEXPECTED);
  9845. if (sc)
  9846. return sc;
  9847. // If view is not customizable then hide the "Show/Hide scope tree" button.
  9848. sc = pStdToolbar->ScEnableScopePaneBtn(IsScopePaneAllowed() && pDoc->AllowViewCustomization());
  9849. if (sc)
  9850. sc.TraceAndClear();
  9851. sc = pStdToolbar->ScEnableContextHelpBtn(true);
  9852. if (sc)
  9853. sc.TraceAndClear();
  9854. sc = pStdToolbar->ScEnableExportList(GetListSize() > 0 /*Enable only if LV has items*/);
  9855. if (sc)
  9856. sc.TraceAndClear();
  9857. // Enable/Disable Up-One Level button.
  9858. BOOL bEnableUpOneLevel = !m_pTreeCtrl->IsRootItemSel();
  9859. sc = pStdToolbar->ScEnableUpOneLevel(bEnableUpOneLevel);
  9860. if (sc)
  9861. sc.TraceAndClear();
  9862. // Now update history related buttons.
  9863. sc = ScCheckPointers(m_pHistoryList, E_UNEXPECTED);
  9864. if (sc)
  9865. return sc;
  9866. m_pHistoryList->MaintainWebBar();
  9867. return sc;
  9868. }
  9869. //+-------------------------------------------------------------------
  9870. //
  9871. // Member: CAMCView::ScUpdateMMCMenus
  9872. //
  9873. // Synopsis: Show or Hide MMC menus depending on if they are allowed
  9874. // or not. Should do this only if our view owns the menus
  9875. // that is we are the active view. (Action/View/Favs)
  9876. //
  9877. // Arguments:
  9878. //
  9879. // Returns: SC
  9880. //
  9881. //--------------------------------------------------------------------
  9882. SC CAMCView::ScUpdateMMCMenus ()
  9883. {
  9884. DECLARE_SC(sc, _T("CAMCView::ScUpdateMMCMenus"));
  9885. CMainFrame* pMainFrame = AMCGetMainWnd();
  9886. sc = ScCheckPointers(pMainFrame, E_UNEXPECTED);
  9887. if (sc)
  9888. return sc;
  9889. if (this != pMainFrame->GetActiveAMCView())
  9890. return (sc = S_OK); // we are not active view so it is ok.
  9891. // We are active view so tell mainframe to update the menus.
  9892. sc = pMainFrame->ScShowMMCMenus(m_ViewData.IsStandardMenusAllowed());
  9893. if (sc)
  9894. return sc;
  9895. return (sc);
  9896. }
  9897. //+-------------------------------------------------------------------
  9898. //
  9899. // Member: CAMCView::ScCreateToolbarObjects
  9900. //
  9901. // Synopsis: Create the CAMCViewToolbars that manages all toolbar data
  9902. // for this view & CStandardToolbar objects.
  9903. //
  9904. // Arguments: None.
  9905. //
  9906. // Returns: SC
  9907. //
  9908. //--------------------------------------------------------------------
  9909. SC CAMCView::ScCreateToolbarObjects ()
  9910. {
  9911. DECLARE_SC(sc, _T("CAMCView::ScCreateToolbarObjects"));
  9912. CMainFrame *pMainFrame = AMCGetMainWnd();
  9913. sc = ScCheckPointers(pMainFrame, E_UNEXPECTED);
  9914. if (sc)
  9915. return sc;
  9916. // Create the toolbars for this view.
  9917. CMMCToolBar *pMainToolbar = pMainFrame->GetMainToolbar();
  9918. sc = ScCheckPointers(pMainToolbar, E_OUTOFMEMORY);
  9919. if (sc)
  9920. return sc;
  9921. m_spAMCViewToolbars = std::auto_ptr<CAMCViewToolbars>(new CAMCViewToolbars(pMainToolbar, this));
  9922. sc = ScCheckPointers(m_spAMCViewToolbars.get(), E_FAIL);
  9923. if (sc)
  9924. return sc;
  9925. m_ViewData.SetAMCViewToolbarsMgr(m_spAMCViewToolbars.get() );
  9926. sc = m_spAMCViewToolbars->ScInit();
  9927. if (sc)
  9928. return sc;
  9929. // This CAMCViewToolbars is interested in view activation/de-activation/destruction events.
  9930. AddObserver( (CAMCViewObserver&) (*m_spAMCViewToolbars) );
  9931. // Main toolbar UI is interested in the active CAMCViewToolbars.
  9932. m_spAMCViewToolbars->AddObserver( *static_cast<CAMCViewToolbarsObserver *>(pMainToolbar) );
  9933. // MMC application is interested in the toolbar event, since it needs to inform the script
  9934. CAMCApp *pCAMCApp = AMCGetApp();
  9935. if ( pCAMCApp )
  9936. m_spAMCViewToolbars->AddObserver( *static_cast<CAMCViewToolbarsObserver *>(pCAMCApp) );
  9937. // Create standard toolbar.
  9938. m_spStandardToolbar = std::auto_ptr<CStandardToolbar>(new CStandardToolbar());
  9939. sc = ScCheckPointers(m_spStandardToolbar.get(), E_OUTOFMEMORY);
  9940. if (sc)
  9941. return sc;
  9942. m_ViewData.SetStdVerbButtons(m_spStandardToolbar.get());
  9943. return (sc);
  9944. }
  9945. /*+-------------------------------------------------------------------------*
  9946. * class CMMCViewFrame
  9947. *
  9948. *
  9949. * PURPOSE: The COM 0bject that exposes the Frame interface off the View object.
  9950. *
  9951. *+-------------------------------------------------------------------------*/
  9952. class CMMCViewFrame :
  9953. public CMMCIDispatchImpl<Frame>,
  9954. public CTiedComObject<CAMCView>
  9955. {
  9956. typedef CAMCView CMyTiedObject;
  9957. typedef CMMCViewFrame ThisClass;
  9958. public:
  9959. BEGIN_MMC_COM_MAP(ThisClass)
  9960. END_MMC_COM_MAP()
  9961. //Frame interface
  9962. public:
  9963. MMC_METHOD0( Maximize );
  9964. MMC_METHOD0( Minimize );
  9965. MMC_METHOD0( Restore );
  9966. MMC_METHOD1( get_Left, LPINT );
  9967. MMC_METHOD1( put_Left, INT );
  9968. MMC_METHOD1( get_Right, LPINT );
  9969. MMC_METHOD1( put_Right, INT );
  9970. MMC_METHOD1( get_Top, LPINT );
  9971. MMC_METHOD1( put_Top, INT );
  9972. MMC_METHOD1( get_Bottom, LPINT );
  9973. MMC_METHOD1( put_Bottom, INT );
  9974. };
  9975. /*+-------------------------------------------------------------------------*
  9976. *
  9977. * CAMCView::ScGetFrame
  9978. *
  9979. * PURPOSE: Returns a pointer to the COM object that implements the
  9980. * Frame interface.
  9981. *
  9982. * PARAMETERS:
  9983. * Frame **ppFrame :
  9984. *
  9985. * RETURNS:
  9986. * SC
  9987. *
  9988. *+-------------------------------------------------------------------------*/
  9989. SC
  9990. CAMCView::Scget_Frame(Frame **ppFrame)
  9991. {
  9992. DECLARE_SC(sc, TEXT("CAMCView::ScGetFrame") );
  9993. if(!ppFrame)
  9994. {
  9995. sc = E_POINTER;
  9996. return sc;
  9997. }
  9998. // init out parameter
  9999. *ppFrame = NULL;
  10000. // create a CMMCApplicationFrame if not already done so.
  10001. sc = CTiedComObjectCreator<CMMCViewFrame>::ScCreateAndConnect(*this, m_spFrame);
  10002. if(sc)
  10003. return sc;
  10004. if(m_spFrame == NULL)
  10005. {
  10006. sc = E_UNEXPECTED;
  10007. return sc;
  10008. }
  10009. // addref the pointer for the client.
  10010. m_spFrame->AddRef();
  10011. *ppFrame = m_spFrame;
  10012. return sc;
  10013. }
  10014. /***************************************************************************\
  10015. | Frame interface |
  10016. \***************************************************************************/
  10017. /*+-------------------------------------------------------------------------*
  10018. *
  10019. * CAMCView::ScMaximize
  10020. *
  10021. * PURPOSE: Maximizes frame window of the view
  10022. *
  10023. * PARAMETERS:
  10024. *
  10025. * RETURNS:
  10026. * SC
  10027. *
  10028. *+-------------------------------------------------------------------------*/
  10029. SC CAMCView::ScMaximize ()
  10030. {
  10031. DECLARE_SC(sc, TEXT("CAMCView::ScMaximize"));
  10032. CChildFrame *pFrame = GetParentFrame();
  10033. sc = ScCheckPointers(pFrame, E_FAIL);
  10034. if (sc)
  10035. return sc;
  10036. pFrame->ShowWindow(SW_MAXIMIZE);
  10037. return sc;
  10038. }
  10039. /*+-------------------------------------------------------------------------*
  10040. *
  10041. * CAMCView::ScMinimize
  10042. *
  10043. * PURPOSE: Minimizes frame window of the view
  10044. *
  10045. * PARAMETERS:
  10046. *
  10047. * RETURNS:
  10048. * SC
  10049. *
  10050. *+-------------------------------------------------------------------------*/
  10051. SC CAMCView::ScMinimize ()
  10052. {
  10053. DECLARE_SC(sc, TEXT("CAMCView::ScMinimize"));
  10054. CChildFrame *pFrame = GetParentFrame();
  10055. sc = ScCheckPointers(pFrame, E_FAIL);
  10056. if (sc)
  10057. return sc;
  10058. pFrame->ShowWindow(SW_MINIMIZE);
  10059. return sc;
  10060. }
  10061. /*+-------------------------------------------------------------------------*
  10062. *
  10063. * CAMCView::ScRestore
  10064. *
  10065. * PURPOSE: Restores frame window of the view
  10066. *
  10067. * PARAMETERS:
  10068. *
  10069. * RETURNS:
  10070. * SC
  10071. *
  10072. *+-------------------------------------------------------------------------*/
  10073. SC CAMCView::ScRestore ()
  10074. {
  10075. DECLARE_SC(sc, TEXT("CAMCView::ScRestore"));
  10076. CChildFrame *pFrame = GetParentFrame();
  10077. sc = ScCheckPointers(pFrame, E_FAIL);
  10078. if (sc)
  10079. return sc;
  10080. pFrame->ShowWindow(SW_RESTORE);
  10081. return sc;
  10082. }
  10083. /*+-------------------------------------------------------------------------*
  10084. *
  10085. * CAMCView::ScGetFrameCoord
  10086. *
  10087. * PURPOSE: Helper method. Returns specified coordinate of the parent frame
  10088. *
  10089. * PARAMETERS:
  10090. * LPINT pCoord - storage for return value
  10091. * coord_t eCoord - which coordinate to return (LEFT, TOP, etc)
  10092. *
  10093. * RETURNS:
  10094. * SC
  10095. *
  10096. *+-------------------------------------------------------------------------*/
  10097. SC CAMCView::ScGetFrameCoord ( LPINT pCoord, coord_t eCoord )
  10098. {
  10099. DECLARE_SC(sc, TEXT("CAMCView::ScGetFrameCoord"));
  10100. // get & check frame ptr
  10101. CChildFrame *pFrame = GetParentFrame();
  10102. sc = ScCheckPointers(pFrame, E_FAIL);
  10103. if (sc)
  10104. return sc;
  10105. CWnd *pParent = pFrame->GetParent();
  10106. sc = ScCheckPointers (pParent, E_FAIL);
  10107. if (sc)
  10108. return (sc);
  10109. // get coordinates of frame window relative to its parent
  10110. CWindowRect rcFrame (pFrame);
  10111. pParent->ScreenToClient(rcFrame);
  10112. // assign to result
  10113. sc = ScGetRectCoord (rcFrame, pCoord, eCoord);
  10114. if (sc)
  10115. return (sc);
  10116. return sc;
  10117. }
  10118. /*+-------------------------------------------------------------------------*
  10119. *
  10120. * CAMCView::ScSetFrameCoord
  10121. *
  10122. * PURPOSE: Helper method. Sets specified coordinate of the parent frame
  10123. *
  10124. * PARAMETERS:
  10125. * INT coord - new value to set
  10126. * coord_t eCoord - which coordinate to modify (LEFT, TOP, etc)
  10127. *
  10128. * RETURNS:
  10129. * SC
  10130. *
  10131. *+-------------------------------------------------------------------------*/
  10132. SC CAMCView::ScSetFrameCoord ( INT coord, coord_t eCoord )
  10133. {
  10134. DECLARE_SC(sc, TEXT("CAMCView::ScSetFrameCoord"));
  10135. CChildFrame *pFrame = GetParentFrame();
  10136. sc = ScCheckPointers(pFrame, E_FAIL);
  10137. if (sc)
  10138. return sc;
  10139. CWnd *pParent = pFrame->GetParent();
  10140. sc = ScCheckPointers (pParent, E_FAIL);
  10141. if (sc)
  10142. return (sc);
  10143. // get coordinates of frame window relative to its parent
  10144. CWindowRect rcFrame (pFrame);
  10145. pParent->ScreenToClient(rcFrame);
  10146. // change the rectangle's specified coordinate
  10147. sc = ScSetRectCoord (rcFrame, coord, eCoord);
  10148. if (sc)
  10149. return (sc);
  10150. // move the window
  10151. pFrame->MoveWindow (rcFrame);
  10152. return sc;
  10153. }
  10154. /*+-------------------------------------------------------------------------*
  10155. *
  10156. * CAMCView::ScGetRectCoord
  10157. *
  10158. * PURPOSE: Helper method. Returns specified coordinate of the given rectangle
  10159. *
  10160. * PARAMETERS:
  10161. * const RECT& rect - rectangle to query
  10162. * LPINT pCoord - storage for return value
  10163. * coord_t eCoord - which coordinate to return (LEFT, TOP, etc)
  10164. *
  10165. * RETURNS:
  10166. * SC
  10167. *
  10168. *+-------------------------------------------------------------------------*/
  10169. SC CAMCView::ScGetRectCoord ( const RECT& rect, LPINT pCoord, coord_t eCoord )
  10170. {
  10171. DECLARE_SC(sc, TEXT("CAMCView::ScGetRectCoord"));
  10172. // check parameters
  10173. sc = ScCheckPointers(pCoord);
  10174. if (sc)
  10175. return sc;
  10176. // assign to result
  10177. switch (eCoord)
  10178. {
  10179. case LEFT: *pCoord = rect.left; break;
  10180. case RIGHT: *pCoord = rect.right; break;
  10181. case TOP: *pCoord = rect.top; break;
  10182. case BOTTOM: *pCoord = rect.bottom; break;
  10183. default:
  10184. *pCoord = 0;
  10185. sc = E_INVALIDARG;
  10186. break;
  10187. }
  10188. return sc;
  10189. }
  10190. /*+-------------------------------------------------------------------------*
  10191. *
  10192. * CAMCView::ScSetRectCoord
  10193. *
  10194. * PURPOSE: Helper method. Sets specified coordinate of the given rectangle
  10195. *
  10196. * PARAMETERS:
  10197. * RECT& rect - rectangle to modify
  10198. * INT coord - new value to set
  10199. * coord_t eCoord - which coordinate to modify (LEFT, TOP, etc)
  10200. *
  10201. * RETURNS:
  10202. * SC
  10203. *
  10204. *+-------------------------------------------------------------------------*/
  10205. SC CAMCView::ScSetRectCoord ( RECT& rect, INT coord, coord_t eCoord )
  10206. {
  10207. DECLARE_SC(sc, TEXT("CAMCView::ScSetRectCoord"));
  10208. // assign coordinate
  10209. switch (eCoord)
  10210. {
  10211. case LEFT: rect.left = coord; break;
  10212. case RIGHT: rect.right = coord; break;
  10213. case TOP: rect.top = coord; break;
  10214. case BOTTOM: rect.bottom = coord; break;
  10215. default: sc = E_INVALIDARG; break;
  10216. }
  10217. return sc;
  10218. }
  10219. /*+-------------------------------------------------------------------------*
  10220. *
  10221. * CAMCView::Scget_Left
  10222. *
  10223. * PURPOSE: Implements Frame.Left property's Get method for view
  10224. *
  10225. * PARAMETERS:
  10226. * LPINT pCoord - storage for return value
  10227. *
  10228. * RETURNS:
  10229. * SC
  10230. *
  10231. *+-------------------------------------------------------------------------*/
  10232. SC CAMCView::Scget_Left ( LPINT pCoord )
  10233. {
  10234. DECLARE_SC(sc, TEXT("CAMCView::Scget_Left"));
  10235. sc = ScGetFrameCoord( pCoord, LEFT );
  10236. if (sc)
  10237. return sc;
  10238. return sc;
  10239. }
  10240. /*+-------------------------------------------------------------------------*
  10241. *
  10242. * CAMCView::Scput_Left
  10243. *
  10244. * PURPOSE: Implements Frame.Left property's Put method for view
  10245. *
  10246. * PARAMETERS:
  10247. * INT coord - value to set
  10248. *
  10249. * RETURNS:
  10250. * SC
  10251. *
  10252. *+-------------------------------------------------------------------------*/
  10253. SC CAMCView::Scput_Left ( INT coord )
  10254. {
  10255. DECLARE_SC(sc, TEXT("CAMCView::Scput_Left"));
  10256. sc = ScSetFrameCoord( coord, LEFT );
  10257. if (sc)
  10258. return sc;
  10259. return sc;
  10260. }
  10261. /*+-------------------------------------------------------------------------*
  10262. *
  10263. * CAMCView::Scget_Right
  10264. *
  10265. * PURPOSE: Implements Frame.Right property's Get method for view
  10266. *
  10267. * PARAMETERS:
  10268. * LPINT pCoord - storage for return value
  10269. *
  10270. * RETURNS:
  10271. * SC
  10272. *
  10273. *+-------------------------------------------------------------------------*/
  10274. SC CAMCView::Scget_Right ( LPINT pCoord)
  10275. {
  10276. DECLARE_SC(sc, TEXT("CAMCView::Scget_Right"));
  10277. sc = ScGetFrameCoord( pCoord, RIGHT );
  10278. if (sc)
  10279. return sc;
  10280. return sc;
  10281. }
  10282. /*+-------------------------------------------------------------------------*
  10283. *
  10284. * CAMCView::Scput_Right
  10285. *
  10286. * PURPOSE: Implements Frame.Right property's Put method for view
  10287. *
  10288. * PARAMETERS:
  10289. * INT coord - value to set
  10290. *
  10291. * RETURNS:
  10292. * SC
  10293. *
  10294. *+-------------------------------------------------------------------------*/
  10295. SC CAMCView::Scput_Right ( INT coord )
  10296. {
  10297. DECLARE_SC(sc, TEXT("CAMCView::Scput_Right"));
  10298. sc = ScSetFrameCoord( coord, RIGHT );
  10299. if (sc)
  10300. return sc;
  10301. return sc;
  10302. }
  10303. /*+-------------------------------------------------------------------------*
  10304. *
  10305. * CAMCView::Scget_Top
  10306. *
  10307. * PURPOSE: Implements Frame.Top property's Get method for view
  10308. *
  10309. * PARAMETERS:
  10310. * LPINT pCoord - storage for return value
  10311. *
  10312. * RETURNS:
  10313. * SC
  10314. *
  10315. *+-------------------------------------------------------------------------*/
  10316. SC CAMCView::Scget_Top ( LPINT pCoord)
  10317. {
  10318. DECLARE_SC(sc, TEXT("CAMCView::Scget_Top"));
  10319. sc = ScGetFrameCoord( pCoord, TOP );
  10320. if (sc)
  10321. return sc;
  10322. return sc;
  10323. }
  10324. /*+-------------------------------------------------------------------------*
  10325. *
  10326. * CAMCView::Scput_Top
  10327. *
  10328. * PURPOSE: Implements Frame.Top property's Put method for view
  10329. *
  10330. * PARAMETERS:
  10331. * INT coord - value to set
  10332. *
  10333. * RETURNS:
  10334. * SC
  10335. *
  10336. *+-------------------------------------------------------------------------*/
  10337. SC CAMCView::Scput_Top ( INT coord )
  10338. {
  10339. DECLARE_SC(sc, TEXT("CAMCView::Scput_Top"));
  10340. sc = ScSetFrameCoord( coord, TOP );
  10341. if (sc)
  10342. return sc;
  10343. return sc;
  10344. }
  10345. /*+-------------------------------------------------------------------------*
  10346. *
  10347. * CAMCView::Scget_Bottom
  10348. *
  10349. * PURPOSE: Implements Frame.Bottom property's Get method for view
  10350. *
  10351. * PARAMETERS:
  10352. * LPINT pCoord - storage for return value
  10353. *
  10354. * RETURNS:
  10355. * SC
  10356. *
  10357. *+-------------------------------------------------------------------------*/
  10358. SC CAMCView::Scget_Bottom ( LPINT pCoord)
  10359. {
  10360. DECLARE_SC(sc, TEXT("CAMCView::Scget_Bottom"));
  10361. sc = ScGetFrameCoord( pCoord, BOTTOM );
  10362. if (sc)
  10363. return sc;
  10364. return sc;
  10365. }
  10366. /*+-------------------------------------------------------------------------*
  10367. *
  10368. * CAMCView::Scput_Bottom
  10369. *
  10370. * PURPOSE: Implements Frame.Bottom property's Put method for view
  10371. *
  10372. * PARAMETERS:
  10373. * INT coord - value to set
  10374. *
  10375. * RETURNS:
  10376. * SC
  10377. *
  10378. *+-------------------------------------------------------------------------*/
  10379. SC CAMCView::Scput_Bottom ( INT coord )
  10380. {
  10381. DECLARE_SC(sc, TEXT("CAMCView::Scput_Bottom"));
  10382. sc = ScSetFrameCoord( coord, BOTTOM );
  10383. if (sc)
  10384. return sc;
  10385. return sc;
  10386. }
  10387. /*+-------------------------------------------------------------------------*
  10388. *
  10389. * CAMCView::ScSetViewExtensionFrame
  10390. *
  10391. * PURPOSE:
  10392. *
  10393. * PARAMETERS:
  10394. * INT top :
  10395. * INT left :
  10396. * INT bottom :
  10397. * INT right :
  10398. *
  10399. * RETURNS:
  10400. * SC
  10401. *
  10402. *+-------------------------------------------------------------------------*/
  10403. SC
  10404. CAMCView::ScSetViewExtensionFrame(bool bShowListView, INT top, INT left, INT bottom, INT right)
  10405. {
  10406. DECLARE_SC(sc, TEXT("CAMCView::ScSetViewExtensionFrame"))
  10407. /*
  10408. * this method is only available while a view extension is active
  10409. */
  10410. if (!m_fViewExtended)
  10411. return sc; // return silently. NOTE: This method will be removed shortly, as will the view extension hosted frame object,
  10412. // once mmc moves the mmcview behavior into the web host's element factory.
  10413. /*
  10414. * figure out the maximum bounding rectangle for the hosted view,
  10415. * mapped to view extension-relative coordinates
  10416. */
  10417. CRect rectBound;
  10418. CalcMaxHostedFrameRect (rectBound);
  10419. #ifdef DBG
  10420. CString strDebugMsg;
  10421. strDebugMsg.Format (_T("CAMCView::ScSetViewExtFrameCoord bound=(l=%d,t=%d,r=%d,b=%d), new = (l=%d,t=%d,r=%d,b=%d)"),
  10422. rectBound.left, rectBound.top, rectBound.right, rectBound.bottom,
  10423. left, top, right, bottom
  10424. );
  10425. #endif
  10426. /*
  10427. * make sure the requested coordinate is withing the permitted area
  10428. */
  10429. if (left < rectBound.left)
  10430. left = rectBound.left;
  10431. if (right > rectBound.right)
  10432. right = rectBound.right;
  10433. if (top < rectBound.top)
  10434. top = rectBound.top;
  10435. if (bottom > rectBound.bottom)
  10436. bottom = rectBound.bottom;
  10437. /*
  10438. * if we get here, the view extension-relative coordinate supplied
  10439. * is within the acceptable range, now we need to convert it to
  10440. * CAMCView-relative coordinates
  10441. */
  10442. CPoint pointTopLeft(left, top);
  10443. CPoint pointBottomRight(right, bottom);
  10444. if ( GetExStyle() & WS_EX_LAYOUTRTL )
  10445. {
  10446. // IE does not change left/right order on the RTL locales
  10447. // thus we need to mirror it's coordinates
  10448. // see windows bug #195094 ntbugs9 11/30/00
  10449. pointTopLeft.x = rectBound.left + (rectBound.right - right);
  10450. pointBottomRight.x = rectBound.left + (rectBound.right - left);
  10451. }
  10452. MapHostedFramePtToViewPt (pointTopLeft);
  10453. MapHostedFramePtToViewPt (pointBottomRight);
  10454. /*
  10455. * set the coordinates
  10456. */
  10457. CRect rectViewExtHostedFrame;
  10458. rectViewExtHostedFrame.left = pointTopLeft.x;
  10459. rectViewExtHostedFrame.right = pointBottomRight.x;
  10460. rectViewExtHostedFrame.top = pointTopLeft.y;
  10461. rectViewExtHostedFrame.bottom = pointBottomRight.y;
  10462. // move the window to the correct location
  10463. CWnd* pwndResult = GetPaneView(ePane_Results);
  10464. sc = ScCheckPointers(pwndResult);
  10465. if(sc)
  10466. return sc;
  10467. if (bShowListView)
  10468. pwndResult->ShowWindow(SW_SHOW);
  10469. ::MoveWindow(*pwndResult, rectViewExtHostedFrame.left, rectViewExtHostedFrame.top,
  10470. rectViewExtHostedFrame.right - rectViewExtHostedFrame.left,
  10471. rectViewExtHostedFrame.bottom - rectViewExtHostedFrame.top,
  10472. TRUE /*bRepaint*/);
  10473. return (sc);
  10474. }
  10475. /*+-------------------------------------------------------------------------*
  10476. * CAMCView::CalcMaxHostedFrameRect
  10477. *
  10478. * Returns the maximum rectangle that can be occupied by a view extension's
  10479. * hosted frame, normalized around (0,0).
  10480. *--------------------------------------------------------------------------*/
  10481. void CAMCView::CalcMaxHostedFrameRect (CRect& rect)
  10482. {
  10483. /*
  10484. * start with the result frame rectangle and inset it a little so
  10485. * we'll see the client edge provided by the view extension's web
  10486. * host view
  10487. */
  10488. rect = m_rectResultFrame;
  10489. rect.DeflateRect (m_sizEdge);
  10490. /*
  10491. * now normalize around (0,0)
  10492. */
  10493. rect.OffsetRect (-rect.TopLeft());
  10494. }
  10495. /*+-------------------------------------------------------------------------*
  10496. * CAMCView::MapViewPtToHostedFramePt
  10497. *
  10498. *
  10499. *--------------------------------------------------------------------------*/
  10500. void CAMCView::MapViewPtToHostedFramePt (CPoint& pt)
  10501. {
  10502. PointMapperWorker (pt, true);
  10503. }
  10504. /*+-------------------------------------------------------------------------*
  10505. * CAMCView::MapHostedFramePtToViewPt
  10506. *
  10507. *
  10508. *--------------------------------------------------------------------------*/
  10509. void CAMCView::MapHostedFramePtToViewPt (CPoint& pt)
  10510. {
  10511. PointMapperWorker (pt, false);
  10512. }
  10513. /*+-------------------------------------------------------------------------*
  10514. * CAMCView::MapHostedFramePtToViewPt
  10515. *
  10516. *
  10517. *--------------------------------------------------------------------------*/
  10518. void CAMCView::PointMapperWorker (CPoint& pt, bool fViewToHostedFrame)
  10519. {
  10520. int nMultiplier = (fViewToHostedFrame) ? -1 : 1;
  10521. /*
  10522. * adjust to the origin of the result frame rectangle and for the
  10523. * web host view's client edge
  10524. */
  10525. pt.Offset (nMultiplier * (m_rectResultFrame.left + m_sizEdge.cx),
  10526. nMultiplier * (m_rectResultFrame.top + m_sizEdge.cy));
  10527. }
  10528. /***************************************************************************\
  10529. *
  10530. * METHOD: CXMLWindowPlacement::Persist
  10531. *
  10532. * PURPOSE: Persists window placement settings
  10533. *
  10534. * PARAMETERS:
  10535. * CPersistor &persistor
  10536. *
  10537. * RETURNS:
  10538. * void
  10539. *
  10540. \***************************************************************************/
  10541. void CXMLWindowPlacement::Persist(CPersistor &persistor)
  10542. {
  10543. // create wrapper to persist flag values as strings
  10544. CXMLBitFlags wpFlagsPersistor(m_rData.flags, mappedWPFlags, countof(mappedWPFlags));
  10545. // persist the wrapper
  10546. persistor.PersistAttribute( XML_ATTR_WIN_PLACEMENT_FLAGS, wpFlagsPersistor );
  10547. // persist show command as literal
  10548. // create wrapper to persist enumeration values as strings
  10549. CXMLEnumeration showCmdPersistor(m_rData.showCmd, mappedSWCommands, countof(mappedSWCommands));
  10550. // persist the wrapper
  10551. persistor.PersistAttribute( XML_ATTR_SHOW_COMMAND, showCmdPersistor );
  10552. persistor.Persist( XMLPoint( XML_NAME_MIN_POSITION, m_rData.ptMinPosition ) );
  10553. persistor.Persist( XMLPoint( XML_NAME_MAX_POSITION, m_rData.ptMaxPosition ) );
  10554. persistor.Persist( XMLRect( XML_NAME_NORMAL_POSITION, m_rData.rcNormalPosition ) );
  10555. }
  10556. /***************************************************************************\
  10557. *
  10558. * METHOD: CAMCView::Scget_Document
  10559. *
  10560. * PURPOSE: implements View.Document property in object model
  10561. *
  10562. * PARAMETERS:
  10563. * PPDOCUMENT ppDocument [out] document to which the view belongs
  10564. *
  10565. * RETURNS:
  10566. * SC - result code
  10567. *
  10568. \***************************************************************************/
  10569. SC CAMCView::Scget_Document( PPDOCUMENT ppDocument )
  10570. {
  10571. DECLARE_SC(sc, TEXT("CAMCView::Scget_Document"));
  10572. // parameter check
  10573. sc = ScCheckPointers(ppDocument);
  10574. if (sc)
  10575. return sc;
  10576. // get the document
  10577. CAMCDoc* pDoc = GetDocument();
  10578. sc = ScCheckPointers(pDoc, E_UNEXPECTED);
  10579. if (sc)
  10580. return sc;
  10581. // construct com object
  10582. sc = pDoc->ScGetMMCDocument(ppDocument);
  10583. if (sc)
  10584. return sc;
  10585. return (sc);
  10586. }
  10587. /*******************************************************\
  10588. | helper function to avoid too many stack allocations
  10589. \*******************************************************/
  10590. static tstring W2T_ForLoop(const std::wstring& str)
  10591. {
  10592. #if defined(_UNICODE)
  10593. return str;
  10594. #else
  10595. USES_CONVERSION;
  10596. return W2CA(str.c_str());
  10597. #endif
  10598. }
  10599. /***************************************************************************\
  10600. *
  10601. * METHOD: CAMCView::ScAddFolderTabs
  10602. *
  10603. * PURPOSE: Collects view extensions and taskpads and displays them as tabs
  10604. *
  10605. * PARAMETERS:
  10606. * HNODE hNode - selected scope node
  10607. * const CLSID &guidTabToSelect - tab to select
  10608. *
  10609. * RETURNS:
  10610. * SC - result code
  10611. *
  10612. \***************************************************************************/
  10613. SC CAMCView::ScAddFolderTabs( HNODE hNode, const CLSID& guidTabToSelect )
  10614. {
  10615. DECLARE_SC(sc, TEXT("CAMCView::ScAddFolderTabs"));
  10616. sc = ScCheckPointers(m_pResultFolderTabView, E_UNEXPECTED);
  10617. if (sc)
  10618. return sc;
  10619. // cleanup urls
  10620. m_ViewExtensionURLs.clear();
  10621. // cleanup view tabs before we do anything else
  10622. m_pResultFolderTabView->DeleteAllItems();
  10623. // get the callback
  10624. INodeCallback* pNodeCallBack = GetNodeCallback();
  10625. sc = ScCheckPointers(pNodeCallBack, m_pResultFolderTabView, E_UNEXPECTED);
  10626. if (sc)
  10627. return sc;
  10628. // collect view extensions
  10629. CViewExtCollection vecExtensions;
  10630. CViewExtInsertIterator itExtensions(vecExtensions, vecExtensions.begin());
  10631. sc = pNodeCallBack->GetNodeViewExtensions(hNode, itExtensions);
  10632. if (sc)
  10633. {
  10634. sc.TraceAndClear();
  10635. vecExtensions.clear();
  10636. // continue anyway
  10637. }
  10638. // check if there is something to show
  10639. if(vecExtensions.size() == 0) // no tabs to show.
  10640. {
  10641. m_pResultFolderTabView->SetVisible(false);
  10642. }
  10643. else
  10644. {
  10645. bool bAddDefaultTab = true;
  10646. // add extensions
  10647. CViewExtCollection::iterator iterVE;
  10648. for(iterVE = vecExtensions.begin(); iterVE != vecExtensions.end(); ++iterVE)
  10649. {
  10650. tstring strName( W2T_ForLoop(iterVE->strName) );
  10651. m_pResultFolderTabView->AddItem(strName.c_str(), iterVE->viewID);
  10652. m_ViewExtensionURLs[iterVE->viewID] = W2T_ForLoop(iterVE->strURL);
  10653. // do not add the "normal" tab if we have a valid replacement for it
  10654. if (iterVE->bReplacesDefaultView)
  10655. bAddDefaultTab = false;
  10656. }
  10657. // add the default item.
  10658. if (bAddDefaultTab)
  10659. {
  10660. CStr strNormal;
  10661. strNormal.LoadString(GetStringModule(), IDS_NORMAL);
  10662. m_pResultFolderTabView->AddItem(strNormal, GUID_NULL);
  10663. }
  10664. // select required item and show tabs
  10665. int iIndex = m_pResultFolderTabView->SelectItemByClsid(guidTabToSelect);
  10666. if (iIndex < 0)
  10667. TraceError(_T("CAMCView::ScAddFolderTabs - failed to select requested folder"), SC(E_FAIL));
  10668. // no need for cotrol if we only have one tab
  10669. bool bMoreThanOneTab = (m_pResultFolderTabView->GetItemCount() > 1);
  10670. m_pResultFolderTabView->SetVisible(bMoreThanOneTab);
  10671. }
  10672. // lookup view extension URL
  10673. CViewExtensionURLs::iterator itVE = m_ViewExtensionURLs.find(guidTabToSelect);
  10674. LPCTSTR url = (itVE != m_ViewExtensionURLs.end()) ? itVE->second.c_str() : NULL;
  10675. // apply URL
  10676. sc = ScApplyViewExtension(url);
  10677. if (sc)
  10678. sc.TraceAndClear();
  10679. RecalcLayout();
  10680. return sc;
  10681. }
  10682. /***************************************************************************\
  10683. *
  10684. * METHOD: CAMCView::Scget_ControlObject
  10685. *
  10686. * PURPOSE: returns IDispatch of embeded OCX control
  10687. * implements View.ControlObject property
  10688. *
  10689. * PARAMETERS:
  10690. * PPDISPATCH ppControl [out] control's interface
  10691. *
  10692. * RETURNS:
  10693. * SC - result code
  10694. *
  10695. \***************************************************************************/
  10696. SC CAMCView::Scget_ControlObject( PPDISPATCH ppControl)
  10697. {
  10698. DECLARE_SC(sc, TEXT("CAMCView::Scget_ControlObject"));
  10699. // parameter check
  10700. sc = ScCheckPointers(ppControl);
  10701. if (sc)
  10702. return sc;
  10703. // init out param
  10704. *ppControl = NULL;
  10705. // have a OCX view?
  10706. if ( (! HasOCX()) || (m_pOCXHostView == NULL))
  10707. return sc.FromMMC( MMC_E_NO_OCX_IN_VIEW );
  10708. // get the control's interface
  10709. CComQIPtr<IDispatch> spDispatch = m_pOCXHostView->GetIUnknown();
  10710. if (spDispatch == NULL)
  10711. return sc = E_NOINTERFACE;
  10712. // return the pointer
  10713. *ppControl = spDispatch.Detach();
  10714. return sc;
  10715. }
  10716. //+-------------------------------------------------------------------
  10717. //
  10718. // Member: CAMCView::ScTreeViewSelectionActivate
  10719. //
  10720. // Synopsis: Only the list(/Web/OCX) or the tree can be "active" from the point
  10721. // of view of selected items and MMCN_SELECT. This is not
  10722. // the same as the MFC concept of "active view". There are a couple
  10723. // of views that cannot be active in this sense, such as the taskpad
  10724. // and tab views.
  10725. // When the active view (according to this definition) changes, this
  10726. // function is called. Thus, ScTreeViewSelectionActivate and
  10727. // ScListViewSelectionActivate/ScSpecialResultpaneSelectionActivate
  10728. // are always called in pairs when the activation changes, one to handle
  10729. // deactivation, and one to handle activation.
  10730. //
  10731. // Consider the following scenario
  10732. // 1) The tree view has (MFC/windows style) focus.
  10733. // 2) The user clicks on the taskpad view
  10734. // Result - selection activation does not change from the tree. All verbs
  10735. // still correspond to the selected tree item.
  10736. // 3) The user clicks on the folder view
  10737. // Result - once again, selection activation does not chang
  10738. // 4) The user clicks on one of the result views eg the list
  10739. // Result - ScTreeViewSelectionActivate(false) and ScListViewSelectionActivate(true)
  10740. // Thus verbs and the toolbar now correspond to the selected list item(s).
  10741. // 5) The user clicks on the taskpad view.
  10742. // Result - as in step 2, nothing happens
  10743. // 6) The user clicks on the result view
  10744. // Result - because the active view has not changed, nothing happens.
  10745. //
  10746. // Arguments: [bActivate] - [in]
  10747. //
  10748. // Returns: SC
  10749. //
  10750. //--------------------------------------------------------------------
  10751. SC CAMCView::ScTreeViewSelectionActivate (bool bActivate)
  10752. {
  10753. DECLARE_SC(sc, _T("CAMCView::ScTreeViewSelectionActivate"));
  10754. sc = ScCheckPointers(m_pTreeCtrl, E_UNEXPECTED);
  10755. if (sc)
  10756. return sc;
  10757. // 1. Setup the SELECTINFO
  10758. SELECTIONINFO selInfo;
  10759. ZeroMemory(&selInfo, sizeof(selInfo));
  10760. selInfo.m_bScope = TRUE;
  10761. selInfo.m_pView = NULL;
  10762. selInfo.m_bDueToFocusChange = TRUE;
  10763. if (HasOCX())
  10764. {
  10765. selInfo.m_bResultPaneIsOCX = true;
  10766. selInfo.m_lCookie = LVDATA_CUSTOMOCX;
  10767. }
  10768. else if (HasWebBrowser())
  10769. {
  10770. selInfo.m_bResultPaneIsWeb = TRUE;
  10771. selInfo.m_lCookie = LVDATA_CUSTOMWEB;
  10772. }
  10773. HTREEITEM htiSelected = m_pTreeCtrl->GetSelectedItem();
  10774. HNODE hSelectedNode = (htiSelected != NULL) ? m_pTreeCtrl->GetItemNode (htiSelected) : NULL;
  10775. // insure that this is the active view when we have the focus
  10776. ASSERT ( ( (bActivate) && (GetParentFrame()->GetActiveView () == m_pTreeCtrl) ) ||
  10777. ( (!bActivate) && (GetParentFrame()->GetActiveView () != m_pTreeCtrl) ) );
  10778. if (hSelectedNode != NULL)
  10779. {
  10780. // Send select notification.
  10781. sc = ScNotifySelect ( GetNodeCallback(), hSelectedNode,
  10782. false /*fMultiSelect*/, bActivate, &selInfo);
  10783. if (sc)
  10784. return sc;
  10785. }
  10786. else if ( (htiSelected == NULL) && (bActivate) )
  10787. {
  10788. m_pTreeCtrl->SelectItem (m_pTreeCtrl->GetRootItem());
  10789. }
  10790. return (sc);
  10791. }
  10792. //+-------------------------------------------------------------------
  10793. //
  10794. // Member: CAMCView::ScOnTreeViewActivated
  10795. //
  10796. // Synopsis: Observer implementation for tree-view activation.
  10797. //
  10798. // Arguments:
  10799. //
  10800. // Returns: SC
  10801. //
  10802. //--------------------------------------------------------------------
  10803. SC CAMCView::ScOnTreeViewActivated ()
  10804. {
  10805. DECLARE_SC(sc, _T("CAMCView::ScOnTreeViewActivated"));
  10806. if (m_eCurrentActivePane == eActivePaneScope) // Scope pane is already active so return.
  10807. return sc;
  10808. #ifdef DBG
  10809. Trace (tagViewActivation, _T("Deactivate %s in result pane Activate Scope pane\n"),
  10810. HasListOrListPad() ? _T("ListView") : (HasOCX() ? _T("OCX") : _T("WebBrowser")));
  10811. #endif
  10812. if (m_eCurrentActivePane == eActivePaneResult)
  10813. {
  10814. // Send deactivate to result.
  10815. if (HasListOrListPad())
  10816. sc = ScListViewSelectionActivate (false);
  10817. else if (HasOCX() || HasWebBrowser())
  10818. sc = ScSpecialResultpaneSelectionActivate(false);
  10819. else
  10820. return (sc = E_UNEXPECTED);
  10821. if (sc)
  10822. sc.TraceAndClear();
  10823. }
  10824. // Send select to scope.
  10825. m_eCurrentActivePane = eActivePaneScope;
  10826. sc = ScTreeViewSelectionActivate(true);
  10827. if (sc)
  10828. return sc;
  10829. return (sc);
  10830. }
  10831. //+-------------------------------------------------------------------
  10832. //
  10833. // Member: CAMCView::ScOnListViewActivated
  10834. //
  10835. // Synopsis: Observer implementation for list-view activation.
  10836. //
  10837. // Arguments:
  10838. //
  10839. // Returns: SC
  10840. //
  10841. //--------------------------------------------------------------------
  10842. SC CAMCView::ScOnListViewActivated ()
  10843. {
  10844. DECLARE_SC(sc, _T("CAMCView::ScOnListViewActivated"));
  10845. if (m_eCurrentActivePane == eActivePaneResult) // Result pane is already active so return.
  10846. return sc;
  10847. #ifdef DBG
  10848. Trace (tagViewActivation, _T("Deactivate Scope pane Activate ListView in Result pane\n"));
  10849. #endif
  10850. if (m_eCurrentActivePane == eActivePaneScope)
  10851. {
  10852. // Send deactivate to scope.
  10853. sc = ScTreeViewSelectionActivate(false);
  10854. if (sc)
  10855. sc.TraceAndClear();
  10856. }
  10857. // Send activate to list.
  10858. m_eCurrentActivePane = eActivePaneResult;
  10859. ASSERT(HasListOrListPad());
  10860. sc = ScListViewSelectionActivate (true);
  10861. if (sc)
  10862. sc.TraceAndClear();
  10863. return (sc);
  10864. }
  10865. /*+-------------------------------------------------------------------------*
  10866. *
  10867. * CAMCView::ScOnListViewItemUpdated
  10868. *
  10869. * PURPOSE: called when an item is updated. This method fires an event to all COM observers.
  10870. *
  10871. * PARAMETERS:
  10872. * int nIndex :
  10873. *
  10874. * RETURNS:
  10875. * SC
  10876. *
  10877. *+-------------------------------------------------------------------------*/
  10878. SC
  10879. CAMCView::ScOnListViewItemUpdated (int nIndex)
  10880. {
  10881. DECLARE_SC(sc, _T("CAMCView::ScOnListViewItemUpdated"));
  10882. // fire event
  10883. sc = ScFireEvent(CAMCViewObserver::ScOnListViewItemUpdated, this, nIndex);
  10884. if (sc)
  10885. return sc;
  10886. return sc;
  10887. }
  10888. //+-------------------------------------------------------------------
  10889. //
  10890. // Member: CAMCView::ScOnOCXHostActivated
  10891. //
  10892. // Synopsis: Observer implementation for ocx or web view activation.
  10893. //
  10894. // Arguments:
  10895. //
  10896. // Returns: SC
  10897. //
  10898. //--------------------------------------------------------------------
  10899. SC CAMCView::ScOnOCXHostActivated ()
  10900. {
  10901. DECLARE_SC(sc, _T("CAMCView::ScOnOCXHostActivated"));
  10902. if (m_eCurrentActivePane == eActivePaneResult) // Result pane is already active so return.
  10903. return sc;
  10904. #ifdef DBG
  10905. Trace (tagViewActivation, _T("Deactivate Scope pane Activate %s in Result pane\n"),
  10906. HasOCX() ? _T("OCX") : _T("WebBrowser"));
  10907. #endif
  10908. if (m_eCurrentActivePane == eActivePaneScope)
  10909. {
  10910. // Send deactivate to scope.
  10911. sc = ScTreeViewSelectionActivate(false);
  10912. if (sc)
  10913. sc.TraceAndClear();
  10914. }
  10915. // Send select to ocx or web view.
  10916. m_eCurrentActivePane = eActivePaneResult;
  10917. ASSERT(HasOCX() || HasWebBrowser());
  10918. sc = ScSpecialResultpaneSelectionActivate(true);
  10919. if (sc)
  10920. sc.TraceAndClear();
  10921. return (sc);
  10922. }