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.

516 lines
13 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. FTMan
  5. File Name:
  6. MainFrm.cpp
  7. Abstract:
  8. Implementation of the CMainFrame class. It is the MFC main frame class for this application
  9. Author:
  10. Cristian Teodorescu October 20, 1998
  11. Notes:
  12. Revision History:
  13. --*/
  14. #include "stdafx.h"
  15. #include "Item.h"
  16. #include "FTListVw.h"
  17. #include "FTTreeVw.h"
  18. #include "MainFrm.h"
  19. #include "Resource.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. // Range limits for OnViewStyle and OnUpdateViewStyle
  26. #define AFX_ID_VIEW_MINIMUM ID_VIEW_SMALLICON
  27. #define AFX_ID_VIEW_MAXIMUM ID_VIEW_BYNAME
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CMainFrame
  30. IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
  31. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  32. //{{AFX_MSG_MAP(CMainFrame)
  33. ON_WM_CREATE()
  34. ON_COMMAND(ID_VIEW_TOGGLE, OnViewToggle)
  35. ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
  36. ON_WM_ACTIVATEAPP()
  37. ON_WM_DESTROY()
  38. ON_WM_TIMER()
  39. //}}AFX_MSG_MAP
  40. ON_UPDATE_COMMAND_UI_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnUpdateViewStyles)
  41. ON_COMMAND_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnViewStyle)
  42. END_MESSAGE_MAP()
  43. static UINT indicators[] =
  44. {
  45. ID_INDICATOR_NAME, // Name of the tree selected item
  46. ID_INDICATOR_TYPE, // Type of the tree selected item
  47. ID_INDICATOR_DISKS, // Disks set of the tree selected item
  48. ID_INDICATOR_SIZE, // Size of the tree selected item
  49. ID_INDICATOR_NOTHING, // Just an empty indicator to let some space between the first 4 indicators and the last one
  50. ID_SEPARATOR, // status line indicator
  51. };
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CMainFrame construction/destruction
  54. CMainFrame::CMainFrame() : m_bEnableAutoRefresh(FALSE), m_bAutoRefreshRequested(FALSE), m_unTimer(0)
  55. {
  56. // TODO: add member initialization code here
  57. }
  58. CMainFrame::~CMainFrame()
  59. {
  60. }
  61. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  62. {
  63. if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  64. return -1;
  65. /*
  66. if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
  67. | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  68. !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  69. */
  70. if (!m_wndToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP
  71. | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  72. !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  73. {
  74. TRACE0(_T("Failed to create toolbar\n"));
  75. return -1; // fail to create
  76. }
  77. m_wndToolBar.GetToolBarCtrl().ModifyStyle( 0, TBSTYLE_FLAT );
  78. if (!m_wndStatusBar.Create(this) ||
  79. !m_wndStatusBar.SetIndicators(indicators,
  80. sizeof(indicators)/sizeof(UINT)))
  81. {
  82. TRACE0(_T("Failed to create status bar\n"));
  83. return -1; // fail to create
  84. }
  85. // Try to compute the optimal size for the status bar indicators ( depending on the application font )
  86. int nAveCharWidth = 0;
  87. CDC* pDC = m_wndStatusBar.GetDC();
  88. if( pDC )
  89. {
  90. TEXTMETRIC textmetrics;
  91. if( pDC->GetTextMetrics(&textmetrics) )
  92. nAveCharWidth = textmetrics.tmAveCharWidth;
  93. m_wndStatusBar.ReleaseDC( pDC );
  94. }
  95. m_wndStatusBar.SetPaneInfo( 0, m_wndStatusBar.GetItemID(0), 0, nAveCharWidth ? (16 * nAveCharWidth) : 130 );
  96. m_wndStatusBar.SetPaneInfo( 1, m_wndStatusBar.GetItemID(1), 0, nAveCharWidth ? (22 * nAveCharWidth) : 150 );
  97. m_wndStatusBar.SetPaneInfo( 2, m_wndStatusBar.GetItemID(2), 0, nAveCharWidth ? (8 * nAveCharWidth) : 50 );
  98. m_wndStatusBar.SetPaneInfo( 3, m_wndStatusBar.GetItemID(3), 0, nAveCharWidth ? (8 * nAveCharWidth) : 60 );
  99. m_wndStatusBar.SetPaneInfo( 4, m_wndStatusBar.GetItemID(4), SBPS_NOBORDERS, nAveCharWidth ? (2 * nAveCharWidth) : 15 );
  100. m_wndStatusBar.SetPaneStyle( 5, SBPS_NOBORDERS | SBPS_STRETCH );
  101. // TODO: Delete these three lines if you don't want the toolbar to
  102. // be dockable
  103. m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
  104. EnableDocking(CBRS_ALIGN_ANY);
  105. DockControlBar(&m_wndToolBar);
  106. return 0;
  107. }
  108. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
  109. CCreateContext* pContext)
  110. {
  111. // create splitter window
  112. if (!m_wndSplitter.CreateStatic(this, 1, 2))
  113. return FALSE;
  114. if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CFTTreeView), CSize(200, 100), pContext) ||
  115. !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CFTListView), CSize(100, 100), pContext))
  116. {
  117. m_wndSplitter.DestroyWindow();
  118. return FALSE;
  119. }
  120. // Create timer
  121. m_unTimer = SetTimer( ID_TIMER_EVENT, TIMER_ELAPSE, NULL );
  122. if( !m_unTimer )
  123. TRACE( _T("Failure installing timer\n") );
  124. return TRUE;
  125. }
  126. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  127. {
  128. if( !CFrameWnd::PreCreateWindow(cs) )
  129. return FALSE;
  130. // TODO: Modify the Window class or styles here by modifying
  131. // the CREATESTRUCT cs
  132. return TRUE;
  133. }
  134. /*
  135. Public method: RefreshAll
  136. Purpose: Refreshes the content of both views by keeping ( when possible ) the expanded and
  137. selected items.
  138. It is also possible to change the selected items and to add some expanded items
  139. Parameters: [IN] CItemIDSet *psetAddTreeExpandedItems
  140. Items to add to the currently expanded items set
  141. [IN] CItemIDSet *psetTreeSelectedItems
  142. Items to select in the tree ( the currently selected items are neglected )
  143. [IN] CItemIDSet *psetListSelectedItems
  144. Items to select in the list ( the currently selected items are neglected )
  145. Return value: TRUE if the refresh operation succeeded
  146. */
  147. BOOL CMainFrame::RefreshAll(
  148. CItemIDSet* psetAddTreeExpandedItems /* =NULL */ ,
  149. CItemIDSet* psetTreeSelectedItems /* =NULL */,
  150. CItemIDSet* psetListSelectedItems /* =NULL */ )
  151. {
  152. CWaitCursor wc;
  153. TREE_SNAPSHOT snapshotTree;
  154. LIST_SNAPSHOT snapshotList;
  155. BOOL bResult;
  156. CAutoRefresh ar(FALSE);
  157. DisplayStatusBarMessage( IDS_STATUS_REFRESH );
  158. CFTTreeView* pTreeView = GetLeftPane();
  159. CFTListView* pListView = GetRightPane();
  160. // Get the snapshots of the tree and list views and do some changes ( if needed )
  161. pTreeView->GetSnapshot(snapshotTree);
  162. if( psetAddTreeExpandedItems )
  163. snapshotTree.setExpandedItems += *psetAddTreeExpandedItems;
  164. if( psetTreeSelectedItems )
  165. snapshotTree.setSelectedItems = *psetTreeSelectedItems;
  166. pListView->GetSnapshot( snapshotList );
  167. if( psetListSelectedItems )
  168. snapshotList.setSelectedItems = *psetListSelectedItems;
  169. // Refresh the tree view
  170. bResult = pTreeView->Refresh(snapshotTree);
  171. // Set the snapshot pf the list view
  172. pListView->SetSnapshot( snapshotList );
  173. // All previous requests for auto refresh should be neglected now
  174. m_bAutoRefreshRequested = FALSE;
  175. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  176. return bResult;
  177. }
  178. /////////////////////////////////////////////////////////////////////////////
  179. // CMainFrame diagnostics
  180. #ifdef _DEBUG
  181. void CMainFrame::AssertValid() const
  182. {
  183. CFrameWnd::AssertValid();
  184. }
  185. void CMainFrame::Dump(CDumpContext& dc) const
  186. {
  187. CFrameWnd::Dump(dc);
  188. }
  189. #endif //_DEBUG
  190. /////////////////////////////////////////////////////////////////////////////
  191. // CMainFrame message handlers
  192. CFTTreeView* CMainFrame::GetLeftPane()
  193. {
  194. CWnd* pWnd = m_wndSplitter.GetPane(0, 0);
  195. CFTTreeView* pView = DYNAMIC_DOWNCAST(CFTTreeView, pWnd);
  196. return pView;
  197. }
  198. CFTListView* CMainFrame::GetRightPane()
  199. {
  200. CWnd* pWnd = m_wndSplitter.GetPane(0, 1);
  201. CFTListView* pView = DYNAMIC_DOWNCAST(CFTListView, pWnd);
  202. return pView;
  203. }
  204. void CMainFrame::OnUpdateViewStyles(CCmdUI* pCmdUI)
  205. {
  206. // TODO: customize or extend this code to handle choices on the
  207. // View menu.
  208. CFTListView* pView = GetRightPane();
  209. // if the right-hand pane hasn't been created or isn't a view,
  210. // disable commands in our range
  211. if (pView == NULL)
  212. pCmdUI->Enable(FALSE);
  213. else
  214. {
  215. DWORD dwStyle = pView->GetStyle() & LVS_TYPEMASK;
  216. // if the command is ID_VIEW_LINEUP, only enable command
  217. // when we're in LVS_ICON or LVS_SMALLICON mode
  218. if (pCmdUI->m_nID == ID_VIEW_LINEUP)
  219. {
  220. if (dwStyle == LVS_ICON || dwStyle == LVS_SMALLICON)
  221. pCmdUI->Enable();
  222. else
  223. pCmdUI->Enable(FALSE);
  224. }
  225. else
  226. {
  227. // otherwise, use dots to reflect the style of the view
  228. pCmdUI->Enable();
  229. BOOL bChecked = FALSE;
  230. switch (pCmdUI->m_nID)
  231. {
  232. case ID_VIEW_DETAILS:
  233. bChecked = (dwStyle == LVS_REPORT);
  234. break;
  235. case ID_VIEW_SMALLICON:
  236. bChecked = (dwStyle == LVS_SMALLICON);
  237. break;
  238. case ID_VIEW_LARGEICON:
  239. bChecked = (dwStyle == LVS_ICON);
  240. break;
  241. case ID_VIEW_LIST:
  242. bChecked = (dwStyle == LVS_LIST);
  243. break;
  244. default:
  245. bChecked = FALSE;
  246. break;
  247. }
  248. pCmdUI->SetRadio(bChecked ? 1 : 0);
  249. }
  250. }
  251. }
  252. void CMainFrame::OnViewStyle(UINT nCommandID)
  253. {
  254. // TODO: customize or extend this code to handle choices on the
  255. // View menu.
  256. CFTListView* pView = GetRightPane();
  257. // if the right-hand pane has been created and is a CFTListView,
  258. // process the menu commands...
  259. if (pView != NULL)
  260. {
  261. DWORD dwStyle = -1;
  262. BOOL bExtendedNames = TRUE;
  263. switch (nCommandID)
  264. {
  265. case ID_VIEW_LINEUP:
  266. {
  267. // ask the list control to snap to grid
  268. CListCtrl& refListCtrl = pView->GetListCtrl();
  269. refListCtrl.Arrange(LVA_SNAPTOGRID);
  270. }
  271. break;
  272. // other commands change the style on the list control
  273. case ID_VIEW_DETAILS:
  274. dwStyle = LVS_REPORT;
  275. bExtendedNames = FALSE;
  276. break;
  277. case ID_VIEW_SMALLICON:
  278. dwStyle = LVS_SMALLICON;
  279. break;
  280. case ID_VIEW_LARGEICON:
  281. dwStyle = LVS_ICON;
  282. break;
  283. case ID_VIEW_LIST:
  284. dwStyle = LVS_LIST;
  285. break;
  286. }
  287. // change the style; window will repaint automatically
  288. if (dwStyle != -1)
  289. {
  290. pView->ModifyStyle(LVS_TYPEMASK, dwStyle);
  291. pView->DisplayItemsExtendedNames( bExtendedNames );
  292. }
  293. }
  294. }
  295. void CMainFrame::OnViewToggle()
  296. {
  297. // TODO: Add your command handler code here
  298. int nRow,nCol;
  299. if( !m_wndSplitter.GetActivePane(&nRow,&nCol) )
  300. return;
  301. ASSERT( nRow == 0 );
  302. ASSERT( nCol <= 1 );
  303. m_wndSplitter.SetActivePane(0,1-nCol, NULL);
  304. }
  305. void CMainFrame::OnViewRefresh()
  306. {
  307. RefreshAll( NULL, NULL, NULL );
  308. }
  309. void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask)
  310. {
  311. CFrameWnd::OnActivateApp(bActive, hTask);
  312. // TODO: Add your message handler code here
  313. if( bActive )
  314. {
  315. if( m_bEnableAutoRefresh )
  316. {
  317. TRACE( _T("OnActivateApp AutoRefresh\n") );
  318. RefreshAll();
  319. }
  320. else
  321. m_bAutoRefreshRequested = TRUE;
  322. }
  323. }
  324. void CMainFrame::OnDestroy()
  325. {
  326. if( m_unTimer )
  327. KillTimer( m_unTimer );
  328. CFrameWnd::OnDestroy();
  329. // TODO: Add your message handler code here
  330. }
  331. void CMainFrame::OnTimer(UINT nIDEvent)
  332. {
  333. // TODO: Add your message handler code here and/or call default
  334. if( ( nIDEvent == ID_TIMER_EVENT ) && m_bEnableAutoRefresh && ( GetActiveWindow() == this ) )
  335. {
  336. //TRACE("OnTimer\n");
  337. CFTTreeView* pTreeView = GetLeftPane();
  338. pTreeView->RefreshOnTimer();
  339. }
  340. CFrameWnd::OnTimer(nIDEvent);
  341. }
  342. /////////////////////////////////////////////////////////////////////////////////////////////
  343. // Global functions related to the main frame
  344. /*
  345. Global function: RefreshAll
  346. Purpose: Refreshes the content of both views of the mainframe by keeping ( when possible )
  347. the expanded and selected items.
  348. It is also possible to change the selected items and to add some expanded items
  349. Parameters: [IN] CItemIDSet *psetAddTreeExpandedItems
  350. Items to add to the currently expanded items set
  351. [IN] CItemIDSet *psetTreeSelectedItems
  352. Items to select in the tree ( the currently selected items are neglected )
  353. [IN] CItemIDSet *psetListSelectedItems
  354. Items to select in the list ( the currently selected items are neglected )
  355. Return value: TRUE if the refresh operation succeeded
  356. */
  357. BOOL AfxRefreshAll(
  358. CItemIDSet* psetAddTreeExpandedItems /* =NULL */ ,
  359. CItemIDSet* psetTreeSelectedItems /* =NULL */,
  360. CItemIDSet* psetListSelectedItems /* =NULL */ )
  361. {
  362. CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
  363. ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)));
  364. return pFrame->RefreshAll( psetAddTreeExpandedItems, psetTreeSelectedItems, psetListSelectedItems );
  365. }
  366. /*
  367. Global function: AfxEnableAutoRefresh()
  368. Purpose: Enables / Disables the auto refresh of both views of the mainframe on WM_ACTIVATEAPP
  369. Parameters: [IN] BOOL bEnable
  370. Specifies whether the auto-refresh is to be enabled or disabled
  371. Return value: The previous status of the auto-refresh flag
  372. */
  373. BOOL AfxEnableAutoRefresh( BOOL bEnable /* =TRUE */ )
  374. {
  375. CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
  376. ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)));
  377. BOOL bPrevious = pFrame->m_bEnableAutoRefresh;
  378. // If the flag is enabling and an auto-refresh request came while it was disabled then proceed with auto-refresh
  379. if( bEnable && !bPrevious && pFrame->m_bAutoRefreshRequested)
  380. {
  381. TRACE( _T("Late OnActivateApp AutoRefresh\n") );
  382. AfxRefreshAll();
  383. }
  384. else if ( !bEnable && bPrevious )
  385. pFrame->m_bAutoRefreshRequested = FALSE;
  386. pFrame->m_bEnableAutoRefresh = bEnable;
  387. return bPrevious;
  388. }
  389. BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  390. {
  391. // TODO: Add your specialized code here and/or call the base class
  392. switch( nID )
  393. {
  394. case ID_VIEW_UP:
  395. case ID_INDICATOR_NAME:
  396. case ID_INDICATOR_TYPE:
  397. case ID_INDICATOR_DISKS:
  398. case ID_INDICATOR_SIZE:
  399. case ID_INDICATOR_NOTHING:
  400. CFTTreeView* pTreeView = GetLeftPane();
  401. return pTreeView->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo );
  402. }
  403. return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  404. }