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.

1984 lines
52 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999
  5. //
  6. // File: mainfrm.cpp
  7. //
  8. // Contents: Main frame for amc
  9. //
  10. // History: 01-Jan-96 TRomano Created
  11. // 16-Jul-96 WayneSc Add code to test switching views
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "stdafx.h"
  15. #include "AMCDoc.h"
  16. #include "AMCView.h"
  17. #include "AMC.h"
  18. #include "MainFrm.h"
  19. #include "ChildFrm.h"
  20. #include "treectrl.h"
  21. #include "menubar.h"
  22. #include "mdiuisim.h"
  23. #include "toolbar.h"
  24. #include "props.h"
  25. #include "sysmenu.h"
  26. #include "amcmsgid.h"
  27. #include "HtmlHelp.h"
  28. #include "strings.h"
  29. #include "ndmgrp.h"
  30. #include "amcmsgid.h"
  31. #include "tbtrack.h"
  32. #include "caption.h"
  33. #include "scriptevents.h"
  34. #ifdef DBG
  35. CTraceTag tagMainFrame(TEXT("CMainFrame"), TEXT("Messages"));
  36. #endif
  37. //############################################################################
  38. //############################################################################
  39. //
  40. // Implementation of class CMMCApplicationFrame
  41. //
  42. //############################################################################
  43. //############################################################################
  44. /*+-------------------------------------------------------------------------*
  45. * class CMMCApplicationFrame
  46. *
  47. *
  48. * PURPOSE: The COM 0bject that exposes the Frame interface off the Application object.
  49. *
  50. *+-------------------------------------------------------------------------*/
  51. class CMMCApplicationFrame :
  52. public CMMCIDispatchImpl<Frame>,
  53. public CTiedComObject<CMainFrame>
  54. {
  55. typedef CMainFrame CMyTiedObject;
  56. public:
  57. BEGIN_MMC_COM_MAP(CMMCApplicationFrame)
  58. END_MMC_COM_MAP()
  59. //Frame interface
  60. public:
  61. STDMETHOD(Maximize)();
  62. STDMETHOD(Minimize)();
  63. STDMETHOD(Restore)();
  64. STDMETHOD(get_Left)(int *pLeft) {return GetCoordinate(pLeft, eLeft);}
  65. STDMETHOD(put_Left)(int left) {return PutCoordinate(left, eLeft);}
  66. STDMETHOD(get_Right)(int *pRight) {return GetCoordinate(pRight, eRight);}
  67. STDMETHOD(put_Right)(int right) {return PutCoordinate(right, eRight);}
  68. STDMETHOD(get_Top)(int *pTop) {return GetCoordinate(pTop, eTop);}
  69. STDMETHOD(put_Top)(int top) {return PutCoordinate(top, eTop);}
  70. STDMETHOD(get_Bottom)(int *pBottom) {return GetCoordinate(pBottom, eBottom);}
  71. STDMETHOD(put_Bottom)(int bottom) {return PutCoordinate(bottom, eBottom);}
  72. private:
  73. enum eCoordinate { eLeft, eRight, eTop, eBottom };
  74. STDMETHOD(GetCoordinate)(int *pCoordinate, eCoordinate e);
  75. STDMETHOD(PutCoordinate)(int coordinate, eCoordinate e);
  76. };
  77. /*+-------------------------------------------------------------------------*
  78. *
  79. * CMMCApplicationFrame::Maximize
  80. *
  81. * PURPOSE:
  82. *
  83. * RETURNS:
  84. * HRESULT
  85. *
  86. *+-------------------------------------------------------------------------*/
  87. HRESULT
  88. CMMCApplicationFrame::Maximize()
  89. {
  90. DECLARE_SC(sc, TEXT("CMMCApplicationFrame::Maximize"));
  91. CMyTiedObject *pTiedObj = NULL;
  92. sc = ScGetTiedObject(pTiedObj);
  93. if(sc)
  94. return sc.ToHr();
  95. // do the operation
  96. sc = pTiedObj->ScMaximize();
  97. return sc.ToHr();
  98. }
  99. /*+-------------------------------------------------------------------------*
  100. *
  101. * CMMCApplicationFrame::Minimize
  102. *
  103. * PURPOSE:
  104. *
  105. * RETURNS:
  106. * HRESULT
  107. *
  108. *+-------------------------------------------------------------------------*/
  109. HRESULT
  110. CMMCApplicationFrame::Minimize()
  111. {
  112. DECLARE_SC(sc, TEXT("CMMCApplicationFrame::Minimize"));
  113. CMyTiedObject *pTiedObj = NULL;
  114. sc = ScGetTiedObject(pTiedObj);
  115. if(sc)
  116. return sc.ToHr();
  117. // do the operation
  118. sc = pTiedObj->ScMinimize();
  119. return sc.ToHr();
  120. }
  121. /*+-------------------------------------------------------------------------*
  122. *
  123. * CMMCApplicationFrame::Restore
  124. *
  125. * PURPOSE:
  126. *
  127. * RETURNS:
  128. * HRESULT
  129. *
  130. *+-------------------------------------------------------------------------*/
  131. HRESULT
  132. CMMCApplicationFrame::Restore()
  133. {
  134. DECLARE_SC(sc, TEXT("CMMCApplicationFrame::Restore"));
  135. CMyTiedObject *pTiedObj = NULL;
  136. sc = ScGetTiedObject(pTiedObj);
  137. if(sc)
  138. return sc.ToHr();
  139. sc = pTiedObj->ScRestore();
  140. return sc.ToHr();
  141. }
  142. /*+-------------------------------------------------------------------------*
  143. *
  144. * CMMCApplicationFrame::GetCoordinate
  145. *
  146. * PURPOSE:
  147. *
  148. * PARAMETERS:
  149. * int * pCoordinate :
  150. * eCoordinate e :
  151. *
  152. * RETURNS:
  153. * HRESULT
  154. *
  155. *+-------------------------------------------------------------------------*/
  156. HRESULT
  157. CMMCApplicationFrame::GetCoordinate(int *pCoordinate, eCoordinate e)
  158. {
  159. DECLARE_SC(sc, TEXT("CMMCApplicationFrame::GetCoordinate"));
  160. // check parameters
  161. if(!pCoordinate)
  162. {
  163. sc = E_POINTER;
  164. return sc.ToHr();
  165. }
  166. CMyTiedObject *pTiedObj = NULL;
  167. sc = ScGetTiedObject(pTiedObj);
  168. if(sc)
  169. return sc.ToHr();
  170. RECT rect;
  171. // do the operation
  172. sc = pTiedObj->ScGetPosition(rect);
  173. if(sc)
  174. return sc.ToHr();
  175. switch(e)
  176. {
  177. case eTop:
  178. *pCoordinate = rect.top;
  179. break;
  180. case eBottom:
  181. *pCoordinate = rect.bottom;
  182. break;
  183. case eLeft:
  184. *pCoordinate = rect.left;
  185. break;
  186. case eRight:
  187. *pCoordinate = rect.right;
  188. break;
  189. default:
  190. ASSERT(0 && "Should not come here!!");
  191. break;
  192. }
  193. return sc.ToHr();
  194. }
  195. /*+-------------------------------------------------------------------------*
  196. *
  197. * CMMCApplicationFrame::PutCoordinate
  198. *
  199. * PURPOSE:
  200. *
  201. * PARAMETERS:
  202. * int coordinate :
  203. * eCoordinate e :
  204. *
  205. * RETURNS:
  206. * HRESULT
  207. *
  208. *+-------------------------------------------------------------------------*/
  209. HRESULT
  210. CMMCApplicationFrame::PutCoordinate(int coordinate, eCoordinate e)
  211. {
  212. DECLARE_SC(sc, TEXT("CMMCApplicationFrame::PutCoordinate"));
  213. CMyTiedObject *pTiedObj = NULL;
  214. sc = ScGetTiedObject(pTiedObj);
  215. if(sc)
  216. return sc.ToHr();
  217. RECT rect;
  218. sc = pTiedObj->ScGetPosition(rect);
  219. if(sc)
  220. return sc.ToHr();
  221. switch(e)
  222. {
  223. case eTop:
  224. rect.top = coordinate;
  225. break;
  226. case eBottom:
  227. rect.bottom = coordinate;
  228. break;
  229. case eLeft:
  230. rect.left = coordinate;
  231. break;
  232. case eRight:
  233. rect.right = coordinate;
  234. break;
  235. default:
  236. ASSERT(0 && "Should not come here!!");
  237. break;
  238. }
  239. sc = pTiedObj->ScSetPosition(rect);
  240. return sc.ToHr();
  241. }
  242. //############################################################################
  243. //############################################################################
  244. //
  245. // Misc declarations
  246. //
  247. //############################################################################
  248. //############################################################################
  249. static TBBUTTON MainButtons[] =
  250. {
  251. { 0, ID_FILE_NEW , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 0 },
  252. { 1, ID_FILE_OPEN , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 1 },
  253. { 2, ID_FILE_SAVE , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 2 },
  254. { 0, 0 , TBSTATE_ENABLED, TBSTYLE_SEP , {0,0}, 0L, 0 },
  255. { 3, ID_WINDOW_NEW , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 3 },
  256. };
  257. /*
  258. * remove the definition that WTL might have given us
  259. */
  260. #ifdef ID_VIEW_REFRESH
  261. #undef ID_VIEW_REFRESH
  262. #endif
  263. enum DoWeNeedThis
  264. {
  265. ID_VIEW_REFRESH = 12797
  266. };
  267. //############################################################################
  268. //############################################################################
  269. //
  270. // Implementation of class CMainFrame
  271. //
  272. //############################################################################
  273. //############################################################################
  274. IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
  275. // CODEWORK message reflection not working yet
  276. BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
  277. //{{AFX_MSG_MAP(CMainFrame)
  278. ON_WM_CREATE()
  279. ON_WM_DRAWCLIPBOARD()
  280. ON_WM_CHANGECBCHAIN()
  281. ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateFilePrint)
  282. ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_SETUP, OnUpdateFilePrintSetup)
  283. ON_WM_CLOSE()
  284. ON_COMMAND(ID_VIEW_TOOLBAR, OnViewToolbar)
  285. ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateViewToolbar)
  286. ON_WM_SIZE()
  287. ON_COMMAND(ID_HELP_HELPTOPICS, OnHelpTopics)
  288. ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
  289. ON_UPDATE_COMMAND_UI(ID_VIEW_REFRESH, OnUpdateViewRefresh)
  290. ON_WM_DESTROY()
  291. ON_WM_SYSCOMMAND()
  292. ON_WM_INITMENUPOPUP()
  293. ON_COMMAND(ID_CONSOLE_PROPERTIES, OnConsoleProperties)
  294. ON_WM_MOVE()
  295. ON_WM_ACTIVATE()
  296. ON_WM_NCACTIVATE()
  297. ON_WM_NCPAINT()
  298. ON_WM_PALETTECHANGED()
  299. ON_WM_QUERYNEWPALETTE()
  300. ON_COMMAND(ID_WINDOW_NEW, OnWindowNew)
  301. ON_WM_SETTINGCHANGE()
  302. ON_WM_MENUSELECT()
  303. ON_MESSAGE(WM_UNINITMENUPOPUP, OnUnInitMenuPopup)
  304. //}}AFX_MSG_MAP
  305. #ifdef DBG
  306. ON_COMMAND(ID_MMC_TRACE_DIALOG, OnMMCTraceDialog)
  307. #endif
  308. ON_MESSAGE(WM_SETTEXT, OnSetText)
  309. ON_MESSAGE(MMC_MSG_PROP_SHEET_NOTIFY, OnPropertySheetNotify)
  310. ON_MESSAGE(MMC_MSG_SHOW_SNAPIN_HELP_TOPIC, OnShowSnapinHelpTopic)
  311. // The following entry is placed here for compatibilty with versions
  312. // of mmc.lib that were compiled with the incorrect value for message
  313. // MMC_MSG_SHOW_SNAPIN_HELP_TOPIC. MMC.lib function MMCPropertyHelp
  314. // sends this message to the mainframe window when called by a snap-in.
  315. ON_MESSAGE(MMC_MSG_SHOW_SNAPIN_HELP_TOPIC_ALT, OnShowSnapinHelpTopic)
  316. END_MESSAGE_MAP()
  317. //+-------------------------------------------------------------------
  318. //
  319. // Member: CMainFrame::OnMenuSelect
  320. //
  321. // Synopsis: Handles WM_MENUSELECT, sets status bar text for the
  322. // given menu item.
  323. //
  324. // Arguments: [nItemID] - the resource id of menu item.
  325. // [nFlags] - MF_* flags
  326. // [hMenu] -
  327. //
  328. // Returns: none
  329. //
  330. //--------------------------------------------------------------------
  331. void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hMenu)
  332. {
  333. DECLARE_SC(sc, TEXT("CMainFrame::OnMenuSelect"));
  334. if (nFlags & MF_SYSMENU)
  335. return;
  336. CString strText = TEXT("");
  337. CString strStatusText;
  338. /*
  339. * We need to handle special cases, most of the menu items have status text with them.
  340. * The exception being, the favoties list, the windows list in windows menu and popup menus.
  341. * The reason is the menu ids are not unique in main menu because we do TrackPopupMenu at
  342. * three places first one for File, Window & Help menus done in menubar.cpp, second for
  343. * Action & View menu in cmenu.cpp and third favorites menu in favui.cpp.
  344. */
  345. /*
  346. * Special case 1: Check to see if current menu is favorites menu, if so need to get status
  347. * text for favorites list except for "Add to favorites.." and "Organize favorites.." items.
  348. * The below test can break if "Add to Favorites..." is moved in menu resource.
  349. */
  350. if ((IDS_ADD_TO_FAVORITES != nItemID) &&
  351. (IDS_ORGANIZEFAVORITES != nItemID) &&
  352. (GetMenuItemID(hMenu, 0) == IDS_ADD_TO_FAVORITES) )
  353. {
  354. strStatusText.LoadString(IDS_FAVORITES_ACTIVATE);
  355. }
  356. /*
  357. * Special case 2: Handle any popup menus (popup menus dont have any ID).
  358. */
  359. else if (nFlags & MF_POPUP)
  360. {
  361. // do nothing
  362. }
  363. // Special case 3: Assume mmc supports maximum of 1024 windows for status bar text sake.
  364. else if ( (nItemID >= AFX_IDM_FIRST_MDICHILD) && (nItemID <= AFX_IDM_FIRST_MDICHILD+1024) )
  365. {
  366. strStatusText.LoadString(ID_WINDOW_ACTIVATEWINDOW);
  367. }
  368. else
  369. {
  370. strText.LoadString(nItemID);
  371. int iSeparator = strText.Find(_T('\n'));
  372. if (iSeparator < 0) // No status text so use the menu text as status text.
  373. strStatusText = strText;
  374. else
  375. strStatusText = strText.Mid(iSeparator);
  376. }
  377. CChildFrame *pChildFrame = dynamic_cast<CChildFrame*>(GetActiveFrame());
  378. if (!pChildFrame)
  379. return;
  380. sc = pChildFrame->ScSetStatusText(strStatusText);
  381. if (sc)
  382. return;
  383. return;
  384. }
  385. /*+-------------------------------------------------------------------------*
  386. *
  387. * CMainFrame::ScGetFrame
  388. *
  389. * PURPOSE: Returns a pointer to the COM object that implements the
  390. * Frame interface.
  391. *
  392. * PARAMETERS:
  393. * Frame **ppFrame :
  394. *
  395. * RETURNS:
  396. * SC
  397. *
  398. *+-------------------------------------------------------------------------*/
  399. SC
  400. CMainFrame::ScGetFrame(Frame **ppFrame)
  401. {
  402. DECLARE_SC(sc, TEXT("CMainFrame::ScGetFrame") );
  403. if(!ppFrame)
  404. {
  405. sc = E_POINTER;
  406. return sc;
  407. }
  408. *ppFrame = NULL;
  409. // NOTE the com object cannot be cached with a smart pointer owned by CMainFrame
  410. // since CMainFrame is VERY LONG living guy - it will lock mmc.exe from exitting
  411. // it could be used by creating CComObjectCached, but CTiedComObjectCreator does
  412. // not support that
  413. // see bug # 101564
  414. CComPtr<Frame> spFrame;
  415. // create a CMMCApplicationFrame if not already done so.
  416. sc = CTiedComObjectCreator<CMMCApplicationFrame>::ScCreateAndConnect(*this, spFrame);
  417. if(sc)
  418. return sc;
  419. if(spFrame == NULL)
  420. {
  421. sc = E_UNEXPECTED;
  422. return sc;
  423. }
  424. *ppFrame = spFrame.Detach();
  425. return sc;
  426. }
  427. /*+-------------------------------------------------------------------------*
  428. *
  429. * CMainFrame::ScMaximize
  430. *
  431. * PURPOSE:
  432. *
  433. * RETURNS:
  434. * SC
  435. *
  436. *+-------------------------------------------------------------------------*/
  437. SC
  438. CMainFrame::ScMaximize()
  439. {
  440. DECLARE_SC(sc, TEXT("CMainFrame::ScMaximize"));
  441. ShowWindow(SW_MAXIMIZE);
  442. return sc;
  443. }
  444. /*+-------------------------------------------------------------------------*
  445. *
  446. * CMainFrame::ScMinimize
  447. *
  448. * PURPOSE:
  449. *
  450. * RETURNS:
  451. * SC
  452. *
  453. *+-------------------------------------------------------------------------*/
  454. SC
  455. CMainFrame::ScMinimize()
  456. {
  457. DECLARE_SC(sc, TEXT("CMainFrame::ScMinimize"));
  458. ShowWindow(SW_MINIMIZE);
  459. return sc;
  460. }
  461. /*+-------------------------------------------------------------------------*
  462. *
  463. * CMainFrame::ScRestore
  464. *
  465. * PURPOSE: Restores the position of the main frame.
  466. *
  467. * RETURNS:
  468. * SC
  469. *
  470. *+-------------------------------------------------------------------------*/
  471. SC
  472. CMainFrame::ScRestore()
  473. {
  474. DECLARE_SC(sc, TEXT("CMainFrame::ScRestore"));
  475. ShowWindow(SW_RESTORE);
  476. return sc;
  477. }
  478. /*+-------------------------------------------------------------------------*
  479. *
  480. * CMainFrame::ScSetPosition
  481. *
  482. * PURPOSE: Sets the position of the main frame
  483. *
  484. * PARAMETERS:
  485. * const RECT :
  486. *
  487. * RETURNS:
  488. * SC
  489. *
  490. *+-------------------------------------------------------------------------*/
  491. SC
  492. CMainFrame::ScSetPosition(const RECT &rect)
  493. {
  494. DECLARE_SC(sc, TEXT("CMainFrame::ScSetPosition"));
  495. int width = rect.right - rect.left + 1;
  496. int height = rect.bottom - rect.top + 1;
  497. SetWindowPos(NULL /*hWndInsertAfter*/, rect.left, rect.top, width, height, SWP_NOZORDER);
  498. return sc;
  499. }
  500. /*+-------------------------------------------------------------------------*
  501. *
  502. * CMainFrame::ScGetPosition
  503. *
  504. * PURPOSE:
  505. *
  506. * PARAMETERS:
  507. * RECT & rect :
  508. *
  509. * RETURNS:
  510. * SC
  511. *
  512. *+-------------------------------------------------------------------------*/
  513. SC
  514. CMainFrame::ScGetPosition(RECT &rect)
  515. {
  516. DECLARE_SC(sc, TEXT("CMainFrame::ScGetPosition"));
  517. GetWindowRect(&rect);
  518. return sc;
  519. }
  520. // OnActivate is overridden to work around a SQL snap-in problem under
  521. // Win9x. When SQL tries to force focus back to its property sheet it
  522. // causes an infinite recursion of the OnActivate call.
  523. // This override discards any activation that occurs during the processing
  524. // of a prior activation.
  525. void CMainFrame::OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized )
  526. {
  527. Trace(tagMainFrame, TEXT("OnActivate: nState=%d"), nState);
  528. static bActivating = FALSE;
  529. m_fCurrentlyActive = (nState != WA_INACTIVE);
  530. // if activating
  531. if (m_fCurrentlyActive)
  532. {
  533. CAMCApp* pApp = AMCGetApp();
  534. ASSERT(NULL != pApp);
  535. // if windows and we're already activating, prevent recursion
  536. if ( (NULL != pApp) && (pApp->IsWin9xPlatform() == true) && bActivating)
  537. return;
  538. // Process activation request
  539. bActivating = TRUE;
  540. CMDIFrameWnd::OnActivate(nState, pWndOther, bMinimized);
  541. bActivating = FALSE;
  542. }
  543. else
  544. {
  545. // if we have accelarators hilited (it happen when one press Alt+TAB)
  546. // we need to remove them now.
  547. SendMessage( WM_CHANGEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEACCEL | UISF_HIDEFOCUS));
  548. // Let unactivate through
  549. CMDIFrameWnd::OnActivate(nState, pWndOther, bMinimized);
  550. }
  551. }
  552. CAMCView* CMainFrame::GetActiveAMCView()
  553. {
  554. CChildFrame *pChildFrame = dynamic_cast<CChildFrame*>(GetActiveFrame());
  555. if (!pChildFrame)
  556. return NULL;
  557. CAMCView* pAMCView = pChildFrame->GetAMCView();
  558. ASSERT(pAMCView != NULL);
  559. ASSERT(::IsWindow(*pAMCView));
  560. if (pAMCView && ::IsWindow(*pAMCView))
  561. return pAMCView;
  562. return NULL;
  563. }
  564. CAMCTreeView* CMainFrame::_GetActiveAMCTreeView()
  565. {
  566. CAMCView* pAMCView = GetActiveAMCView();
  567. CAMCTreeView* pAMCTreeView = pAMCView ? pAMCView->GetTreeCtrl() : NULL;
  568. if (pAMCTreeView && ::IsWindow(*pAMCTreeView))
  569. return pAMCTreeView;
  570. return NULL;
  571. }
  572. void CMainFrame::OnDrawClipboard()
  573. {
  574. if (m_hwndToNotifyCBChange != NULL &&
  575. ::IsWindow(m_hwndToNotifyCBChange))
  576. {
  577. ::SendMessage(m_hwndToNotifyCBChange, WM_DRAWCLIPBOARD, 0, 0);
  578. m_hwndToNotifyCBChange = NULL;
  579. }
  580. if (m_hwndNextCB != NULL &&
  581. ::IsWindow(m_hwndNextCB))
  582. {
  583. ::SendMessage(m_hwndNextCB, WM_DRAWCLIPBOARD, 0, 0);
  584. }
  585. CAMCDoc* pAMCDoc = CAMCDoc::GetDocument();
  586. if (pAMCDoc)
  587. {
  588. CAMCViewPosition pos = pAMCDoc->GetFirstAMCViewPosition();
  589. while (pos != NULL)
  590. {
  591. CAMCView* v = pAMCDoc->GetNextAMCView(pos);
  592. if (v && ::IsWindow(*v))
  593. v->OnUpdatePasteBtn();
  594. }
  595. }
  596. }
  597. void CMainFrame::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
  598. {
  599. if (m_hwndNextCB == hWndRemove)
  600. m_hwndNextCB = hWndAfter;
  601. else if (m_hwndNextCB != NULL && ::IsWindow(m_hwndNextCB))
  602. ::SendMessage(m_hwndNextCB, WM_CHANGECBCHAIN,
  603. (WPARAM)hWndRemove, (LPARAM)hWndAfter);
  604. }
  605. void CMainFrame::OnWindowNew()
  606. {
  607. // lock AppEvents until this function is done
  608. LockComEventInterface(AppEvents);
  609. CAMCDoc* pAMCDoc = CAMCDoc::GetDocument();
  610. ASSERT(pAMCDoc != NULL);
  611. if (pAMCDoc != NULL)
  612. {
  613. pAMCDoc->SetMTNodeIDForNewView(ROOTNODEID);
  614. pAMCDoc->CreateNewView(true);
  615. }
  616. }
  617. /////////////////////////////////////////////////////////////////////////////
  618. // CMainFrame construction/destruction
  619. CMainFrame::CMainFrame()
  620. :
  621. m_hwndToNotifyCBChange(NULL),
  622. m_hwndNextCB(NULL),
  623. m_fCurrentlyMinimized(false),
  624. m_fCurrentlyActive(false)
  625. {
  626. CommonConstruct();
  627. }
  628. void CMainFrame::CommonConstruct(void)
  629. {
  630. m_pRebar = NULL;
  631. m_pMenuBar = NULL;
  632. m_pToolBar = NULL;
  633. m_pMDIChildWndFocused = NULL;
  634. m_hMenuCurrent = NULL;
  635. m_pToolbarTracker = NULL;
  636. SetInRenameMode(false);
  637. }
  638. CMainFrame::~CMainFrame()
  639. {
  640. delete m_pMenuBar;
  641. delete m_pToolBar;
  642. delete m_pRebar;
  643. delete m_pToolbarTracker;
  644. }
  645. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  646. {
  647. DECLARE_SC(sc, TEXT("CMainFrame::OnCreate"));
  648. if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
  649. return -1;
  650. if (!m_wndMDIClient.SubclassWindow(m_hWndMDIClient))
  651. {
  652. ASSERT(0 && "Failed to subclass MDI client window\n");
  653. return -1;
  654. }
  655. ASSERT(m_wndMDIClient.m_hWnd == m_hWndMDIClient);
  656. // create the rebar
  657. m_pRebar = new CRebarDockWindow;
  658. m_pRebar->Create(this,WS_CHILD|WS_VISIBLE, IDR_REBAR);
  659. // Create the toolbar like we just created the stat bar
  660. //m_wndToolBar.Create(this, WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, 0x1003);
  661. m_ToolBarDockSite.Create(CDockSite::DSS_TOP);
  662. m_ToolBarDockSite.Attach(m_pRebar);
  663. m_ToolBarDockSite.Show();
  664. m_DockingManager.Attach(&m_ToolBarDockSite);
  665. AddMainFrameBars();
  666. m_hwndNextCB = SetClipboardViewer();
  667. if (m_hwndNextCB == NULL)
  668. {
  669. LRESULT lr = GetLastError();
  670. ASSERT(lr == 0);
  671. }
  672. // append our modifications to the system menu
  673. AppendToSystemMenu (this, eMode_Last + 1);
  674. // create the toolbar tracker
  675. m_pToolbarTracker = new CToolbarTracker (this);
  676. return 0;
  677. }
  678. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  679. {
  680. if (!CMDIFrameWnd::PreCreateWindow(cs))
  681. return (FALSE);
  682. static TCHAR szClassName[countof (MAINFRAME_CLASS_NAME)];
  683. static bool fFirstTime = true;
  684. if (fFirstTime)
  685. {
  686. USES_CONVERSION;
  687. _tcscpy (szClassName, W2T (MAINFRAME_CLASS_NAME));
  688. fFirstTime = false;
  689. }
  690. WNDCLASS wc;
  691. HINSTANCE hInst = AfxGetInstanceHandle();
  692. BOOL fSuccess = GetClassInfo (hInst, szClassName, &wc);
  693. // if we haven't already registered...
  694. if (!fSuccess && ::GetClassInfo (hInst, cs.lpszClass, &wc))
  695. {
  696. // ...register a uniquely-named window class so
  697. // MMCPropertyHelp the correct main window
  698. wc.lpszClassName = szClassName;
  699. wc.hIcon = GetDefaultIcon();
  700. fSuccess = AfxRegisterClass (&wc);
  701. }
  702. if (fSuccess)
  703. {
  704. // Use the new child frame window class
  705. cs.lpszClass = szClassName;
  706. // remove MFC's title-munging styles
  707. cs.style &= ~(FWS_ADDTOTITLE | FWS_PREFIXTITLE);
  708. }
  709. return (fSuccess);
  710. }
  711. /////////////////////////////////////////////////////////////////////////////
  712. // CMainFrame diagnostics
  713. #ifdef _DEBUG
  714. void CMainFrame::AssertValid() const
  715. {
  716. CMDIFrameWnd::AssertValid();
  717. }
  718. void CMainFrame::Dump(CDumpContext& dc) const
  719. {
  720. CMDIFrameWnd::Dump(dc);
  721. }
  722. #endif //_DEBUG
  723. /////////////////////////////////////////////////////////////////////////////
  724. // CMainFrame message handlers
  725. // this code is duplicated in ..\nodemgr\propsht.cpp
  726. BOOL CALLBACK MyEnumThreadWindProc (HWND current, LPARAM lParam)
  727. { // this enumerates non-child-windows created by a given thread
  728. if (!IsWindow (current))
  729. return TRUE; // this shouldn't happen, but does!!!
  730. if (!IsWindowVisible (current)) // if they've explicitly hidden a window,
  731. return TRUE; // don't set focus to it.
  732. // we'll return hwnd in here
  733. HWND * phwnd = reinterpret_cast<HWND *>(lParam);
  734. // don't bother returning property sheet dialog window handle
  735. if (*phwnd == current)
  736. return TRUE;
  737. // also, don't return OleMainThreadWndClass window
  738. TCHAR szCaption[14];
  739. GetWindowText (current, szCaption, 14);
  740. if (!lstrcmp (szCaption, _T("OLEChannelWnd")))
  741. return TRUE;
  742. // anything else will do
  743. *phwnd = current;
  744. return FALSE;
  745. }
  746. /***************************************************************************\
  747. *
  748. * METHOD: FArePropertySheetsOpen
  749. *
  750. * PURPOSE: Checks if there are propperty sheets open and asks to close them
  751. * It is implemented as the following steps:
  752. * 1. Collect all property pages (and their children) to the stack
  753. * 2. Bring all the pages to the front, maintainig their z-order
  754. * 3. Disable all those windows, plus MMC main window to disallow switching to them
  755. * untill message box is dissmissed
  756. * 4. Put all disabled windows to the stack, to be able to re-enable them
  757. * 5. (if there are any sheets) display message box asking to close the sheets
  758. * 6. Re-enable disabled windows
  759. *
  760. * PARAMETERS:
  761. * CString* pstrUserMsg - [in] message to display
  762. * bool bBringToFrontAndAskToClose [in] if need to proceed whole way. false -> just inspect and do nothing
  763. *
  764. * RETURNS:
  765. * bool - [true == there are windows to close]
  766. *
  767. \***************************************************************************/
  768. bool FArePropertySheetsOpen(CString* pstrUserMsg, bool bBringToFrontAndAskToClose /* = true */ )
  769. {
  770. std::stack<HWND, std::vector<HWND> > WindowStack;
  771. std::stack<HWND, std::vector<HWND> > EnableWindowStack;
  772. ASSERT (WindowStack.empty());
  773. HWND hwndData = NULL;
  774. while (TRUE)
  775. {
  776. USES_CONVERSION;
  777. // Note: No need to localize this string
  778. hwndData = ::FindWindowEx(NULL, hwndData, W2T(DATAWINDOW_CLASS_NAME), NULL);
  779. if (hwndData == NULL)
  780. break; // No more windows
  781. ASSERT(IsWindow(hwndData));
  782. // Check if the window belongs to the current process
  783. DWORD dwPid = 0; // Process Id
  784. ::GetWindowThreadProcessId(hwndData, &dwPid);
  785. if (dwPid != ::GetCurrentProcessId())
  786. continue;
  787. DataWindowData* pData = GetDataWindowData (hwndData);
  788. ASSERT (pData != NULL);
  789. HWND hwndPropSheet = pData->hDlg;
  790. ASSERT (IsWindow (hwndPropSheet));
  791. // don't allow lost data window to block mmc from exiting
  792. // windows bug #425049 ntbug9 6/27/2001
  793. if ( !IsWindow (hwndPropSheet) )
  794. continue;
  795. // if propsheet has other windows or prop pages up,
  796. // then we send focus to them....
  797. // grab first one that isn't property sheet dialog
  798. HWND hwndOther = pData->hDlg;
  799. EnumThreadWindows (::GetWindowThreadProcessId(pData->hDlg, NULL),
  800. MyEnumThreadWindProc, (LPARAM)&hwndOther);
  801. // if we got another window for this property sheet, we'll want
  802. // it to be on top of the property sheet after the shuffle, so
  803. // put it under the property sheet on the stack
  804. if (IsWindow (hwndOther) && (hwndOther != hwndPropSheet))
  805. WindowStack.push (hwndOther);
  806. // push the property sheet on the stack
  807. // of windows to bring to the foreground
  808. WindowStack.push (hwndPropSheet);
  809. }
  810. bool fFoundSheets = !WindowStack.empty();
  811. // we did the investigation, see if we were asked to do more
  812. if ( !bBringToFrontAndAskToClose )
  813. return (fFoundSheets);
  814. HWND hwndMsgBoxParent = NULL;
  815. // if we found property sheets, bring them to the foreground,
  816. // maintaining their original Z-order
  817. while (!WindowStack.empty())
  818. {
  819. HWND hwnd = WindowStack.top();
  820. WindowStack.pop();
  821. SetActiveWindow (hwnd);
  822. SetForegroundWindow (hwnd);
  823. if ( ::IsWindowEnabled(hwnd) )
  824. {
  825. // disable the pages while message box is displayed
  826. ::EnableWindow( hwnd, FALSE );
  827. // remember to enable when done
  828. EnableWindowStack.push(hwnd);
  829. }
  830. hwndMsgBoxParent = hwnd; // the last one wins the right to be the parent :-)
  831. }
  832. if (fFoundSheets && pstrUserMsg)
  833. {
  834. // parent the message box on the top-most property page to make it obvios to the user
  835. CString strCaption;
  836. LPCTSTR szCaption = LoadString(strCaption, IDR_MAINFRAME) ? (LPCTSTR)strCaption : NULL;
  837. // disable main window as well
  838. CWnd *pMainWnd = AfxGetMainWnd();
  839. if ( pMainWnd && pMainWnd->IsWindowEnabled() )
  840. {
  841. pMainWnd->EnableWindow( FALSE );
  842. // remember to enable when done
  843. EnableWindowStack.push( pMainWnd->m_hWnd );
  844. }
  845. ::MessageBox( hwndMsgBoxParent, *pstrUserMsg, szCaption , MB_ICONSTOP | MB_OK );
  846. }
  847. // make everything functional again
  848. while (!EnableWindowStack.empty())
  849. {
  850. // enable the disabled window
  851. ::EnableWindow( EnableWindowStack.top(), TRUE );
  852. EnableWindowStack.pop();
  853. }
  854. return (fFoundSheets);
  855. }
  856. bool CanCloseDoc(void)
  857. {
  858. CString strMessage;
  859. CString strConsoleName;
  860. AfxGetMainWnd()->GetWindowText (strConsoleName);
  861. FormatString1 (strMessage, IDS_ClosePropertyPagesBeforeClosingTheDoc,
  862. strConsoleName);
  863. bool fPropSheets = FArePropertySheetsOpen(&strMessage);
  864. return !fPropSheets;
  865. }
  866. void CMainFrame::OnClose()
  867. {
  868. /*
  869. * Bug 233682: We need to make sure that we only handle WM_CLOSE when
  870. * it's dispatched from our main message pump. If it comes from elsewhere
  871. * (like the message pump in a modal dialog or message box), then we're
  872. * likely in a state where we can't shut down cleanly.
  873. */
  874. CAMCApp* pApp = AMCGetApp();
  875. if (!pApp->DidCloseComeFromMainPump())
  876. {
  877. pApp->DelayCloseUntilIdle();
  878. return;
  879. }
  880. // Reset the flag so that while processing this WM_CLOSE if there is
  881. // any more WM_CLOSE messages from other sources it will not be processed.
  882. pApp->ResetCloseCameFromMainPump();
  883. if (!CanCloseDoc())
  884. return;
  885. // since this process includes event posting
  886. // - we should guard the function from reentrance
  887. static bool bInProgress = false;
  888. if (!bInProgress)
  889. {
  890. bInProgress = true;
  891. CMDIFrameWnd::OnClose();
  892. bInProgress = false;
  893. }
  894. }
  895. void CMainFrame::OnUpdateFilePrint(CCmdUI* pCmdUI)
  896. {
  897. pCmdUI->Enable(FALSE);
  898. }
  899. void CMainFrame::OnUpdateFilePrintSetup(CCmdUI* pCmdUI)
  900. {
  901. pCmdUI->Enable(FALSE);
  902. }
  903. #ifdef DBG
  904. /*+-------------------------------------------------------------------------*
  905. *
  906. * CMainFrame::OnMMCTraceDialog
  907. *
  908. * PURPOSE: In Debug mode, shows the Trace dialog, in response to the hotkey.
  909. *
  910. * RETURNS:
  911. * void
  912. *
  913. *+-------------------------------------------------------------------------*/
  914. void CMainFrame::OnMMCTraceDialog()
  915. {
  916. DoDebugTraceDialog();
  917. }
  918. #endif
  919. SC CMainFrame::ScUpdateAllScopes(LONG lHint, LPARAM lParam)
  920. {
  921. AFX_MANAGE_STATE (AfxGetAppModuleState());
  922. // Updating all scopes may be requested as a result of document being deleted
  923. // in that case we do not have a document, and thus do not have any views.
  924. // So we are done.
  925. if (NULL == CAMCDoc::GetDocument())
  926. return S_OK;
  927. CAMCDoc::GetDocument()->UpdateAllViews (NULL, lHint,
  928. reinterpret_cast<CObject*>(lParam));
  929. return (S_OK);
  930. }
  931. void CMainFrame::OnViewToolbar()
  932. {
  933. m_ToolBarDockSite.Toggle();
  934. RenderDockSites();
  935. }
  936. void CMainFrame::OnUpdateViewToolbar(CCmdUI* pCmdUI)
  937. {
  938. pCmdUI->SetCheck(m_ToolBarDockSite.IsVisible());
  939. pCmdUI->Enable(true);
  940. }
  941. void CMainFrame::OnSize(UINT nType, int cx, int cy)
  942. {
  943. // Don't call MFC version to size window
  944. // CMDIFrameWnd::OnSize (nType, cx, cy);
  945. if (nType != SIZE_MINIMIZED)
  946. {
  947. RenderDockSites();
  948. MDIIconArrange();
  949. }
  950. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  951. if (pDoc != NULL)
  952. pDoc->SetFrameModifiedFlag();
  953. /*
  954. * If we're moving to or from the minimized state, notify child windows.
  955. */
  956. if (m_fCurrentlyMinimized != (nType == SIZE_MINIMIZED))
  957. {
  958. m_fCurrentlyMinimized = (nType == SIZE_MINIMIZED);
  959. SendMinimizeNotifications (m_fCurrentlyMinimized);
  960. }
  961. }
  962. void CMainFrame::OnMove(int x, int y)
  963. {
  964. CMDIFrameWnd::OnMove (x, y);
  965. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  966. if (pDoc != NULL)
  967. pDoc->SetFrameModifiedFlag();
  968. }
  969. void CMainFrame::RenderDockSites()
  970. {
  971. ASSERT_VALID (this);
  972. CRect clientRect;
  973. GetClientRect(&clientRect);
  974. m_DockingManager.BeginLayout();
  975. m_DockingManager.RenderDockSites(m_hWndMDIClient, clientRect);
  976. m_DockingManager.EndLayout();
  977. }
  978. void CMainFrame::AddMainFrameBars(void)
  979. {
  980. /*
  981. * activate our fusion context so the bars will be themed
  982. */
  983. CThemeContextActivator activator;
  984. AFX_MANAGE_STATE (AfxGetAppModuleState());
  985. DECLARE_SC(sc, _T("CMainFrame::AddMainFrameBars"));
  986. sc = ScCheckPointers(m_pRebar);
  987. if (sc)
  988. return;
  989. // insert the menu bar
  990. ASSERT (m_pMenuBar == NULL);
  991. m_pMenuBar = new CMenuBar;
  992. sc = ScCheckPointers(m_pMenuBar);
  993. if (sc)
  994. return;
  995. m_pMenuBar->Create (this, m_pRebar, WS_VISIBLE, ID_MENUBAR);
  996. m_pMenuBar->SetMenu (GetMenu ());
  997. m_pMenuBar->Show (TRUE);
  998. ASSERT(NULL == m_pToolBar);
  999. m_pToolBar = new CMMCToolBar();
  1000. sc = ScCheckPointers(m_pToolBar);
  1001. if (sc)
  1002. return;
  1003. // Create the toolbar.
  1004. sc = m_pToolBar->ScInit(m_pRebar);
  1005. if (sc)
  1006. return;
  1007. m_pToolBar->Show(TRUE, true /* In new line*/);
  1008. }
  1009. SC CMainFrame::ScCreateNewView (CreateNewViewStruct* pcnvs, bool bEmitScriptEvents /*= true*/)
  1010. {
  1011. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1012. // lock AppEvents until this function is done
  1013. LockComEventInterface(AppEvents);
  1014. DECLARE_SC (sc, _T("CMainFrame::ScCreateNewView"));
  1015. CAMCView* pNewView = NULL; // avoid "initialization skipped by 'goto Error'"
  1016. CAMCDoc* pAMCDoc = CAMCDoc::GetDocument();
  1017. ASSERT(pAMCDoc != NULL);
  1018. if (pAMCDoc == NULL)
  1019. return (sc = E_UNEXPECTED);
  1020. if (pcnvs == NULL)
  1021. return (sc = E_POINTER);
  1022. if ((AMCGetApp()->GetMode() == eMode_User_SDI) && pcnvs->fVisible)
  1023. return (sc = E_FAIL);
  1024. pAMCDoc->SetMTNodeIDForNewView (pcnvs->idRootNode);
  1025. pAMCDoc->SetNewWindowOptions (pcnvs->lWindowOptions);
  1026. pNewView = pAMCDoc->CreateNewView (pcnvs->fVisible, bEmitScriptEvents);
  1027. if (pNewView == NULL)
  1028. {
  1029. pcnvs->pViewData = NULL;
  1030. return (sc = E_FAIL);
  1031. }
  1032. pcnvs->pViewData = pNewView->GetViewData();
  1033. pcnvs->hRootNode = pNewView->GetRootNode();
  1034. return (sc);
  1035. }
  1036. void CMainFrame::OnHelpTopics()
  1037. {
  1038. ScOnHelpTopics();
  1039. }
  1040. SC CMainFrame::ScOnHelpTopics()
  1041. {
  1042. DECLARE_SC(sc, _T("CMainFrame::ScOnHelpTopics"));
  1043. /*
  1044. * if there is a view, route through it so the snap-in gets a crack
  1045. * at the help message (just like Help Topics from the Help menu).
  1046. */
  1047. CConsoleView* pConsoleView = NULL;
  1048. sc = ScGetActiveConsoleView (pConsoleView);
  1049. if (sc)
  1050. return (sc);
  1051. if (pConsoleView != NULL)
  1052. {
  1053. sc = pConsoleView->ScHelpTopics ();
  1054. return sc;
  1055. }
  1056. HH_WINTYPE hhWinType;
  1057. ZeroMemory(&hhWinType, sizeof(hhWinType));
  1058. CAMCApp* pAMCApp = AMCGetApp();
  1059. if (NULL == pAMCApp)
  1060. return (sc = E_UNEXPECTED);
  1061. sc = pAMCApp->ScShowHtmlHelp(SC::GetHelpFile(), 0);
  1062. return sc;
  1063. }
  1064. void CMainFrame::OnViewRefresh()
  1065. {
  1066. // if this doesn't fire before 10/1/99, remove this, OnUpdateViewRefresh, and all references to ID_VIEW_REFRESH (vivekj)
  1067. ASSERT(false && "If this assert ever fires, then we need ID_VIEW_REFRESH (see above) and we can remove the 'Do we need this?' and this assert");
  1068. CAMCTreeView* pAMCTreeView = _GetActiveAMCTreeView();
  1069. if (pAMCTreeView)
  1070. pAMCTreeView->ScReselect();
  1071. }
  1072. void CMainFrame::OnUpdateViewRefresh(CCmdUI* pCmdUI)
  1073. {
  1074. // if this doesn't fire before 10/1/99, remove this, OnUpdateView, and all references to ID_VIEW_REFRESH (vivekj)
  1075. ASSERT(false && "If this assert ever fires, then we need ID_VIEW_REFRESH (see above) and we can remove the 'Do we need this?' and this assert");
  1076. pCmdUI->Enable(TRUE);
  1077. }
  1078. void CMainFrame::OnDestroy()
  1079. {
  1080. if (m_hwndNextCB)
  1081. ChangeClipboardChain(m_hwndNextCB);
  1082. CMDIFrameWnd::OnDestroy();
  1083. }
  1084. void CMainFrame::OnUpdateFrameMenu(HMENU hMenuAlt)
  1085. {
  1086. // let the base class select the right menu
  1087. CMDIFrameWnd::OnUpdateFrameMenu (hMenuAlt);
  1088. // by now, the right menu is on the frame; reflect it to the toolbar
  1089. NotifyMenuChanged ();
  1090. }
  1091. void CMainFrame::NotifyMenuChanged ()
  1092. {
  1093. CMenu* pMenuCurrent = NULL;
  1094. // make sure we don't have menus for MDI or SDI User mode
  1095. switch (AMCGetApp()->GetMode())
  1096. {
  1097. case eMode_Author:
  1098. case eMode_User:
  1099. case eMode_User_MDI:
  1100. case eMode_User_SDI:
  1101. pMenuCurrent = CWnd::GetMenu();
  1102. break;
  1103. default:
  1104. ASSERT (false);
  1105. break;
  1106. }
  1107. m_hMenuCurrent = pMenuCurrent->GetSafeHmenu();
  1108. if (m_pMenuBar != NULL)
  1109. {
  1110. // reflect the new menu on the menu bar
  1111. m_pMenuBar->SetMenu (pMenuCurrent);
  1112. // detach the menu from the frame
  1113. SetMenu (NULL);
  1114. }
  1115. }
  1116. BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
  1117. {
  1118. /*
  1119. * If mainframe is not the active window then do not translate
  1120. * the messages. (See Bug# 119355)
  1121. */
  1122. if (!m_fCurrentlyActive)
  1123. return (FALSE);
  1124. CRebarWnd* pwndRebar = m_pRebar->GetRebar();
  1125. // give the rebar a crack
  1126. if (pwndRebar && pwndRebar->PreTranslateMessage (pMsg))
  1127. return (TRUE);
  1128. // give the menu bar a crack (for menu accelerators)
  1129. if (m_pMenuBar && m_pMenuBar->PreTranslateMessage (pMsg))
  1130. return (TRUE);
  1131. // give the base class a crack
  1132. if ((InRenameMode() == false) &&
  1133. (CMDIFrameWnd::PreTranslateMessage(pMsg)))
  1134. return (TRUE);
  1135. // not translated
  1136. return (FALSE);
  1137. }
  1138. void CMainFrame::OnIdle ()
  1139. {
  1140. if (m_pMenuBar != NULL)
  1141. {
  1142. CMDIChildWnd* pwndActive = MDIGetActive ();
  1143. // The menus are always visible in SDI & MDI modes.
  1144. switch (AMCGetApp()->GetMode())
  1145. {
  1146. case eMode_User_SDI:
  1147. {
  1148. BOOL bMaximized = (pwndActive != NULL) ? pwndActive->IsZoomed () : false;
  1149. ASSERT (bMaximized);
  1150. ASSERT (IsMenuVisible());
  1151. }
  1152. break;
  1153. case eMode_User_MDI:
  1154. ASSERT (pwndActive != NULL);
  1155. ASSERT (IsMenuVisible());
  1156. break;
  1157. }
  1158. ASSERT (m_pMenuBar->GetMenu() != NULL);
  1159. m_pMenuBar->OnIdle ();
  1160. }
  1161. }
  1162. void CMainFrame::ShowMenu (bool fShow)
  1163. {
  1164. CRebarWnd * pwndRebar = m_pRebar->GetRebar();
  1165. pwndRebar->ShowBand (pwndRebar->IdToIndex (ID_MENUBAR), fShow);
  1166. /*---------------------------------------------------------------------*/
  1167. /* if we're showing, the rebar must be showing, too; */
  1168. /* if we're hiding, the rebar should be hidden if no bands are visible */
  1169. /*---------------------------------------------------------------------*/
  1170. if ( fShow && !m_pRebar->IsVisible())
  1171. {
  1172. m_pRebar->Show (fShow);
  1173. RenderDockSites ();
  1174. }
  1175. }
  1176. static bool IsRebarBandVisible (CRebarWnd* pwndRebar, int nBandID)
  1177. {
  1178. REBARBANDINFO rbbi;
  1179. ZeroMemory (&rbbi, sizeof (rbbi));
  1180. rbbi.cbSize = sizeof (rbbi);
  1181. rbbi.fMask = RBBIM_STYLE;
  1182. pwndRebar->GetBandInfo (pwndRebar->IdToIndex (nBandID), &rbbi);
  1183. return ((rbbi.fStyle & RBBS_HIDDEN) == 0);
  1184. }
  1185. bool CMainFrame::IsMenuVisible ()
  1186. {
  1187. return (IsRebarBandVisible (m_pRebar->GetRebar(), ID_MENUBAR));
  1188. }
  1189. /////////////////////////////////////////////////////////////////////////////
  1190. // Special UI processing depending on current active child
  1191. CString CMainFrame::GetFrameTitle()
  1192. {
  1193. /*
  1194. * If there's no active child window, then the document
  1195. * is being closed. Just use the default title.
  1196. */
  1197. if (MDIGetActive() != NULL)
  1198. {
  1199. CAMCDoc* pDocument = CAMCDoc::GetDocument();
  1200. /*
  1201. * If there's a document, use its title.
  1202. */
  1203. if (pDocument != NULL)
  1204. return (pDocument->GetCustomTitle());
  1205. }
  1206. return (m_strGenericTitle);
  1207. }
  1208. void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
  1209. {
  1210. AfxSetWindowText(m_hWnd, GetFrameTitle());
  1211. }
  1212. BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
  1213. {
  1214. if (!CMDIFrameWnd::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
  1215. return (FALSE);
  1216. // save the title we'll use for the main frame if there's no console open
  1217. m_strGenericTitle = m_strTitle;
  1218. return (TRUE);
  1219. }
  1220. void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
  1221. {
  1222. switch (nID)
  1223. {
  1224. case ID_HELP_HELPTOPICS:
  1225. OnHelpTopics ();
  1226. break;
  1227. case ID_CUSTOMIZE_VIEW:
  1228. {
  1229. CChildFrame* pwndActive = dynamic_cast<CChildFrame*>(MDIGetActive ());
  1230. if (pwndActive != NULL)
  1231. pwndActive->OnSysCommand (nID, lParam);
  1232. else
  1233. CMDIFrameWnd::OnSysCommand(nID, lParam);
  1234. break;
  1235. }
  1236. default:
  1237. CMDIFrameWnd::OnSysCommand(nID, lParam);
  1238. break;
  1239. }
  1240. }
  1241. void CMainFrame::UpdateChildSystemMenus ()
  1242. {
  1243. ProgramMode eMode = AMCGetApp()->GetMode();
  1244. // make necessary modifications to existing windows' system menus
  1245. for (CWnd* pwndT = MDIGetActive();
  1246. pwndT != NULL;
  1247. pwndT = pwndT->GetWindow (GW_HWNDNEXT))
  1248. {
  1249. CMenu* pSysMenu = pwndT->GetSystemMenu (FALSE);
  1250. if (pSysMenu != NULL)
  1251. {
  1252. // if not in author mode, protect author mode windows from
  1253. // user close
  1254. if (eMode != eMode_Author)
  1255. {
  1256. // Get AMCView object for this frame
  1257. CChildFrame *pChildFrm = dynamic_cast<CChildFrame*>(pwndT);
  1258. ASSERT(pChildFrm != NULL);
  1259. CAMCView* pView = pChildFrm->GetAMCView();
  1260. ASSERT(pView != NULL);
  1261. // if it's an author mode view, don't let user close it
  1262. if (pView && pView->IsAuthorModeView())
  1263. pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
  1264. }
  1265. // if we're not in SDI User mode, append common stuff
  1266. if (eMode != eMode_User_SDI)
  1267. AppendToSystemMenu (pwndT, eMode);
  1268. }
  1269. }
  1270. }
  1271. void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
  1272. {
  1273. CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
  1274. if (bSysMenu)
  1275. {
  1276. int nEnable = MF_GRAYED;
  1277. CChildFrame* pwndActive = dynamic_cast<CChildFrame*>(MDIGetActive ());
  1278. // if there's an active child, let it handle system menu validation
  1279. if ((pwndActive != NULL) && (pwndActive->IsCustomizeViewEnabled()))
  1280. nEnable = MF_ENABLED;
  1281. pPopupMenu->EnableMenuItem (ID_CUSTOMIZE_VIEW, MF_BYCOMMAND | nEnable);
  1282. }
  1283. else
  1284. {
  1285. // Check if Help menu by testing for "Help Topics" item
  1286. if (pPopupMenu->GetMenuState(ID_HELP_HELPTOPICS, MF_BYCOMMAND) != UINT(-1))
  1287. {
  1288. // View will update item
  1289. CAMCView* pView = GetActiveAMCView();
  1290. if (pView != NULL)
  1291. {
  1292. pView->UpdateSnapInHelpMenus(pPopupMenu);
  1293. }
  1294. }
  1295. }
  1296. }
  1297. LRESULT CMainFrame::OnShowSnapinHelpTopic (WPARAM wParam, LPARAM lParam)
  1298. {
  1299. DECLARE_SC (sc, _T("CMainFrame::OnShowSnapinHelpTopic"));
  1300. CConsoleView* pConsoleView;
  1301. sc = ScGetActiveConsoleView (pConsoleView);
  1302. if (sc)
  1303. return (sc.ToHr());
  1304. /*
  1305. * ScGetActiveConsoleView will return success (S_FALSE) even if there's no
  1306. * active view. This is a valid case, occuring when there's no console
  1307. * file open. In this particular circumstance, it is an unexpected
  1308. * failure since we shouldn't get to this point in the code if there's
  1309. * no view.
  1310. */
  1311. sc = ScCheckPointers (pConsoleView, E_UNEXPECTED);
  1312. if (sc)
  1313. return (sc.ToHr());
  1314. // forward this on the the active AMC view window
  1315. USES_CONVERSION;
  1316. sc = pConsoleView->ScShowSnapinHelpTopic (W2T (reinterpret_cast<LPOLESTR>(lParam)));
  1317. return (sc.ToHr());
  1318. }
  1319. SC CMainFrame::ScGetMenuAccelerators (LPTSTR pBuffer, int cchBuffer)
  1320. {
  1321. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1322. if ((m_pMenuBar != NULL) && IsMenuVisible())
  1323. m_pMenuBar->GetAccelerators (cchBuffer, pBuffer);
  1324. else if (cchBuffer > 0)
  1325. pBuffer[0] = 0;
  1326. return (S_OK);
  1327. }
  1328. //+-------------------------------------------------------------------
  1329. //
  1330. // Member: CMainFrame::ScShowMMCMenus
  1331. //
  1332. // Synopsis: Show or hide MMC menus. (Action/View/Favs)
  1333. //
  1334. // Arguments: bShow
  1335. //
  1336. // Returns: SC
  1337. //
  1338. //--------------------------------------------------------------------
  1339. SC CMainFrame::ScShowMMCMenus (bool bShow)
  1340. {
  1341. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1342. DECLARE_SC(sc, _T("CMainFrame::ScShowMMCMenus"));
  1343. if ((m_pMenuBar != NULL) && IsMenuVisible())
  1344. sc = m_pMenuBar->ScShowMMCMenus(bShow);
  1345. else
  1346. return (sc = E_UNEXPECTED);
  1347. return (sc);
  1348. }
  1349. //////////////////////////////////////////////////////////////////////////////
  1350. // This message is received from the node manager whenever a property
  1351. // sheet use the MMCPropertyChangeNotify() api.
  1352. // The wParam contains a copy of the handle information which must be freed.
  1353. //
  1354. LRESULT CMainFrame::OnPropertySheetNotify(WPARAM wParam, LPARAM lParam)
  1355. {
  1356. TRACE_METHOD(CAMCView, OnPropertySheetNotify);
  1357. ASSERT(wParam != 0);
  1358. LPPROPERTYNOTIFYINFO pNotify = reinterpret_cast<LPPROPERTYNOTIFYINFO>(wParam);
  1359. // Crack the information from the handle object and send a notify to the snap-in
  1360. ASSERT((pNotify->pComponent != NULL || pNotify->pComponentData != NULL));
  1361. if (pNotify->pComponent != NULL)
  1362. pNotify->pComponent->Notify(NULL, MMCN_PROPERTY_CHANGE, pNotify->fScopePane, lParam);
  1363. else if (pNotify->pComponentData != NULL)
  1364. pNotify->pComponentData->Notify(NULL, MMCN_PROPERTY_CHANGE, pNotify->fScopePane, lParam);
  1365. ::GlobalFree(pNotify);
  1366. return TRUE;
  1367. }
  1368. LRESULT CMainFrame::OnSetText (WPARAM wParam, LPARAM lParam)
  1369. {
  1370. LRESULT rc;
  1371. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  1372. /*
  1373. * If the document has a custom title, we don't want to append
  1374. * the maxed child's title to the main frame's title. To do this,
  1375. * we'll bypass DefFrameProc and go directly to DefWindowProc.
  1376. */
  1377. if ((pDoc != NULL) && pDoc->HasCustomTitle())
  1378. rc = CWnd::DefWindowProc (WM_SETTEXT, wParam, lParam);
  1379. else
  1380. rc = Default();
  1381. DrawFrameCaption (this, m_fCurrentlyActive);
  1382. return (rc);
  1383. }
  1384. void CMainFrame::OnPaletteChanged( CWnd* pwndFocus)
  1385. {
  1386. if (pwndFocus != this)
  1387. {
  1388. CAMCDoc* pAMCDoc = CAMCDoc::GetDocument();
  1389. if (pAMCDoc)
  1390. {
  1391. HWND hwndFocus = pwndFocus->GetSafeHwnd();
  1392. CAMCViewPosition pos = pAMCDoc->GetFirstAMCViewPosition();
  1393. while (pos != NULL)
  1394. {
  1395. CAMCView* pv = pAMCDoc->GetNextAMCView(pos);
  1396. if (pv)
  1397. pv->SendMessage(WM_PALETTECHANGED, (WPARAM)hwndFocus);
  1398. }
  1399. }
  1400. }
  1401. CMDIFrameWnd::OnPaletteChanged(pwndFocus);
  1402. }
  1403. BOOL CMainFrame::OnQueryNewPalette()
  1404. {
  1405. CAMCView* pAMCView = GetActiveAMCView();
  1406. if (pAMCView != NULL)
  1407. return pAMCView->SendMessage(WM_QUERYNEWPALETTE);
  1408. return CMDIFrameWnd::OnQueryNewPalette();
  1409. }
  1410. void CMainFrame::OnConsoleProperties()
  1411. {
  1412. CConsolePropSheet().DoModal();
  1413. }
  1414. void CMainFrame::SetIconEx (HICON hIcon, BOOL fBig)
  1415. {
  1416. if (hIcon == NULL)
  1417. hIcon = GetDefaultIcon();
  1418. SetIcon (hIcon, fBig);
  1419. /*
  1420. * make sure the child icon on the menu bar gets updated
  1421. */
  1422. ASSERT (m_pMenuBar != NULL);
  1423. m_pMenuBar->InvalidateMaxedChildIcon();
  1424. }
  1425. /*+-------------------------------------------------------------------------*
  1426. * CMainFrame::GetDefaultIcon
  1427. *
  1428. *
  1429. *--------------------------------------------------------------------------*/
  1430. HICON CMainFrame::GetDefaultIcon () const
  1431. {
  1432. return (AfxGetApp()->LoadIcon (IDR_MAINFRAME));
  1433. }
  1434. /*+-------------------------------------------------------------------------*
  1435. * CMainFrame::SendMinimizeNotifications
  1436. *
  1437. * Causes each CChildFrame to send NCLBK_MINIMIZED.
  1438. *--------------------------------------------------------------------------*/
  1439. void CMainFrame::SendMinimizeNotifications (bool fMinimized) const
  1440. {
  1441. CWnd* pwndMDIChild;
  1442. for (pwndMDIChild = m_wndMDIClient.GetWindow (GW_CHILD);
  1443. pwndMDIChild != NULL;
  1444. pwndMDIChild = pwndMDIChild->GetWindow (GW_HWNDNEXT))
  1445. {
  1446. // There used to be an ASSERT_ISKINDOF. However, that had to change to an if
  1447. // since the active background denies that assumption. See bug 428906.
  1448. if(pwndMDIChild->IsKindOf(RUNTIME_CLASS(CChildFrame)))
  1449. (static_cast<CChildFrame*>(pwndMDIChild))->SendMinimizeNotification (fMinimized);
  1450. }
  1451. }
  1452. /*+-------------------------------------------------------------------------*
  1453. * CMainFrame::OnNcActivate
  1454. *
  1455. * WM_NCACTIVATE handler for CMainFrame.
  1456. *--------------------------------------------------------------------------*/
  1457. BOOL CMainFrame::OnNcActivate(BOOL bActive)
  1458. {
  1459. BOOL rc = CMDIFrameWnd::OnNcActivate(bActive);
  1460. DrawFrameCaption (this, m_fCurrentlyActive);
  1461. return (rc);
  1462. }
  1463. /*+-------------------------------------------------------------------------*
  1464. * CMainFrame::OnNcPaint
  1465. *
  1466. * WM_NCPAINT handler for CMainFrame.
  1467. *--------------------------------------------------------------------------*/
  1468. void CMainFrame::OnNcPaint()
  1469. {
  1470. Default();
  1471. DrawFrameCaption (this, m_fCurrentlyActive);
  1472. }
  1473. /*+-------------------------------------------------------------------------*
  1474. * MsgForwardingEnumProc
  1475. *
  1476. *
  1477. *--------------------------------------------------------------------------*/
  1478. static BOOL CALLBACK MsgForwardingEnumProc (HWND hwnd, LPARAM lParam)
  1479. {
  1480. /*
  1481. * if this isn't an MFC window, forward the message
  1482. */
  1483. if (CWnd::FromHandlePermanent(hwnd) == NULL)
  1484. {
  1485. const MSG* pMsg = (const MSG*) lParam;
  1486. SendMessage (hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
  1487. }
  1488. /*
  1489. * continue enumeration
  1490. */
  1491. return (true);
  1492. }
  1493. /*+-------------------------------------------------------------------------*
  1494. * CMainFrame::OnSettingChange
  1495. *
  1496. * WM_SETTINGCHANGE handler for CMainFrame.
  1497. *--------------------------------------------------------------------------*/
  1498. void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  1499. {
  1500. CMDIFrameWnd::OnSettingChange(uFlags, lpszSection);
  1501. /*
  1502. * MFC will send WM_SETTINGCHANGEs to all descendent MFC windows.
  1503. * There are some non-MFC windows owned by nodemgr that we also want
  1504. * to get this message. We'll send these manually.
  1505. */
  1506. const MSG* pMsg = GetCurrentMessage();
  1507. EnumChildWindows (m_hWnd, MsgForwardingEnumProc, (LPARAM) pMsg);
  1508. /*
  1509. * If we're in SDI mode, then there can be some redrawing problems
  1510. * around the caption if the caption height changes significantly.
  1511. * (This is a USER MDI bug.) We can work around it by manually
  1512. * placing the maximized child window within the MDI client.
  1513. *
  1514. * Note that restoring and re-maximizing the active child window
  1515. * will put the window in the right place, it has the side effect
  1516. * of undesired window flicker (see 375430, et al) as well as
  1517. * a bunch of annoying sound effects if you have sounds associated
  1518. * with the "Restore Down" and/or "Maximize" sound events.
  1519. */
  1520. if (AMCGetApp()->GetMode() == eMode_User_SDI)
  1521. {
  1522. CMDIChildWnd* pwndActive = MDIGetActive();
  1523. if (pwndActive)
  1524. {
  1525. /*
  1526. * get the size of the MDI client
  1527. */
  1528. CRect rect;
  1529. m_wndMDIClient.GetClientRect (rect);
  1530. /*
  1531. * inflate the MDI client's client rect by the size of sizing
  1532. * borders, and add room for the caption at the top
  1533. */
  1534. rect.InflateRect (GetSystemMetrics (SM_CXFRAME),
  1535. GetSystemMetrics (SM_CYFRAME));
  1536. rect.top -= GetSystemMetrics (SM_CYCAPTION);
  1537. /*
  1538. * put the window in the right place
  1539. */
  1540. pwndActive->MoveWindow (rect);
  1541. }
  1542. }
  1543. }
  1544. /*+-------------------------------------------------------------------------*
  1545. * CMainFrame::ScGetActiveStatusBar
  1546. *
  1547. * Returns the CConsoleStatusBar interface for the active view. If there's no
  1548. * active view, pStatusBar is set to NULL and S_FALSE is returned.
  1549. *--------------------------------------------------------------------------*/
  1550. SC CMainFrame::ScGetActiveStatusBar (
  1551. CConsoleStatusBar*& pStatusBar) /* O:CConsoleStatusBar for active view*/
  1552. {
  1553. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1554. DECLARE_SC (sc, _T("CMainFrame::ScGetActiveStatusBar"));
  1555. pStatusBar = dynamic_cast<CConsoleStatusBar*>(GetActiveFrame());
  1556. if (pStatusBar == NULL)
  1557. sc = S_FALSE;
  1558. return (sc);
  1559. }
  1560. /*+-------------------------------------------------------------------------*
  1561. * CMainFrame::ScGetActiveConsoleView
  1562. *
  1563. * Returns the CConsoleView interface for the active view. If there's no
  1564. * active view, pConsoleView is set to NULL and S_FALSE is returned.
  1565. *--------------------------------------------------------------------------*/
  1566. SC CMainFrame::ScGetActiveConsoleView (
  1567. CConsoleView*& pConsoleView) /* O:CConsoleView for active view */
  1568. {
  1569. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1570. DECLARE_SC (sc, _T("CMainFrame::ScGetActiveConsoleView"));
  1571. pConsoleView = GetActiveAMCView();
  1572. if (pConsoleView == NULL)
  1573. sc = S_FALSE;
  1574. return (sc);
  1575. }
  1576. /***************************************************************************\
  1577. *
  1578. * METHOD: CMainFrame::OnUnInitMenuPopup
  1579. *
  1580. * PURPOSE: Used to remove accelerators once system menus are dismissed
  1581. *
  1582. * PARAMETERS:
  1583. * WPARAM wParam
  1584. * LPARAM lParam
  1585. *
  1586. * RETURNS:
  1587. * LRESULT - result code
  1588. *
  1589. \***************************************************************************/
  1590. afx_msg LRESULT CMainFrame::OnUnInitMenuPopup(WPARAM wParam, LPARAM lParam)
  1591. {
  1592. // hide accelerators whenever leaving system popup
  1593. if ( HIWORD(lParam) & MF_SYSMENU )
  1594. {
  1595. SendMessage( WM_CHANGEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEACCEL | UISF_HIDEFOCUS));
  1596. }
  1597. return 0;
  1598. }