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.

2054 lines
57 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. DECLARE_SC(sc, TEXT("CMainFrame::PreCreateWindow"));
  681. if (!CMDIFrameWnd::PreCreateWindow(cs))
  682. return (FALSE);
  683. static TCHAR szClassName[countof (MAINFRAME_CLASS_NAME)];
  684. static bool fFirstTime = true;
  685. if (fFirstTime)
  686. {
  687. USES_CONVERSION;
  688. sc = StringCchCopy(szClassName, countof (MAINFRAME_CLASS_NAME), W2T (MAINFRAME_CLASS_NAME));
  689. if (sc)
  690. return FALSE;
  691. fFirstTime = false;
  692. }
  693. WNDCLASS wc;
  694. HINSTANCE hInst = AfxGetInstanceHandle();
  695. BOOL fSuccess = GetClassInfo (hInst, szClassName, &wc);
  696. // if we haven't already registered...
  697. if (!fSuccess && ::GetClassInfo (hInst, cs.lpszClass, &wc))
  698. {
  699. // ...register a uniquely-named window class so
  700. // MMCPropertyHelp the correct main window
  701. wc.lpszClassName = szClassName;
  702. wc.hIcon = GetDefaultIcon();
  703. fSuccess = AfxRegisterClass (&wc);
  704. }
  705. if (fSuccess)
  706. {
  707. // Use the new child frame window class
  708. cs.lpszClass = szClassName;
  709. // remove MFC's title-munging styles
  710. cs.style &= ~(FWS_ADDTOTITLE | FWS_PREFIXTITLE);
  711. }
  712. return (fSuccess);
  713. }
  714. /////////////////////////////////////////////////////////////////////////////
  715. // CMainFrame diagnostics
  716. #ifdef _DEBUG
  717. void CMainFrame::AssertValid() const
  718. {
  719. CMDIFrameWnd::AssertValid();
  720. }
  721. void CMainFrame::Dump(CDumpContext& dc) const
  722. {
  723. CMDIFrameWnd::Dump(dc);
  724. }
  725. #endif //_DEBUG
  726. /////////////////////////////////////////////////////////////////////////////
  727. // CMainFrame message handlers
  728. // this code is duplicated in ..\nodemgr\propsht.cpp
  729. BOOL CALLBACK MyEnumThreadWindProc (HWND current, LPARAM lParam)
  730. { // this enumerates non-child-windows created by a given thread
  731. if (!IsWindow (current))
  732. return TRUE; // this shouldn't happen, but does!!!
  733. if (!IsWindowVisible (current)) // if they've explicitly hidden a window,
  734. return TRUE; // don't set focus to it.
  735. // we'll return hwnd in here
  736. HWND * phwnd = reinterpret_cast<HWND *>(lParam);
  737. // don't bother returning property sheet dialog window handle
  738. if (*phwnd == current)
  739. return TRUE;
  740. // also, don't return OleMainThreadWndClass window
  741. TCHAR szCaption[14];
  742. if (GetWindowText (current, szCaption, countof(szCaption)))
  743. if (!lstrcmp (szCaption, _T("OLEChannelWnd")))
  744. return TRUE;
  745. // anything else will do
  746. *phwnd = current;
  747. return FALSE;
  748. }
  749. /***************************************************************************\
  750. *
  751. * METHOD: FArePropertySheetsOpen
  752. *
  753. * PURPOSE: Checks if there are propperty sheets open and asks to close them
  754. * It is implemented as the following steps:
  755. * 1. Collect all property pages (and their children) to the stack
  756. * 2. Bring all the pages to the front, maintainig their z-order
  757. * 3. Disable all those windows, plus MMC main window to disallow switching to them
  758. * untill message box is dissmissed
  759. * 4. Put all disabled windows to the stack, to be able to re-enable them
  760. * 5. (if there are any sheets) display message box asking to close the sheets
  761. * 6. Re-enable disabled windows
  762. *
  763. * PARAMETERS:
  764. * CString* pstrUserMsg - [in] message to display
  765. * bool bBringToFrontAndAskToClose [in] if need to proceed whole way. false -> just inspect and do nothing
  766. *
  767. * RETURNS:
  768. * bool - [true == there are windows to close]
  769. *
  770. \***************************************************************************/
  771. bool FArePropertySheetsOpen(CString* pstrUserMsg, bool bBringToFrontAndAskToClose /* = true */ )
  772. {
  773. std::stack<HWND, std::vector<HWND> > WindowStack;
  774. std::stack<HWND, std::vector<HWND> > EnableWindowStack;
  775. ASSERT (WindowStack.empty());
  776. HWND hwndData = NULL;
  777. while (TRUE)
  778. {
  779. USES_CONVERSION;
  780. // Note: No need to localize this string
  781. hwndData = ::FindWindowEx(NULL, hwndData, W2T(DATAWINDOW_CLASS_NAME), NULL);
  782. if (hwndData == NULL)
  783. break; // No more windows
  784. ASSERT(IsWindow(hwndData));
  785. // Check if the window belongs to the current process
  786. DWORD dwPid = 0; // Process Id
  787. ::GetWindowThreadProcessId(hwndData, &dwPid);
  788. if (dwPid != ::GetCurrentProcessId())
  789. continue;
  790. DataWindowData* pData = GetDataWindowData (hwndData);
  791. ASSERT (pData != NULL);
  792. HWND hwndPropSheet = pData->hDlg;
  793. ASSERT (IsWindow (hwndPropSheet));
  794. // don't allow lost data window to block mmc from exiting
  795. // windows bug #425049 ntbug9 6/27/2001
  796. if ( !IsWindow (hwndPropSheet) )
  797. continue;
  798. // if propsheet has other windows or prop pages up,
  799. // then we send focus to them....
  800. // grab first one that isn't property sheet dialog
  801. HWND hwndOther = pData->hDlg;
  802. EnumThreadWindows (::GetWindowThreadProcessId(pData->hDlg, NULL),
  803. MyEnumThreadWindProc, (LPARAM)&hwndOther);
  804. // if we got another window for this property sheet, we'll want
  805. // it to be on top of the property sheet after the shuffle, so
  806. // put it under the property sheet on the stack
  807. if (IsWindow (hwndOther) && (hwndOther != hwndPropSheet))
  808. WindowStack.push (hwndOther);
  809. // push the property sheet on the stack
  810. // of windows to bring to the foreground
  811. WindowStack.push (hwndPropSheet);
  812. }
  813. bool fFoundSheets = !WindowStack.empty();
  814. // we did the investigation, see if we were asked to do more
  815. if ( !bBringToFrontAndAskToClose )
  816. return (fFoundSheets);
  817. HWND hwndMsgBoxParent = NULL;
  818. // if we found property sheets, bring them to the foreground,
  819. // maintaining their original Z-order
  820. while (!WindowStack.empty())
  821. {
  822. HWND hwnd = WindowStack.top();
  823. WindowStack.pop();
  824. SetActiveWindow (hwnd);
  825. SetForegroundWindow (hwnd);
  826. if ( ::IsWindowEnabled(hwnd) )
  827. {
  828. // disable the pages while message box is displayed
  829. ::EnableWindow( hwnd, FALSE );
  830. // remember to enable when done
  831. EnableWindowStack.push(hwnd);
  832. }
  833. hwndMsgBoxParent = hwnd; // the last one wins the right to be the parent :-)
  834. }
  835. if (fFoundSheets && pstrUserMsg)
  836. {
  837. // parent the message box on the top-most property page to make it obvios to the user
  838. CString strCaption;
  839. LPCTSTR szCaption = LoadString(strCaption, IDR_MAINFRAME) ? (LPCTSTR)strCaption : NULL;
  840. // disable main window as well
  841. CWnd *pMainWnd = AfxGetMainWnd();
  842. if ( pMainWnd && pMainWnd->IsWindowEnabled() )
  843. {
  844. pMainWnd->EnableWindow( FALSE );
  845. // remember to enable when done
  846. EnableWindowStack.push( pMainWnd->m_hWnd );
  847. }
  848. ::MessageBox( hwndMsgBoxParent, *pstrUserMsg, szCaption , MB_ICONSTOP | MB_OK );
  849. }
  850. // make everything functional again
  851. while (!EnableWindowStack.empty())
  852. {
  853. // enable the disabled window
  854. ::EnableWindow( EnableWindowStack.top(), TRUE );
  855. EnableWindowStack.pop();
  856. }
  857. return (fFoundSheets);
  858. }
  859. bool CanCloseDoc(void)
  860. {
  861. CString strMessage;
  862. CString strConsoleName;
  863. AfxGetMainWnd()->GetWindowText (strConsoleName);
  864. FormatString1 (strMessage, IDS_ClosePropertyPagesBeforeClosingTheDoc,
  865. strConsoleName);
  866. bool fPropSheets = FArePropertySheetsOpen(&strMessage);
  867. return !fPropSheets;
  868. }
  869. void CMainFrame::OnClose()
  870. {
  871. /*
  872. * Bug 233682: We need to make sure that we only handle WM_CLOSE when
  873. * it's dispatched from our main message pump. If it comes from elsewhere
  874. * (like the message pump in a modal dialog or message box), then we're
  875. * likely in a state where we can't shut down cleanly.
  876. */
  877. CAMCApp* pApp = AMCGetApp();
  878. if (!pApp->DidCloseComeFromMainPump())
  879. {
  880. pApp->DelayCloseUntilIdle();
  881. return;
  882. }
  883. // Reset the flag so that while processing this WM_CLOSE if there is
  884. // any more WM_CLOSE messages from other sources it will not be processed.
  885. pApp->ResetCloseCameFromMainPump();
  886. if (!CanCloseDoc())
  887. return;
  888. // since this process includes event posting
  889. // - we should guard the function from reentrance
  890. static bool bInProgress = false;
  891. if (!bInProgress)
  892. {
  893. bInProgress = true;
  894. CMDIFrameWnd::OnClose();
  895. bInProgress = false;
  896. }
  897. }
  898. void CMainFrame::OnUpdateFilePrint(CCmdUI* pCmdUI)
  899. {
  900. pCmdUI->Enable(FALSE);
  901. }
  902. void CMainFrame::OnUpdateFilePrintSetup(CCmdUI* pCmdUI)
  903. {
  904. pCmdUI->Enable(FALSE);
  905. }
  906. #ifdef DBG
  907. /*+-------------------------------------------------------------------------*
  908. *
  909. * CMainFrame::OnMMCTraceDialog
  910. *
  911. * PURPOSE: In Debug mode, shows the Trace dialog, in response to the hotkey.
  912. *
  913. * RETURNS:
  914. * void
  915. *
  916. *+-------------------------------------------------------------------------*/
  917. void CMainFrame::OnMMCTraceDialog()
  918. {
  919. DoDebugTraceDialog();
  920. }
  921. #endif
  922. /***************************************************************************\
  923. *
  924. * METHOD: ScUpdateAllScopes
  925. *
  926. * PURPOSE: Just calls CDocument::UpdateAllViews.
  927. * If we want to Update all views to delete empty views then
  928. * First it gets list of empty views and then it closes them.
  929. *
  930. * PARAMETERS:
  931. * lHint - [in] The action to perform.
  932. * lParam - [in] Extra context info.
  933. *
  934. * RETURNS:
  935. * SC
  936. *
  937. \***************************************************************************/
  938. SC CMainFrame::ScUpdateAllScopes(LONG lHint, LPARAM lParam)
  939. {
  940. AFX_MANAGE_STATE (AfxGetAppModuleState());
  941. DECLARE_SC(sc, TEXT("CMainFrame::ScUpdateAllScopes"));
  942. // Updating all scopes may be requested as a result of document being deleted
  943. // in that case we do not have a document, and thus do not have any views.
  944. // So we are done.
  945. if (NULL == CAMCDoc::GetDocument())
  946. return sc;
  947. // Special case, we cannot destroy the view during CDocument::UpdateAllViews
  948. // as CDocument is enumerating the view collection. Nor we can do PostMessage
  949. // to close view as scripts in (479627) web pages execute. Therefore we get the
  950. // list of empty views and then destroy them.
  951. if (lHint == VIEW_UPDATE_DELETE_EMPTY_VIEW)
  952. {
  953. // Get the list of AMCViews to be deleted.
  954. if (lParam != NULL)
  955. return (sc = E_UNEXPECTED);
  956. CArray<CAMCView*, CAMCView*> rgEmptyAMCViews;
  957. CAMCDoc::GetDocument()->UpdateAllViews (NULL, lHint, reinterpret_cast<CObject*>(&rgEmptyAMCViews));
  958. // Now destroy each view.
  959. for (int i = 0; i < rgEmptyAMCViews.GetSize(); i++)
  960. {
  961. CAMCView *pAMCView = rgEmptyAMCViews.GetAt(i);
  962. sc = ScCheckPointers(pAMCView);
  963. if (sc)
  964. {
  965. sc.TraceAndClear();
  966. continue;
  967. }
  968. CChildFrame* pFrame = pAMCView->GetParentFrame();
  969. sc = ScCheckPointers(pFrame);
  970. if (sc)
  971. {
  972. sc.TraceAndClear();
  973. continue;
  974. }
  975. // Send WM_CLOSE Synchronously else the web page views with scripts in them will
  976. // have their scripts executed and may AV.
  977. pFrame->SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
  978. }
  979. }
  980. else
  981. CAMCDoc::GetDocument()->UpdateAllViews (NULL, lHint,
  982. reinterpret_cast<CObject*>(lParam));
  983. return (sc);
  984. }
  985. void CMainFrame::OnViewToolbar()
  986. {
  987. m_ToolBarDockSite.Toggle();
  988. RenderDockSites();
  989. }
  990. void CMainFrame::OnUpdateViewToolbar(CCmdUI* pCmdUI)
  991. {
  992. pCmdUI->SetCheck(m_ToolBarDockSite.IsVisible());
  993. pCmdUI->Enable(true);
  994. }
  995. void CMainFrame::OnSize(UINT nType, int cx, int cy)
  996. {
  997. // Don't call MFC version to size window
  998. // CMDIFrameWnd::OnSize (nType, cx, cy);
  999. if (nType != SIZE_MINIMIZED)
  1000. {
  1001. RenderDockSites();
  1002. MDIIconArrange();
  1003. }
  1004. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  1005. if (pDoc != NULL)
  1006. pDoc->SetFrameModifiedFlag();
  1007. /*
  1008. * If we're moving to or from the minimized state, notify child windows.
  1009. */
  1010. if (m_fCurrentlyMinimized != (nType == SIZE_MINIMIZED))
  1011. {
  1012. m_fCurrentlyMinimized = (nType == SIZE_MINIMIZED);
  1013. SendMinimizeNotifications (m_fCurrentlyMinimized);
  1014. }
  1015. }
  1016. void CMainFrame::OnMove(int x, int y)
  1017. {
  1018. CMDIFrameWnd::OnMove (x, y);
  1019. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  1020. if (pDoc != NULL)
  1021. pDoc->SetFrameModifiedFlag();
  1022. }
  1023. void CMainFrame::RenderDockSites()
  1024. {
  1025. ASSERT_VALID (this);
  1026. CRect clientRect;
  1027. GetClientRect(&clientRect);
  1028. m_DockingManager.BeginLayout();
  1029. m_DockingManager.RenderDockSites(m_hWndMDIClient, clientRect);
  1030. m_DockingManager.EndLayout();
  1031. }
  1032. void CMainFrame::AddMainFrameBars(void)
  1033. {
  1034. /*
  1035. * activate our fusion context so the bars will be themed
  1036. */
  1037. CThemeContextActivator activator;
  1038. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1039. DECLARE_SC(sc, _T("CMainFrame::AddMainFrameBars"));
  1040. sc = ScCheckPointers(m_pRebar);
  1041. if (sc)
  1042. return;
  1043. // insert the menu bar
  1044. ASSERT (m_pMenuBar == NULL);
  1045. m_pMenuBar = new CMenuBar;
  1046. sc = ScCheckPointers(m_pMenuBar);
  1047. if (sc)
  1048. return;
  1049. m_pMenuBar->Create (this, m_pRebar, WS_VISIBLE, ID_MENUBAR);
  1050. m_pMenuBar->SetMenu (GetMenu ());
  1051. m_pMenuBar->Show (TRUE);
  1052. ASSERT(NULL == m_pToolBar);
  1053. m_pToolBar = new CMMCToolBar();
  1054. sc = ScCheckPointers(m_pToolBar);
  1055. if (sc)
  1056. return;
  1057. // Create the toolbar.
  1058. sc = m_pToolBar->ScInit(m_pRebar);
  1059. if (sc)
  1060. return;
  1061. m_pToolBar->Show(TRUE, true /* In new line*/);
  1062. }
  1063. SC CMainFrame::ScCreateNewView (CreateNewViewStruct* pcnvs, bool bEmitScriptEvents /*= true*/)
  1064. {
  1065. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1066. // lock AppEvents until this function is done
  1067. LockComEventInterface(AppEvents);
  1068. DECLARE_SC (sc, _T("CMainFrame::ScCreateNewView"));
  1069. CAMCView* pNewView = NULL; // avoid "initialization skipped by 'goto Error'"
  1070. CAMCDoc* pAMCDoc = CAMCDoc::GetDocument();
  1071. ASSERT(pAMCDoc != NULL);
  1072. if (pAMCDoc == NULL)
  1073. return (sc = E_UNEXPECTED);
  1074. if (pcnvs == NULL)
  1075. return (sc = E_POINTER);
  1076. if ((AMCGetApp()->GetMode() == eMode_User_SDI) && pcnvs->fVisible)
  1077. return (sc = E_FAIL);
  1078. pAMCDoc->SetMTNodeIDForNewView (pcnvs->idRootNode);
  1079. pAMCDoc->SetNewWindowOptions (pcnvs->lWindowOptions);
  1080. pNewView = pAMCDoc->CreateNewView (pcnvs->fVisible, bEmitScriptEvents);
  1081. if (pNewView == NULL)
  1082. {
  1083. pcnvs->pViewData = NULL;
  1084. return (sc = E_FAIL);
  1085. }
  1086. pcnvs->pViewData = pNewView->GetViewData();
  1087. pcnvs->hRootNode = pNewView->GetRootNode();
  1088. return (sc);
  1089. }
  1090. void CMainFrame::OnHelpTopics()
  1091. {
  1092. ScOnHelpTopics();
  1093. }
  1094. SC CMainFrame::ScOnHelpTopics()
  1095. {
  1096. DECLARE_SC(sc, _T("CMainFrame::ScOnHelpTopics"));
  1097. /*
  1098. * if there is a view, route through it so the snap-in gets a crack
  1099. * at the help message (just like Help Topics from the Help menu).
  1100. */
  1101. CConsoleView* pConsoleView = NULL;
  1102. sc = ScGetActiveConsoleView (pConsoleView);
  1103. if (sc)
  1104. return (sc);
  1105. if (pConsoleView != NULL)
  1106. {
  1107. sc = pConsoleView->ScHelpTopics ();
  1108. return sc;
  1109. }
  1110. HH_WINTYPE hhWinType;
  1111. ZeroMemory(&hhWinType, sizeof(hhWinType));
  1112. CAMCApp* pAMCApp = AMCGetApp();
  1113. if (NULL == pAMCApp)
  1114. return (sc = E_UNEXPECTED);
  1115. sc = pAMCApp->ScShowHtmlHelp(SC::GetHelpFile(), 0);
  1116. return sc;
  1117. }
  1118. void CMainFrame::OnViewRefresh()
  1119. {
  1120. // if this doesn't fire before 10/1/99, remove this, OnUpdateViewRefresh, and all references to ID_VIEW_REFRESH (vivekj)
  1121. 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");
  1122. CAMCTreeView* pAMCTreeView = _GetActiveAMCTreeView();
  1123. if (pAMCTreeView)
  1124. pAMCTreeView->ScReselect();
  1125. }
  1126. void CMainFrame::OnUpdateViewRefresh(CCmdUI* pCmdUI)
  1127. {
  1128. // if this doesn't fire before 10/1/99, remove this, OnUpdateView, and all references to ID_VIEW_REFRESH (vivekj)
  1129. 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");
  1130. pCmdUI->Enable(TRUE);
  1131. }
  1132. void CMainFrame::OnDestroy()
  1133. {
  1134. DECLARE_SC(sc, _T("CMainFrame::OnDestroy"));
  1135. // NTRAID#NTBUG9-684811-2002/09/10 - MMC does not send WM_CHANGECBCHAIN message on shutdown if next viewer is NULL.
  1136. // since MMC could be the last window in the chain, it needs to call ChangeClipboardChain even
  1137. // if m_hwndNextCB is null
  1138. if (ChangeClipboardChain(m_hwndNextCB) == FALSE)
  1139. {
  1140. sc.FromLastError();
  1141. sc.TraceAndClear();
  1142. }
  1143. CMDIFrameWnd::OnDestroy();
  1144. }
  1145. void CMainFrame::OnUpdateFrameMenu(HMENU hMenuAlt)
  1146. {
  1147. // let the base class select the right menu
  1148. CMDIFrameWnd::OnUpdateFrameMenu (hMenuAlt);
  1149. // by now, the right menu is on the frame; reflect it to the toolbar
  1150. NotifyMenuChanged ();
  1151. }
  1152. void CMainFrame::NotifyMenuChanged ()
  1153. {
  1154. CMenu* pMenuCurrent = NULL;
  1155. // make sure we don't have menus for MDI or SDI User mode
  1156. switch (AMCGetApp()->GetMode())
  1157. {
  1158. case eMode_Author:
  1159. case eMode_User:
  1160. case eMode_User_MDI:
  1161. case eMode_User_SDI:
  1162. pMenuCurrent = CWnd::GetMenu();
  1163. break;
  1164. default:
  1165. ASSERT (false);
  1166. break;
  1167. }
  1168. m_hMenuCurrent = pMenuCurrent->GetSafeHmenu();
  1169. if (m_pMenuBar != NULL)
  1170. {
  1171. // reflect the new menu on the menu bar
  1172. m_pMenuBar->SetMenu (pMenuCurrent);
  1173. // detach the menu from the frame
  1174. SetMenu (NULL);
  1175. }
  1176. }
  1177. BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
  1178. {
  1179. /*
  1180. * If mainframe is not the active window then do not translate
  1181. * the messages. (See Bug# 119355)
  1182. */
  1183. if (!m_fCurrentlyActive)
  1184. return (FALSE);
  1185. CRebarWnd* pwndRebar = m_pRebar->GetRebar();
  1186. // give the rebar a crack
  1187. if (pwndRebar && pwndRebar->PreTranslateMessage (pMsg))
  1188. return (TRUE);
  1189. // give the menu bar a crack (for menu accelerators)
  1190. if (m_pMenuBar && m_pMenuBar->PreTranslateMessage (pMsg))
  1191. return (TRUE);
  1192. // give the base class a crack
  1193. if ((InRenameMode() == false) &&
  1194. (CMDIFrameWnd::PreTranslateMessage(pMsg)))
  1195. return (TRUE);
  1196. // not translated
  1197. return (FALSE);
  1198. }
  1199. void CMainFrame::OnIdle ()
  1200. {
  1201. if (m_pMenuBar != NULL)
  1202. {
  1203. CMDIChildWnd* pwndActive = MDIGetActive ();
  1204. // The menus are always visible in SDI & MDI modes.
  1205. switch (AMCGetApp()->GetMode())
  1206. {
  1207. case eMode_User_SDI:
  1208. {
  1209. BOOL bMaximized = (pwndActive != NULL) ? pwndActive->IsZoomed () : false;
  1210. ASSERT (bMaximized);
  1211. ASSERT (IsMenuVisible());
  1212. }
  1213. break;
  1214. case eMode_User_MDI:
  1215. ASSERT (pwndActive != NULL);
  1216. ASSERT (IsMenuVisible());
  1217. break;
  1218. }
  1219. ASSERT (m_pMenuBar->GetMenu() != NULL);
  1220. m_pMenuBar->OnIdle ();
  1221. }
  1222. }
  1223. void CMainFrame::ShowMenu (bool fShow)
  1224. {
  1225. CRebarWnd * pwndRebar = m_pRebar->GetRebar();
  1226. pwndRebar->ShowBand (pwndRebar->IdToIndex (ID_MENUBAR), fShow);
  1227. /*---------------------------------------------------------------------*/
  1228. /* if we're showing, the rebar must be showing, too; */
  1229. /* if we're hiding, the rebar should be hidden if no bands are visible */
  1230. /*---------------------------------------------------------------------*/
  1231. if ( fShow && !m_pRebar->IsVisible())
  1232. {
  1233. m_pRebar->Show (fShow);
  1234. RenderDockSites ();
  1235. }
  1236. }
  1237. static bool IsRebarBandVisible (CRebarWnd* pwndRebar, int nBandID)
  1238. {
  1239. REBARBANDINFO rbbi;
  1240. ZeroMemory (&rbbi, sizeof (rbbi));
  1241. rbbi.cbSize = sizeof (rbbi);
  1242. rbbi.fMask = RBBIM_STYLE;
  1243. pwndRebar->GetBandInfo (pwndRebar->IdToIndex (nBandID), &rbbi);
  1244. return ((rbbi.fStyle & RBBS_HIDDEN) == 0);
  1245. }
  1246. bool CMainFrame::IsMenuVisible ()
  1247. {
  1248. return (IsRebarBandVisible (m_pRebar->GetRebar(), ID_MENUBAR));
  1249. }
  1250. /////////////////////////////////////////////////////////////////////////////
  1251. // Special UI processing depending on current active child
  1252. CString CMainFrame::GetFrameTitle()
  1253. {
  1254. /*
  1255. * If there's no active child window, then the document
  1256. * is being closed. Just use the default title.
  1257. */
  1258. if (MDIGetActive() != NULL)
  1259. {
  1260. CAMCDoc* pDocument = CAMCDoc::GetDocument();
  1261. /*
  1262. * If there's a document, use its title.
  1263. */
  1264. if (pDocument != NULL)
  1265. return (pDocument->GetCustomTitle());
  1266. }
  1267. return (m_strGenericTitle);
  1268. }
  1269. void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
  1270. {
  1271. AfxSetWindowText(m_hWnd, GetFrameTitle());
  1272. }
  1273. BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
  1274. {
  1275. if (!CMDIFrameWnd::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
  1276. return (FALSE);
  1277. // save the title we'll use for the main frame if there's no console open
  1278. m_strGenericTitle = m_strTitle;
  1279. return (TRUE);
  1280. }
  1281. void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
  1282. {
  1283. switch (nID)
  1284. {
  1285. case ID_HELP_HELPTOPICS:
  1286. OnHelpTopics ();
  1287. break;
  1288. case ID_CUSTOMIZE_VIEW:
  1289. {
  1290. CChildFrame* pwndActive = dynamic_cast<CChildFrame*>(MDIGetActive ());
  1291. if (pwndActive != NULL)
  1292. pwndActive->OnSysCommand (nID, lParam);
  1293. else
  1294. CMDIFrameWnd::OnSysCommand(nID, lParam);
  1295. break;
  1296. }
  1297. default:
  1298. CMDIFrameWnd::OnSysCommand(nID, lParam);
  1299. break;
  1300. }
  1301. }
  1302. void CMainFrame::UpdateChildSystemMenus ()
  1303. {
  1304. ProgramMode eMode = AMCGetApp()->GetMode();
  1305. // make necessary modifications to existing windows' system menus
  1306. for (CWnd* pwndT = MDIGetActive();
  1307. pwndT != NULL;
  1308. pwndT = pwndT->GetWindow (GW_HWNDNEXT))
  1309. {
  1310. CMenu* pSysMenu = pwndT->GetSystemMenu (FALSE);
  1311. if (pSysMenu != NULL)
  1312. {
  1313. // if not in author mode, protect author mode windows from
  1314. // user close
  1315. if (eMode != eMode_Author)
  1316. {
  1317. // Get AMCView object for this frame
  1318. CChildFrame *pChildFrm = dynamic_cast<CChildFrame*>(pwndT);
  1319. ASSERT(pChildFrm != NULL);
  1320. CAMCView* pView = pChildFrm->GetAMCView();
  1321. ASSERT(pView != NULL);
  1322. // if it's an author mode view, don't let user close it
  1323. if (pView && pView->IsAuthorModeView())
  1324. pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
  1325. }
  1326. // if we're not in SDI User mode, append common stuff
  1327. if (eMode != eMode_User_SDI)
  1328. AppendToSystemMenu (pwndT, eMode);
  1329. }
  1330. }
  1331. }
  1332. void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
  1333. {
  1334. CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
  1335. if (bSysMenu)
  1336. {
  1337. int nEnable = MF_GRAYED;
  1338. CChildFrame* pwndActive = dynamic_cast<CChildFrame*>(MDIGetActive ());
  1339. // if there's an active child, let it handle system menu validation
  1340. if ((pwndActive != NULL) && (pwndActive->IsCustomizeViewEnabled()))
  1341. nEnable = MF_ENABLED;
  1342. pPopupMenu->EnableMenuItem (ID_CUSTOMIZE_VIEW, MF_BYCOMMAND | nEnable);
  1343. }
  1344. else
  1345. {
  1346. // Check if Help menu by testing for "Help Topics" item
  1347. if (pPopupMenu->GetMenuState(ID_HELP_HELPTOPICS, MF_BYCOMMAND) != UINT(-1))
  1348. {
  1349. // View will update item
  1350. CAMCView* pView = GetActiveAMCView();
  1351. if (pView != NULL)
  1352. {
  1353. pView->UpdateSnapInHelpMenus(pPopupMenu);
  1354. }
  1355. }
  1356. }
  1357. }
  1358. LRESULT CMainFrame::OnShowSnapinHelpTopic (WPARAM wParam, LPARAM lParam)
  1359. {
  1360. DECLARE_SC (sc, _T("CMainFrame::OnShowSnapinHelpTopic"));
  1361. CConsoleView* pConsoleView;
  1362. sc = ScGetActiveConsoleView (pConsoleView);
  1363. if (sc)
  1364. return (sc.ToHr());
  1365. /*
  1366. * ScGetActiveConsoleView will return success (S_FALSE) even if there's no
  1367. * active view. This is a valid case, occuring when there's no console
  1368. * file open. In this particular circumstance, it is an unexpected
  1369. * failure since we shouldn't get to this point in the code if there's
  1370. * no view.
  1371. */
  1372. sc = ScCheckPointers (pConsoleView, E_UNEXPECTED);
  1373. if (sc)
  1374. return (sc.ToHr());
  1375. // forward this on the the active AMC view window
  1376. USES_CONVERSION;
  1377. sc = pConsoleView->ScShowSnapinHelpTopic (W2T (reinterpret_cast<LPOLESTR>(lParam)));
  1378. return (sc.ToHr());
  1379. }
  1380. SC CMainFrame::ScGetMenuAccelerators (LPTSTR pBuffer, int cchBuffer)
  1381. {
  1382. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1383. if ((m_pMenuBar != NULL) && IsMenuVisible())
  1384. m_pMenuBar->GetAccelerators (cchBuffer, pBuffer);
  1385. else if (cchBuffer > 0)
  1386. pBuffer[0] = 0;
  1387. return (S_OK);
  1388. }
  1389. //+-------------------------------------------------------------------
  1390. //
  1391. // Member: CMainFrame::ScShowMMCMenus
  1392. //
  1393. // Synopsis: Show or hide MMC menus. (Action/View/Favs)
  1394. //
  1395. // Arguments: bShow
  1396. //
  1397. // Returns: SC
  1398. //
  1399. //--------------------------------------------------------------------
  1400. SC CMainFrame::ScShowMMCMenus (bool bShow)
  1401. {
  1402. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1403. DECLARE_SC(sc, _T("CMainFrame::ScShowMMCMenus"));
  1404. if ((m_pMenuBar != NULL) && IsMenuVisible())
  1405. sc = m_pMenuBar->ScShowMMCMenus(bShow);
  1406. else
  1407. return (sc = E_UNEXPECTED);
  1408. return (sc);
  1409. }
  1410. //////////////////////////////////////////////////////////////////////////////
  1411. // This message is received from the node manager whenever a property
  1412. // sheet use the MMCPropertyChangeNotify() api.
  1413. // The wParam contains a copy of the handle information which must be freed.
  1414. //
  1415. LRESULT CMainFrame::OnPropertySheetNotify(WPARAM wParam, LPARAM lParam)
  1416. {
  1417. TRACE_METHOD(CAMCView, OnPropertySheetNotify);
  1418. ASSERT(wParam != 0);
  1419. LPPROPERTYNOTIFYINFO pNotify = reinterpret_cast<LPPROPERTYNOTIFYINFO>(wParam);
  1420. // Crack the information from the handle object and send a notify to the snap-in
  1421. ASSERT((pNotify->pComponent != NULL || pNotify->pComponentData != NULL));
  1422. if (pNotify->pComponent != NULL)
  1423. pNotify->pComponent->Notify(NULL, MMCN_PROPERTY_CHANGE, pNotify->fScopePane, lParam);
  1424. else if (pNotify->pComponentData != NULL)
  1425. pNotify->pComponentData->Notify(NULL, MMCN_PROPERTY_CHANGE, pNotify->fScopePane, lParam);
  1426. ::GlobalFree(pNotify);
  1427. return TRUE;
  1428. }
  1429. LRESULT CMainFrame::OnSetText (WPARAM wParam, LPARAM lParam)
  1430. {
  1431. LRESULT rc;
  1432. CAMCDoc* pDoc = CAMCDoc::GetDocument();
  1433. /*
  1434. * If the document has a custom title, we don't want to append
  1435. * the maxed child's title to the main frame's title. To do this,
  1436. * we'll bypass DefFrameProc and go directly to DefWindowProc.
  1437. */
  1438. if ((pDoc != NULL) && pDoc->HasCustomTitle())
  1439. rc = CWnd::DefWindowProc (WM_SETTEXT, wParam, lParam);
  1440. else
  1441. rc = Default();
  1442. DrawFrameCaption (this, m_fCurrentlyActive);
  1443. return (rc);
  1444. }
  1445. void CMainFrame::OnPaletteChanged( CWnd* pwndFocus)
  1446. {
  1447. if (pwndFocus != this)
  1448. {
  1449. CAMCDoc* pAMCDoc = CAMCDoc::GetDocument();
  1450. if (pAMCDoc)
  1451. {
  1452. HWND hwndFocus = pwndFocus->GetSafeHwnd();
  1453. CAMCViewPosition pos = pAMCDoc->GetFirstAMCViewPosition();
  1454. while (pos != NULL)
  1455. {
  1456. CAMCView* pv = pAMCDoc->GetNextAMCView(pos);
  1457. if (pv)
  1458. pv->SendMessage(WM_PALETTECHANGED, (WPARAM)hwndFocus);
  1459. }
  1460. }
  1461. }
  1462. CMDIFrameWnd::OnPaletteChanged(pwndFocus);
  1463. }
  1464. BOOL CMainFrame::OnQueryNewPalette()
  1465. {
  1466. CAMCView* pAMCView = GetActiveAMCView();
  1467. if (pAMCView != NULL)
  1468. return pAMCView->SendMessage(WM_QUERYNEWPALETTE);
  1469. return CMDIFrameWnd::OnQueryNewPalette();
  1470. }
  1471. void CMainFrame::OnConsoleProperties()
  1472. {
  1473. CConsolePropSheet().DoModal();
  1474. }
  1475. void CMainFrame::SetIconEx (HICON hIcon, BOOL fBig)
  1476. {
  1477. if (hIcon == NULL)
  1478. hIcon = GetDefaultIcon();
  1479. SetIcon (hIcon, fBig);
  1480. /*
  1481. * make sure the child icon on the menu bar gets updated
  1482. */
  1483. ASSERT (m_pMenuBar != NULL);
  1484. m_pMenuBar->InvalidateMaxedChildIcon();
  1485. }
  1486. /*+-------------------------------------------------------------------------*
  1487. * CMainFrame::GetDefaultIcon
  1488. *
  1489. *
  1490. *--------------------------------------------------------------------------*/
  1491. HICON CMainFrame::GetDefaultIcon () const
  1492. {
  1493. return (AfxGetApp()->LoadIcon (IDR_MAINFRAME));
  1494. }
  1495. /*+-------------------------------------------------------------------------*
  1496. * CMainFrame::SendMinimizeNotifications
  1497. *
  1498. * Causes each CChildFrame to send NCLBK_MINIMIZED.
  1499. *--------------------------------------------------------------------------*/
  1500. void CMainFrame::SendMinimizeNotifications (bool fMinimized) const
  1501. {
  1502. CWnd* pwndMDIChild;
  1503. for (pwndMDIChild = m_wndMDIClient.GetWindow (GW_CHILD);
  1504. pwndMDIChild != NULL;
  1505. pwndMDIChild = pwndMDIChild->GetWindow (GW_HWNDNEXT))
  1506. {
  1507. // There used to be an ASSERT_ISKINDOF. However, that had to change to an if
  1508. // since the active background denies that assumption. See bug 428906.
  1509. if(pwndMDIChild->IsKindOf(RUNTIME_CLASS(CChildFrame)))
  1510. (static_cast<CChildFrame*>(pwndMDIChild))->SendMinimizeNotification (fMinimized);
  1511. }
  1512. }
  1513. /*+-------------------------------------------------------------------------*
  1514. * CMainFrame::OnNcActivate
  1515. *
  1516. * WM_NCACTIVATE handler for CMainFrame.
  1517. *--------------------------------------------------------------------------*/
  1518. BOOL CMainFrame::OnNcActivate(BOOL bActive)
  1519. {
  1520. BOOL rc = CMDIFrameWnd::OnNcActivate(bActive);
  1521. DrawFrameCaption (this, m_fCurrentlyActive);
  1522. return (rc);
  1523. }
  1524. /*+-------------------------------------------------------------------------*
  1525. * CMainFrame::OnNcPaint
  1526. *
  1527. * WM_NCPAINT handler for CMainFrame.
  1528. *--------------------------------------------------------------------------*/
  1529. void CMainFrame::OnNcPaint()
  1530. {
  1531. Default();
  1532. DrawFrameCaption (this, m_fCurrentlyActive);
  1533. }
  1534. /*+-------------------------------------------------------------------------*
  1535. * MsgForwardingEnumProc
  1536. *
  1537. *
  1538. *--------------------------------------------------------------------------*/
  1539. static BOOL CALLBACK MsgForwardingEnumProc (HWND hwnd, LPARAM lParam)
  1540. {
  1541. /*
  1542. * if this isn't an MFC window, forward the message
  1543. */
  1544. if (CWnd::FromHandlePermanent(hwnd) == NULL)
  1545. {
  1546. const MSG* pMsg = (const MSG*) lParam;
  1547. SendMessage (hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
  1548. }
  1549. /*
  1550. * continue enumeration
  1551. */
  1552. return (true);
  1553. }
  1554. /*+-------------------------------------------------------------------------*
  1555. * CMainFrame::OnSettingChange
  1556. *
  1557. * WM_SETTINGCHANGE handler for CMainFrame.
  1558. *--------------------------------------------------------------------------*/
  1559. void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  1560. {
  1561. CMDIFrameWnd::OnSettingChange(uFlags, lpszSection);
  1562. /*
  1563. * MFC will send WM_SETTINGCHANGEs to all descendent MFC windows.
  1564. * There are some non-MFC windows owned by nodemgr that we also want
  1565. * to get this message. We'll send these manually.
  1566. */
  1567. const MSG* pMsg = GetCurrentMessage();
  1568. EnumChildWindows (m_hWnd, MsgForwardingEnumProc, (LPARAM) pMsg);
  1569. /*
  1570. * If we're in SDI mode, then there can be some redrawing problems
  1571. * around the caption if the caption height changes significantly.
  1572. * (This is a USER MDI bug.) We can work around it by manually
  1573. * placing the maximized child window within the MDI client.
  1574. *
  1575. * Note that restoring and re-maximizing the active child window
  1576. * will put the window in the right place, it has the side effect
  1577. * of undesired window flicker (see 375430, et al) as well as
  1578. * a bunch of annoying sound effects if you have sounds associated
  1579. * with the "Restore Down" and/or "Maximize" sound events.
  1580. */
  1581. if (AMCGetApp()->GetMode() == eMode_User_SDI)
  1582. {
  1583. CMDIChildWnd* pwndActive = MDIGetActive();
  1584. if (pwndActive)
  1585. {
  1586. /*
  1587. * get the size of the MDI client
  1588. */
  1589. CRect rect;
  1590. m_wndMDIClient.GetClientRect (rect);
  1591. /*
  1592. * inflate the MDI client's client rect by the size of sizing
  1593. * borders, and add room for the caption at the top
  1594. */
  1595. rect.InflateRect (GetSystemMetrics (SM_CXFRAME),
  1596. GetSystemMetrics (SM_CYFRAME));
  1597. rect.top -= GetSystemMetrics (SM_CYCAPTION);
  1598. /*
  1599. * put the window in the right place
  1600. */
  1601. pwndActive->MoveWindow (rect);
  1602. }
  1603. }
  1604. }
  1605. /*+-------------------------------------------------------------------------*
  1606. * CMainFrame::ScGetActiveStatusBar
  1607. *
  1608. * Returns the CConsoleStatusBar interface for the active view. If there's no
  1609. * active view, pStatusBar is set to NULL and S_FALSE is returned.
  1610. *--------------------------------------------------------------------------*/
  1611. SC CMainFrame::ScGetActiveStatusBar (
  1612. CConsoleStatusBar*& pStatusBar) /* O:CConsoleStatusBar for active view*/
  1613. {
  1614. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1615. DECLARE_SC (sc, _T("CMainFrame::ScGetActiveStatusBar"));
  1616. pStatusBar = dynamic_cast<CConsoleStatusBar*>(GetActiveFrame());
  1617. if (pStatusBar == NULL)
  1618. sc = S_FALSE;
  1619. return (sc);
  1620. }
  1621. /*+-------------------------------------------------------------------------*
  1622. * CMainFrame::ScGetActiveConsoleView
  1623. *
  1624. * Returns the CConsoleView interface for the active view. If there's no
  1625. * active view, pConsoleView is set to NULL and S_FALSE is returned.
  1626. *--------------------------------------------------------------------------*/
  1627. SC CMainFrame::ScGetActiveConsoleView (
  1628. CConsoleView*& pConsoleView) /* O:CConsoleView for active view */
  1629. {
  1630. AFX_MANAGE_STATE (AfxGetAppModuleState());
  1631. DECLARE_SC (sc, _T("CMainFrame::ScGetActiveConsoleView"));
  1632. pConsoleView = GetActiveAMCView();
  1633. if (pConsoleView == NULL)
  1634. sc = S_FALSE;
  1635. return (sc);
  1636. }
  1637. /***************************************************************************\
  1638. *
  1639. * METHOD: CMainFrame::OnUnInitMenuPopup
  1640. *
  1641. * PURPOSE: Used to remove accelerators once system menus are dismissed
  1642. *
  1643. * PARAMETERS:
  1644. * WPARAM wParam
  1645. * LPARAM lParam
  1646. *
  1647. * RETURNS:
  1648. * LRESULT - result code
  1649. *
  1650. \***************************************************************************/
  1651. afx_msg LRESULT CMainFrame::OnUnInitMenuPopup(WPARAM wParam, LPARAM lParam)
  1652. {
  1653. // hide accelerators whenever leaving system popup
  1654. if ( HIWORD(lParam) & MF_SYSMENU )
  1655. {
  1656. SendMessage( WM_CHANGEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEACCEL | UISF_HIDEFOCUS));
  1657. }
  1658. return 0;
  1659. }