Leaked source code of windows server 2003
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.

1124 lines
33 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // SplitFrm.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CSplitterFrame class.
  10. //
  11. // Author:
  12. // David Potter (davidp) May 1, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "ConstDef.h"
  21. #include "SplitFrm.h"
  22. #include "MainFrm.h"
  23. #include "TreeView.h"
  24. #include "ListView.h"
  25. #include "TraceTag.h"
  26. #include "ExtDll.h"
  27. #include "ClusItem.h"
  28. #include "ClusDoc.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. /////////////////////////////////////////////////////////////////////////////
  35. // Global Variables
  36. /////////////////////////////////////////////////////////////////////////////
  37. #ifdef _DEBUG
  38. CTraceTag g_tagSplitFrame(_T("UI"), _T("SPLITTER FRAME"), 0);
  39. CTraceTag g_tagSplitFrameMenu(_T("Menu"), _T("SPLITTER FRAME MENU"), 0);
  40. CTraceTag g_tagSplitFrameDrag(_T("Drag&Drop"), _T("SPLITTER FRAME DRAG"), 0);
  41. CTraceTag g_tagSplitFrameDragMouse(_T("Drag&Drop"), _T("SPLITTER FRAME DRAG MOUSE"), 0);
  42. #endif
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CSplitterFrame
  45. /////////////////////////////////////////////////////////////////////////////
  46. IMPLEMENT_DYNCREATE(CSplitterFrame, CMDIChildWnd)
  47. /////////////////////////////////////////////////////////////////////////////
  48. // Message Maps
  49. BEGIN_MESSAGE_MAP(CSplitterFrame, CMDIChildWnd)
  50. //{{AFX_MSG_MAP(CSplitterFrame)
  51. ON_WM_CONTEXTMENU()
  52. ON_WM_DESTROY()
  53. ON_UPDATE_COMMAND_UI(ID_VIEW_LARGE_ICONS, OnUpdateLargeIconsView)
  54. ON_UPDATE_COMMAND_UI(ID_VIEW_SMALL_ICONS, OnUpdateSmallIconsView)
  55. ON_UPDATE_COMMAND_UI(ID_VIEW_LIST, OnUpdateListView)
  56. ON_UPDATE_COMMAND_UI(ID_VIEW_DETAILS, OnUpdateDetailsView)
  57. ON_COMMAND(ID_VIEW_LARGE_ICONS, OnLargeIconsView)
  58. ON_COMMAND(ID_VIEW_SMALL_ICONS, OnSmallIconsView)
  59. ON_COMMAND(ID_VIEW_LIST, OnListView)
  60. ON_COMMAND(ID_VIEW_DETAILS, OnDetailsView)
  61. ON_WM_MOUSEMOVE()
  62. ON_WM_LBUTTONUP()
  63. ON_WM_RBUTTONUP()
  64. //}}AFX_MSG_MAP
  65. #ifdef _DEBUG
  66. ON_WM_MDIACTIVATE()
  67. #endif
  68. ON_MESSAGE(WM_CAM_UNLOAD_EXTENSION, OnUnloadExtension)
  69. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 0, OnUpdateExtMenu)
  70. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 1, OnUpdateExtMenu)
  71. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 2, OnUpdateExtMenu)
  72. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 3, OnUpdateExtMenu)
  73. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 4, OnUpdateExtMenu)
  74. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 5, OnUpdateExtMenu)
  75. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 6, OnUpdateExtMenu)
  76. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 7, OnUpdateExtMenu)
  77. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 8, OnUpdateExtMenu)
  78. ON_UPDATE_COMMAND_UI(CAEXT_MENU_FIRST_ID + 9, OnUpdateExtMenu)
  79. END_MESSAGE_MAP()
  80. /////////////////////////////////////////////////////////////////////////////
  81. //++
  82. //
  83. // CSplitterFrame::CSplitterFrame
  84. //
  85. // Routine Description:
  86. // Default constructor.
  87. //
  88. // Arguments:
  89. // None.
  90. //
  91. // Return Value:
  92. // None.
  93. //
  94. //--
  95. /////////////////////////////////////////////////////////////////////////////
  96. CSplitterFrame::CSplitterFrame(void)
  97. {
  98. m_pdoc = NULL;
  99. m_iFrame = 0;
  100. m_pext = NULL;
  101. // Initialize drag & drop.
  102. m_bDragging = FALSE;
  103. m_pimagelist = NULL;
  104. m_pciDrag = NULL;
  105. } //*** CSplitterFrame::CSplitterFrame()
  106. /////////////////////////////////////////////////////////////////////////////
  107. //++
  108. //
  109. // CSplitterFrame::CSplitterFrame
  110. //
  111. // Routine Description:
  112. // Destructor.
  113. //
  114. // Arguments:
  115. // None.
  116. //
  117. // Return Value:
  118. // None.
  119. //
  120. //--
  121. /////////////////////////////////////////////////////////////////////////////
  122. CSplitterFrame::~CSplitterFrame(void)
  123. {
  124. // Cleanup after ourselves.
  125. if ((Pdoc() != NULL) && (Pdoc()->PtiCluster() != NULL))
  126. Pdoc()->PtiCluster()->PreRemoveFromFrameWithChildren(this);
  127. // Cleanup any extensions.
  128. delete Pext();
  129. } //*** CSplitterFrame::~CSplitterFrame()
  130. #ifdef _DEBUG
  131. void CSplitterFrame::AssertValid(void) const
  132. {
  133. CMDIChildWnd::AssertValid();
  134. } //*** CSplitterFrame::AssertValid()
  135. void CSplitterFrame::Dump(CDumpContext& dc) const
  136. {
  137. CMDIChildWnd::Dump(dc);
  138. } //*** CSplitterFrame::Dump()
  139. #endif //_DEBUG
  140. /////////////////////////////////////////////////////////////////////////////
  141. //++
  142. //
  143. // CSplitterFrame::CalculateFrameNumber
  144. //
  145. // Routine Description:
  146. // Calculate the number of this frame connected to the document. This
  147. // should only be called before the views have been created.
  148. //
  149. // Arguments:
  150. // None.
  151. //
  152. // Return Value:
  153. // None.
  154. //
  155. //--
  156. /////////////////////////////////////////////////////////////////////////////
  157. void CSplitterFrame::CalculateFrameNumber(void)
  158. {
  159. POSITION pos;
  160. CView * pview;
  161. if (Pdoc() != NULL)
  162. {
  163. // At least frame # 1 'cause we exist.
  164. m_iFrame = 1;
  165. pos = Pdoc()->GetFirstViewPosition();
  166. while (pos != NULL)
  167. {
  168. pview = Pdoc()->GetNextView(pos);
  169. ASSERT_VALID(pview);
  170. if (pview->IsKindOf(RUNTIME_CLASS(CClusterTreeView)))
  171. {
  172. if (pview->GetParentFrame() == this)
  173. break;
  174. m_iFrame++;
  175. } // if: found another tree view
  176. } // while: more views in the list
  177. } // if: document associated with frame
  178. } //*** CSplitterFrame::CalculateFrameNumber()
  179. /////////////////////////////////////////////////////////////////////////////
  180. //++
  181. //
  182. // CSplitterFrame::InitFrame
  183. //
  184. // Routine Description:
  185. // Called to initialize the frame after being initially created and
  186. // after the document has been initialized.
  187. //
  188. // Arguments:
  189. // pDoc Document associated with the frame.
  190. //
  191. // Return Value:
  192. // None.
  193. //
  194. //--
  195. /////////////////////////////////////////////////////////////////////////////
  196. void CSplitterFrame::InitFrame(IN OUT CClusterDoc * pDoc)
  197. {
  198. m_pdoc = pDoc;
  199. ASSERT_VALID(Pdoc());
  200. // Calculate the number of our frame so the views can use it.
  201. CalculateFrameNumber();
  202. // Read from the profile.
  203. {
  204. CString strSection;
  205. strSection.Format(REGPARAM_CONNECTIONS _T("\\%s"), Pdoc()->StrNode());
  206. // Set window placement.
  207. {
  208. WINDOWPLACEMENT wp;
  209. if (ReadWindowPlacement(&wp, strSection, NFrameNumber()))
  210. SetWindowPlacement(&wp);
  211. } // Set window placement
  212. // Set splitter bar position.
  213. {
  214. CString strValueName;
  215. CString strPosition;
  216. int nCurWidth;
  217. int nMaxWidth;
  218. int nRead;
  219. try
  220. {
  221. ConstructProfileValueName(strValueName, REGPARAM_SPLITTER_BAR_POS);
  222. strPosition = AfxGetApp()->GetProfileString(strSection, strValueName);
  223. nRead = _stscanf(strPosition, _T("%d,%d"), &nCurWidth, &nMaxWidth);
  224. if (nRead == 2)
  225. {
  226. m_wndSplitter.SetColumnInfo(0, nCurWidth, nMaxWidth);
  227. m_wndSplitter.RecalcLayout();
  228. } // if: correct number of parameters specified
  229. } // try
  230. catch (CException * pe)
  231. {
  232. pe->Delete();
  233. } // catch: CException
  234. } // Save the splitter bar position
  235. // Set the view style of the list view.
  236. {
  237. DWORD dwView;
  238. CString strValueName;
  239. try
  240. {
  241. // Construct the value name.
  242. ConstructProfileValueName(strValueName, REGPARAM_VIEW);
  243. // Read the view setting.
  244. dwView = AfxGetApp()->GetProfileInt(strSection, strValueName, (LVS_ICON | LVS_REPORT));
  245. PviewList()->SetView(dwView);
  246. } // try
  247. catch (CException * pe)
  248. {
  249. pe->Delete();
  250. } // catch: CException
  251. } // Set the view style of the list view
  252. } // Read from the profile
  253. } //*** CSplitterFrame::InitFrame()
  254. /////////////////////////////////////////////////////////////////////////////
  255. //++
  256. //
  257. // CSplitterFrame::OnCreateClient
  258. //
  259. // Routine Description:
  260. // Called to create the client views for the frame. Here we create
  261. // a splitter window with two views -- a tree view and a list view.
  262. //
  263. // Arguments:
  264. // lpcs Pointer to a CREATESTRUCT.
  265. // pContext Pointer to a create context.
  266. //
  267. // Return Value:
  268. // TRUE Client created successfully.
  269. // FALSE Failed to create client.
  270. //
  271. //--
  272. /////////////////////////////////////////////////////////////////////////////
  273. BOOL CSplitterFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
  274. {
  275. // Create a splitter window with 1 row & 2 columns.
  276. if (!m_wndSplitter.CreateStatic(this, 1, 2))
  277. {
  278. Trace(g_tagSplitFrame, _T("Failed to CreateStaticSplitter"));
  279. return FALSE;
  280. } // if: error creating splitter window
  281. // Add the first splitter pane.
  282. if (!m_wndSplitter.CreateView(0, 0, pContext->m_pNewViewClass, CSize(200, 50), pContext))
  283. {
  284. Trace(g_tagSplitFrame, _T("Failed to create first pane"));
  285. return FALSE;
  286. } // if: error creating first splitter pane
  287. // Add the second splitter pane.
  288. if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CClusterListView), CSize(0, 0), pContext))
  289. {
  290. Trace(g_tagSplitFrame, _T("Failed to create second pane"));
  291. return FALSE;
  292. } // if: error creating second pane
  293. // Activate the tree view.
  294. // SetActiveView((CView *) PviewTree());
  295. // If this is not the first frame on the document, initialize the frame.
  296. {
  297. CClusterDoc * pdoc = (CClusterDoc *) pContext->m_pCurrentDoc;
  298. if (pdoc->StrNode().GetLength() > 0)
  299. InitFrame(pdoc);
  300. } // If this is not the first frame on the document, initialize the frame
  301. return TRUE;
  302. } //*** CSplitterFrame::OnCreateClient()
  303. /////////////////////////////////////////////////////////////////////////////
  304. //++
  305. //
  306. // CSplitterFrame::ConstructProfileValueName
  307. //
  308. // Routine Description:
  309. // Construct the name of a value that is to be written to the user's
  310. // profile.
  311. //
  312. // Arguments:
  313. // rstrName [OUT] String in which to return the constructed name.
  314. // pszPrefix [IN] String to prefix the name with.
  315. //
  316. // Return Value:
  317. // None.
  318. //
  319. //--
  320. /////////////////////////////////////////////////////////////////////////////
  321. void CSplitterFrame::ConstructProfileValueName(
  322. OUT CString & rstrName,
  323. IN LPCTSTR pszPrefix
  324. ) const
  325. {
  326. ASSERT(pszPrefix != NULL);
  327. // Construct the name of the value to read.
  328. if (NFrameNumber() <= 1)
  329. rstrName = pszPrefix;
  330. else
  331. rstrName.Format(_T("%s-%d"), pszPrefix, NFrameNumber());
  332. } //*** CSplitterFrame::ConstructProfileValueName()
  333. /////////////////////////////////////////////////////////////////////////////
  334. //++
  335. //
  336. // CSplitterFrame::GetMessageString
  337. //
  338. // Routine Description:
  339. // Get a string for a command ID.
  340. //
  341. // Arguments:
  342. // nID [IN] Command ID for which a string should be returned.
  343. // rMessage [OUT] String in which to return the message.
  344. //
  345. // Return Value:
  346. // None.
  347. //
  348. //--
  349. /////////////////////////////////////////////////////////////////////////////
  350. void CSplitterFrame::GetMessageString(UINT nID, CString& rMessage) const
  351. {
  352. BOOL bHandled = FALSE;
  353. if ((Pext() != NULL)
  354. && (CAEXT_MENU_FIRST_ID <= nID))
  355. bHandled = Pext()->BGetCommandString(nID, rMessage);
  356. if (!bHandled)
  357. CMDIChildWnd::GetMessageString(nID, rMessage);
  358. } //*** CSplitterFrame::GetMessageString()
  359. /////////////////////////////////////////////////////////////////////////////
  360. //++
  361. //
  362. // CSplitterFrame::OnContextMenu
  363. //
  364. // Routine Description:
  365. // Handler for the WM_CONTEXTMENU method.
  366. //
  367. // Arguments:
  368. // pWnd Window in which the user right clicked the mouse.
  369. // point Position of the cursor, in screen coordinates.
  370. //
  371. // Return Value:
  372. // None.
  373. //
  374. //--
  375. /////////////////////////////////////////////////////////////////////////////
  376. void CSplitterFrame::OnContextMenu(CWnd * pWnd, CPoint point)
  377. {
  378. CView * pviewActive = GetActiveView();
  379. CMenu * pmenu = NULL;
  380. CClusterItem * pci = NULL;
  381. Trace(g_tagSplitFrame, _T("OnContextMenu()"));
  382. if (!BDragging())
  383. {
  384. if (pviewActive == PviewTree())
  385. pmenu = PviewTree()->PmenuPopup(point, pci);
  386. else if (pviewActive == PviewList())
  387. pmenu = PviewList()->PmenuPopup(point, pci);
  388. if (pmenu == NULL)
  389. pmenu = PmenuPopup();
  390. } // if: not dragging
  391. if (pmenu != NULL)
  392. {
  393. // If there is an extension already loaded, unload it.
  394. delete Pext();
  395. m_pext = NULL;
  396. // If there is an extension for this item, load it.
  397. if ((pci != NULL)
  398. && (pci->PlstrExtensions() != NULL)
  399. && (pci->PlstrExtensions()->GetCount() > 0))
  400. {
  401. CWaitCursor wc;
  402. try
  403. {
  404. m_pext = new CExtensions;
  405. if ( m_pext == NULL )
  406. {
  407. AfxThrowMemoryException();
  408. } // if: error allocating the extensions object
  409. Pext()->AddContextMenuItems(
  410. pmenu->GetSubMenu(0),
  411. *pci->PlstrExtensions(),
  412. pci
  413. );
  414. } // try
  415. catch (CException * pe)
  416. {
  417. #ifdef _DEBUG
  418. TCHAR szError[256];
  419. pe->GetErrorMessage(szError, sizeof(szError) / sizeof(TCHAR));
  420. Trace(g_tagError, _T("CSplitterFrame::OnContextMenu() - Error loading extension DLL - %s"), szError);
  421. #endif
  422. pe->Delete();
  423. delete Pext();
  424. m_pext = NULL;
  425. } // catch: CException
  426. } // if: this item has an extension
  427. // Display the menu.
  428. if (!pmenu->GetSubMenu(0)->TrackPopupMenu(
  429. TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  430. point.x,
  431. point.y,
  432. AfxGetMainWnd()
  433. ))
  434. {
  435. delete Pext();
  436. m_pext = NULL;
  437. } // if: unsuccessfully displayed the menu
  438. else if (Pext() != NULL)
  439. PostMessage(WM_CAM_UNLOAD_EXTENSION, NULL, NULL);;
  440. pmenu->DestroyMenu();
  441. delete pmenu;
  442. } // if: there is a menu to display
  443. } //*** CSplitterFrame::OnContextMenu()
  444. /////////////////////////////////////////////////////////////////////////////
  445. //++
  446. //
  447. // CSplitterFrame::PmenuPopup
  448. //
  449. // Routine Description:
  450. // Returns a popup menu.
  451. //
  452. // Arguments:
  453. // None.
  454. //
  455. // Return Value:
  456. // pmenu A popup menu for the item.
  457. //
  458. //--
  459. /////////////////////////////////////////////////////////////////////////////
  460. CMenu * CSplitterFrame::PmenuPopup( void ) const
  461. {
  462. CMenu * pmenu;
  463. // Load the menu.
  464. pmenu = new CMenu;
  465. if ( pmenu == NULL )
  466. {
  467. AfxThrowMemoryException();
  468. } // if: error allocating the menu
  469. if ( ! pmenu->LoadMenu( IDM_VIEW_POPUP ) )
  470. {
  471. delete pmenu;
  472. pmenu = NULL;
  473. } // if: error loading the menu
  474. return pmenu;
  475. } //*** CSplitterFrame::PmenuPopup()
  476. /////////////////////////////////////////////////////////////////////////////
  477. //++
  478. //
  479. // CSplitterFrame::OnCmdMsg
  480. //
  481. // Routine Description:
  482. // Processes command messages. If an extension DLL is loaded and the
  483. // message is a command selection, pass it on to the DLL.
  484. //
  485. // Arguments:
  486. // nID [IN] Command ID.
  487. // nCode [IN] Notification code.
  488. // pExtra [IN OUT] Used according to the value of nCode.
  489. // pHandlerInfo [OUT] ???
  490. //
  491. // Return Value:
  492. // TRUE Message has been handled.
  493. // FALSE Message has NOT been handled.
  494. //
  495. //--
  496. /////////////////////////////////////////////////////////////////////////////
  497. BOOL CSplitterFrame::OnCmdMsg(
  498. UINT nID,
  499. int nCode,
  500. void * pExtra,
  501. AFX_CMDHANDLERINFO * pHandlerInfo
  502. )
  503. {
  504. BOOL bHandled = FALSE;
  505. // If there is an extension DLL loaded, see if it wants to handle this message.
  506. if ((Pext() != NULL) && (nCode == 0))
  507. {
  508. Trace(g_tagSplitFrame, _T("OnCmdMsg() - Passing message to extension (ID = %d)"), nID);
  509. bHandled = Pext()->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  510. // Unload the extension DLL if there is one loaded.
  511. if (bHandled)
  512. {
  513. delete Pext();
  514. m_pext = NULL;
  515. } // if: message was handled
  516. } // if: there is an extension DLL loaded
  517. // if ((CAEXT_MENU_FIRST_ID <= nID) && (nID <= CAEXT_MENU_LAST_ID))
  518. // Trace(g_tagSplitFrame, _T("CSplitterFrame::OnCmdMsg() - nID = %d, nCode = 0x%08.8x, pExtra = 0x%08.8x\n"), nID, nCode, pExtra);
  519. if (!bHandled)
  520. bHandled = CMDIChildWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  521. return bHandled;
  522. } //*** CSplitterFrame::OnCmdMsg()
  523. /////////////////////////////////////////////////////////////////////////////
  524. //++
  525. //
  526. // CSplitterFrame::OnUpdateExtMenu
  527. //
  528. // Routine Description:
  529. // Determines whether extension menu items should be enabled or not.
  530. //
  531. // Arguments:
  532. // pCmdUI [IN OUT] Command routing object.
  533. //
  534. // Return Value:
  535. // None.
  536. //
  537. //--
  538. /////////////////////////////////////////////////////////////////////////////
  539. void CSplitterFrame::OnUpdateExtMenu(CCmdUI * pCmdUI)
  540. {
  541. if (Pext() != NULL)
  542. Pext()->OnUpdateCommand(pCmdUI);
  543. } //*** CSplitterFrame::OnUpdateExtMenu()
  544. /////////////////////////////////////////////////////////////////////////////
  545. //++
  546. //
  547. // CSplitterFrame::OnUnloadExtension
  548. //
  549. // Routine Description:
  550. // Handler for the WM_CAM_UNLOAD_EXTENSION message.
  551. //
  552. // Arguments:
  553. // wparam 1st parameter.
  554. // lparam 2nd parameter.
  555. //
  556. // Return Value:
  557. // ERROR_SUCCESS
  558. //
  559. //--
  560. /////////////////////////////////////////////////////////////////////////////
  561. LRESULT CSplitterFrame::OnUnloadExtension(WPARAM wparam, LPARAM lparam)
  562. {
  563. Trace(g_tagSplitFrame, _T("OnUnloadExtension() - m_pext = 0x%08.8x"), Pext());
  564. delete Pext();
  565. m_pext = NULL;
  566. return ERROR_SUCCESS;
  567. } //*** CSplitterFrame::OnUnloadExtension()
  568. /////////////////////////////////////////////////////////////////////////////
  569. //++
  570. //
  571. // CSplitterFrame::OnDestroy
  572. //
  573. // Routine Description:
  574. // Handler method for the WM_DESTROY message.
  575. //
  576. // Arguments:
  577. // None.
  578. //
  579. // Return Value:
  580. // None.
  581. //
  582. //--
  583. /////////////////////////////////////////////////////////////////////////////
  584. void CSplitterFrame::OnDestroy(void)
  585. {
  586. // Display information about the current menu.
  587. TraceMenu(g_tagSplitFrameMenu, AfxGetMainWnd()->GetMenu(), _T("Menu before child wnd destroyed: "));
  588. // Save current settings.
  589. if (Pdoc() != NULL)
  590. {
  591. CString strSection;
  592. // Construct the section name.
  593. ASSERT_VALID(Pdoc());
  594. strSection.Format(REGPARAM_CONNECTIONS _T("\\%s"), Pdoc()->StrNode());
  595. // Save the current window position information.
  596. {
  597. WINDOWPLACEMENT wp;
  598. wp.length = sizeof wp;
  599. if (GetWindowPlacement(&wp))
  600. {
  601. wp.flags = 0;
  602. if (IsZoomed())
  603. wp.flags |= WPF_RESTORETOMAXIMIZED;
  604. // and write it to the .INI file
  605. WriteWindowPlacement(&wp, strSection, NFrameNumber());
  606. } // if: window placement retrieved successfully
  607. } // Save the current window position information
  608. // Save the splitter bar position.
  609. {
  610. CString strValueName;
  611. CString strPosition;
  612. int nCurWidth;
  613. int nMaxWidth;
  614. m_wndSplitter.GetColumnInfo(0, nCurWidth, nMaxWidth);
  615. ConstructProfileValueName(strValueName, REGPARAM_SPLITTER_BAR_POS);
  616. strPosition.Format(_T("%d,%d"), nCurWidth, nMaxWidth);
  617. AfxGetApp()->WriteProfileString(strSection, strValueName, strPosition);
  618. } // Save the splitter bar position
  619. // Save the current list view style.
  620. {
  621. DWORD dwView;
  622. CString strValueName;
  623. // Construct the value name.
  624. ConstructProfileValueName(strValueName, REGPARAM_VIEW);
  625. // Save the view setting.
  626. dwView = PviewList()->GetView();
  627. AfxGetApp()->WriteProfileInt(strSection, strValueName, dwView);
  628. } // Save the current list view style
  629. } // if: document is valid
  630. // Call the base class method.
  631. CMDIChildWnd::OnDestroy();
  632. // Display information about the current menu.
  633. TraceMenu(g_tagSplitFrameMenu, AfxGetMainWnd()->GetMenu(), _T("Menu after child wnd destroyed: "));
  634. } //*** CSplitterFrame::OnDestroy()
  635. /////////////////////////////////////////////////////////////////////////////
  636. //++
  637. //
  638. // CSplitterFrame::OnUpdateLargeIconsView
  639. // CSplitterFrame::OnUpdateSmallIconsView
  640. // CSplitterFrame::OnUpdateListView
  641. // CSplitterFrame::OnUpdateDetailsView
  642. //
  643. // Routine Description:
  644. // Determines whether menu items corresponding to ID_VIEW_LARGE_ICONS,
  645. // ID_VIEW_SMALL_ICONS, ID_VIEW_LIST, and ID_VIEW_DETAILS should be
  646. // enabled or not.
  647. //
  648. // Arguments:
  649. // None.
  650. //
  651. // Return Value:
  652. // None.
  653. //
  654. //--
  655. /////////////////////////////////////////////////////////////////////////////
  656. void CSplitterFrame::OnUpdateLargeIconsView(CCmdUI * pCmdUI)
  657. {
  658. int nCheck;
  659. nCheck = PviewList()->GetView();
  660. pCmdUI->SetRadio(nCheck == LVS_ICON);
  661. pCmdUI->Enable();
  662. } //*** CSplitterFrame::OnUpdateLargeIconsView()
  663. void CSplitterFrame::OnUpdateSmallIconsView(CCmdUI * pCmdUI)
  664. {
  665. int nCheck;
  666. nCheck = PviewList()->GetView();
  667. pCmdUI->SetRadio(nCheck == LVS_SMALLICON);
  668. pCmdUI->Enable();
  669. } //*** CSplitterFrame::OnUpdateSmallIconsView()
  670. void CSplitterFrame::OnUpdateListView(CCmdUI * pCmdUI)
  671. {
  672. int nCheck;
  673. nCheck = PviewList()->GetView();
  674. pCmdUI->SetRadio(nCheck == LVS_LIST);
  675. pCmdUI->Enable();
  676. } //*** CSplitterFrame::OnUpdateListView()
  677. void CSplitterFrame::OnUpdateDetailsView(CCmdUI * pCmdUI)
  678. {
  679. int nCheck;
  680. nCheck = PviewList()->GetView();
  681. pCmdUI->SetRadio(nCheck == (LVS_REPORT | LVS_ICON));
  682. pCmdUI->Enable();
  683. } //*** CSplitterFrame::OnUpdateDetailsView()
  684. /////////////////////////////////////////////////////////////////////////////
  685. //++
  686. //
  687. // CSplitterFrame::OnCmdLargeIconsView
  688. // CSplitterFrame::OnCmdSmallIconsView
  689. // CSplitterFrame::OnCmdListView
  690. // CSplitterFrame::OnCmdDetailsView
  691. //
  692. // Routine Description:
  693. // Processes the ID_VIEW_LARGE_ICONS, ID_VIEW_SMALL_ICONS, ID_VIEW_LIST,
  694. // and ID_VIEW_DETAILS menu commands.
  695. //
  696. // Arguments:
  697. // None.
  698. //
  699. // Return Value:
  700. // None.
  701. //
  702. //--
  703. /////////////////////////////////////////////////////////////////////////////
  704. void CSplitterFrame::OnLargeIconsView(void)
  705. {
  706. PviewList()->SetView(LVS_ICON);
  707. } //*** CSplitterFrame::OnLargeIconsView()
  708. void CSplitterFrame::OnSmallIconsView(void)
  709. {
  710. PviewList()->SetView(LVS_SMALLICON);
  711. } //*** CSplitterFrame::OnSmallIconsView()
  712. void CSplitterFrame::OnListView(void)
  713. {
  714. PviewList()->SetView(LVS_LIST);
  715. } //*** CSplitterFrame::OnListView()
  716. void CSplitterFrame::OnDetailsView(void)
  717. {
  718. PviewList()->SetView(LVS_REPORT | LVS_ICON);
  719. } //*** CSplitterFrame::OnDetailsView()
  720. #ifdef _DEBUG
  721. /////////////////////////////////////////////////////////////////////////////
  722. //++
  723. //
  724. // CSplitterFrame::OnMDIActivate
  725. //
  726. // Routine Description:
  727. // Handler method for the WM_MDIACTIVATE message.
  728. //
  729. // Arguments:
  730. // bActivate [IN] TRUE if the child is being activated and FALSE
  731. // if it is being deactivated.
  732. // pActivateWnd [IN OUT] Child window to be activated.
  733. // pDeactivateWnd [IN OUT] Child window being deactivated.
  734. //
  735. // Return Value:
  736. // None.
  737. //
  738. //--
  739. /////////////////////////////////////////////////////////////////////////////
  740. void CSplitterFrame::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)
  741. {
  742. if (g_tagSplitFrameMenu.BAny())
  743. {
  744. if (!bActivate)
  745. {
  746. CMDIFrameWnd * pFrame = GetMDIFrame();
  747. CMenu menuDefault;
  748. TraceMenu(g_tagSplitFrameMenu, AfxGetMainWnd()->GetMenu(), _T("Menu before deactivating: "));
  749. menuDefault.Attach(pFrame->m_hMenuDefault);
  750. TraceMenu(g_tagSplitFrameMenu, &menuDefault, _T("Frame menu before deactivating: "));
  751. menuDefault.Detach();
  752. } // if: deactivating
  753. else
  754. {
  755. CMDIFrameWnd * pFrame = GetMDIFrame();
  756. CMenu menuDefault;
  757. menuDefault.Attach(pFrame->m_hMenuDefault);
  758. TraceMenu(g_tagSplitFrameMenu, &menuDefault, _T("Frame menu before activating: "));
  759. menuDefault.Detach();
  760. } // else: activating
  761. } // if: tag is active
  762. CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);
  763. if (!bActivate)
  764. TraceMenu(g_tagSplitFrameMenu, AfxGetMainWnd()->GetMenu(), _T("Menu after deactivating: "));
  765. } //*** CSplitterFrame::OnMDIActivate()
  766. #endif // _DEBUG
  767. /////////////////////////////////////////////////////////////////////////////
  768. //++
  769. //
  770. // CSplitterFrame::BeginDrag
  771. //
  772. // Routine Description:
  773. // Called by a view to begin a drag operation.
  774. //
  775. // Arguments:
  776. // pimagelist [IN OUT] Image list to use for the drag operation.
  777. // pci [IN OUT] Cluster item being dragged.
  778. // ptImage [IN] Specifies the x- and y-coordinate of the cursor.
  779. // ptStart [IN] Specifies the x- and y-coordinate of the start position.
  780. //
  781. // Return Value:
  782. // None.
  783. //
  784. //--
  785. /////////////////////////////////////////////////////////////////////////////
  786. void CSplitterFrame::BeginDrag(
  787. IN OUT CImageList * pimagelist,
  788. IN OUT CClusterItem * pci,
  789. IN CPoint ptImage,
  790. IN CPoint ptStart
  791. )
  792. {
  793. ASSERT(!BDragging());
  794. ASSERT(pimagelist != NULL);
  795. ASSERT_VALID(pci);
  796. // Save the cluster item.
  797. m_pciDrag = pci;
  798. // Prepare the image list.
  799. m_pimagelist = pimagelist;
  800. VERIFY(Pimagelist()->BeginDrag(0, ptStart));
  801. VERIFY(Pimagelist()->DragEnter(this, ptImage));
  802. SetCapture();
  803. // Set the dragging state.
  804. m_bDragging = TRUE;
  805. // Let each view initialize for the drag operation.
  806. PviewTree()->BeginDrag();
  807. PviewList()->BeginDrag();
  808. } //*** CSplitterFrame::BeginDrag()
  809. /////////////////////////////////////////////////////////////////////////////
  810. //++
  811. //
  812. // CSplitterFrame::OnMouseMove
  813. //
  814. // Routine Description:
  815. // Handler method for the WM_MOUSEMOVE message during a drag operation.
  816. //
  817. // Arguments:
  818. // nFlags Indicates whether various virtual keys are down.
  819. // point Specifies the x- and y-coordinate of the cursor in frame
  820. // coordinates.
  821. //
  822. // Return Value:
  823. // None.
  824. //
  825. //--
  826. /////////////////////////////////////////////////////////////////////////////
  827. void CSplitterFrame::OnMouseMove(UINT nFlags, CPoint point)
  828. {
  829. // If we are dragging, move the drag image.
  830. if (BDragging())
  831. {
  832. CWnd * pwndDrop;
  833. Trace(g_tagSplitFrameDragMouse, _T("OnMouseMove() - Moving to (%d,%d)"), point.x, point.y);
  834. // Move the item.
  835. ASSERT(Pimagelist() != NULL);
  836. VERIFY(Pimagelist()->DragMove(point));
  837. // Get the child window for this point.
  838. pwndDrop = ChildWindowFromPoint(point);
  839. if (pwndDrop == &m_wndSplitter)
  840. pwndDrop = m_wndSplitter.ChildWindowFromPoint(point);
  841. if ((pwndDrop == PviewTree()) || (pwndDrop == PviewList()))
  842. pwndDrop->SetFocus();
  843. PviewTree()->OnMouseMoveForDrag(nFlags, point, pwndDrop);
  844. PviewList()->OnMouseMoveForDrag(nFlags, point, pwndDrop);
  845. } // if: tree item is being dragged
  846. // Call the base class method.
  847. CMDIChildWnd::OnMouseMove(nFlags, point);
  848. } //*** CSplitterFrame::OnMouseMove()
  849. /////////////////////////////////////////////////////////////////////////////
  850. //++
  851. //
  852. // CSplitterFrame::OnLButtonUp
  853. // CSplitterFrame::OnRButtonUp
  854. // CSplitterFrame::OnButtonUp
  855. //
  856. // Routine Description:
  857. // Handler method for the WM_LBUTTONUP and WM_RBUTTONUP messages.
  858. //
  859. // Arguments:
  860. // nFlags Indicates whether various virtual keys are down.
  861. // point Specifies the x- and y-coordinate of the cursor.
  862. //
  863. // Return Value:
  864. // None.
  865. //
  866. //--
  867. /////////////////////////////////////////////////////////////////////////////
  868. void CSplitterFrame::OnLButtonUp(UINT nFlags, CPoint point)
  869. {
  870. CMDIChildWnd::OnLButtonUp(nFlags, point);
  871. OnButtonUp(nFlags, point);
  872. } //*** CSplitterFrame::OnLButtonUp()
  873. void CSplitterFrame::OnRButtonUp(UINT nFlags, CPoint point)
  874. {
  875. CMDIChildWnd::OnRButtonUp(nFlags, point);
  876. OnButtonUp(nFlags, point);
  877. } //*** CSplitterFrame::OnRButtonUp()
  878. /////////////////////////////////////////////////////////////////////////////
  879. //++
  880. //
  881. // CSplitterFrame::OnButtonUp
  882. //
  883. // Routine Description:
  884. // Process a button up event by ending an active drag operation.
  885. //
  886. // Arguments:
  887. // nFlags Indicates whether various virtual keys are down.
  888. // point Specifies the x- and y-coordinate of the cursor.
  889. //
  890. // Return Value:
  891. // None.
  892. //
  893. //--
  894. /////////////////////////////////////////////////////////////////////////////
  895. void CSplitterFrame::OnButtonUp(UINT nFlags, CPoint point)
  896. {
  897. // If we are dragging, process the drop.
  898. if (BDragging())
  899. {
  900. CWnd * pwndChild;
  901. Trace(g_tagSplitFrameDrag, _T("OnButtonUp() - Dropping at (%d,%d)"), point.x, point.y);
  902. // Cleanup the image list.
  903. ASSERT(Pimagelist() != NULL);
  904. VERIFY(Pimagelist()->DragLeave(this));
  905. Pimagelist()->EndDrag();
  906. delete m_pimagelist;
  907. m_pimagelist = NULL;
  908. // Get the child window for this point.
  909. pwndChild = ChildWindowFromPoint(point);
  910. if (pwndChild == &m_wndSplitter)
  911. pwndChild = m_wndSplitter.ChildWindowFromPoint(point);
  912. if (pwndChild == PviewTree())
  913. PviewTree()->OnButtonUpForDrag(nFlags, point);
  914. else if (pwndChild == PviewList())
  915. PviewList()->OnButtonUpForDrag(nFlags, point);
  916. // Cleanup.
  917. PviewTree()->EndDrag();
  918. PviewList()->EndDrag();
  919. VERIFY(ReleaseCapture());
  920. m_bDragging = FALSE;
  921. m_pciDrag = NULL;
  922. } // if: tree item is being dragged
  923. } //*** CSplitterFrame::OnButtonUp()
  924. /////////////////////////////////////////////////////////////////////////////
  925. //++
  926. //
  927. // CSplitterFrame::ChangeDragCursor
  928. //
  929. // Routine Description:
  930. // Changes the cursor used for dragging.
  931. //
  932. // Arguments:
  933. // pszCursor [IN] System cursor to load.
  934. //
  935. // Return Value:
  936. // None.
  937. //
  938. //--
  939. /////////////////////////////////////////////////////////////////////////////
  940. void CSplitterFrame::ChangeDragCursor(LPCTSTR pszCursor)
  941. {
  942. HCURSOR hcurDrag = LoadCursor(NULL, pszCursor);
  943. ASSERT(hcurDrag != NULL);
  944. SetCursor(hcurDrag);
  945. Pimagelist()->SetDragCursorImage(0, CPoint(0, 0)); // define the hot spot for the new cursor image
  946. } //*** CSplitterFrame::ChangeDragCursor()
  947. /////////////////////////////////////////////////////////////////////////////
  948. //++
  949. //
  950. // CSplitterFrame::AbortDrag
  951. //
  952. // Routine Description:
  953. // Abort the drag & drop operation currently in progress.
  954. //
  955. // Arguments:
  956. // pszCursor [IN] System cursor to load.
  957. //
  958. // Return Value:
  959. // None.
  960. //
  961. //--
  962. /////////////////////////////////////////////////////////////////////////////
  963. void CSplitterFrame::AbortDrag(void)
  964. {
  965. ASSERT(BDragging());
  966. Trace(g_tagSplitFrameDrag, _T("AbortDrag() - Aborting drag & drop"));
  967. // Cleanup the image list.
  968. ASSERT(Pimagelist() != NULL);
  969. VERIFY(Pimagelist()->DragLeave(this));
  970. Pimagelist()->EndDrag();
  971. delete m_pimagelist;
  972. m_pimagelist = NULL;
  973. // Cleanup.
  974. PviewTree()->EndDrag();
  975. PviewList()->EndDrag();
  976. VERIFY(ReleaseCapture());
  977. m_bDragging = FALSE;
  978. m_pciDrag = NULL;
  979. } //*** CSplitterFrame::AbortDrag()