//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1999 // // File: mainfrm.cpp // // Contents: Main frame for amc // // History: 01-Jan-96 TRomano Created // 16-Jul-96 WayneSc Add code to test switching views // //-------------------------------------------------------------------------- #include "stdafx.h" #include "AMCDoc.h" #include "AMCView.h" #include "AMC.h" #include "MainFrm.h" #include "ChildFrm.h" #include "treectrl.h" #include "menubar.h" #include "mdiuisim.h" #include "toolbar.h" #include "props.h" #include "sysmenu.h" #include "amcmsgid.h" #include "HtmlHelp.h" #include "strings.h" #include "ndmgrp.h" #include "amcmsgid.h" #include "tbtrack.h" #include "caption.h" #include "scriptevents.h" #ifdef DBG CTraceTag tagMainFrame(TEXT("CMainFrame"), TEXT("Messages")); #endif //############################################################################ //############################################################################ // // Implementation of class CMMCApplicationFrame // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * class CMMCApplicationFrame * * * PURPOSE: The COM 0bject that exposes the Frame interface off the Application object. * *+-------------------------------------------------------------------------*/ class CMMCApplicationFrame : public CMMCIDispatchImpl, public CTiedComObject { typedef CMainFrame CMyTiedObject; public: BEGIN_MMC_COM_MAP(CMMCApplicationFrame) END_MMC_COM_MAP() //Frame interface public: STDMETHOD(Maximize)(); STDMETHOD(Minimize)(); STDMETHOD(Restore)(); STDMETHOD(get_Left)(int *pLeft) {return GetCoordinate(pLeft, eLeft);} STDMETHOD(put_Left)(int left) {return PutCoordinate(left, eLeft);} STDMETHOD(get_Right)(int *pRight) {return GetCoordinate(pRight, eRight);} STDMETHOD(put_Right)(int right) {return PutCoordinate(right, eRight);} STDMETHOD(get_Top)(int *pTop) {return GetCoordinate(pTop, eTop);} STDMETHOD(put_Top)(int top) {return PutCoordinate(top, eTop);} STDMETHOD(get_Bottom)(int *pBottom) {return GetCoordinate(pBottom, eBottom);} STDMETHOD(put_Bottom)(int bottom) {return PutCoordinate(bottom, eBottom);} private: enum eCoordinate { eLeft, eRight, eTop, eBottom }; STDMETHOD(GetCoordinate)(int *pCoordinate, eCoordinate e); STDMETHOD(PutCoordinate)(int coordinate, eCoordinate e); }; /*+-------------------------------------------------------------------------* * * CMMCApplicationFrame::Maximize * * PURPOSE: * * RETURNS: * HRESULT * *+-------------------------------------------------------------------------*/ HRESULT CMMCApplicationFrame::Maximize() { DECLARE_SC(sc, TEXT("CMMCApplicationFrame::Maximize")); CMyTiedObject *pTiedObj = NULL; sc = ScGetTiedObject(pTiedObj); if(sc) return sc.ToHr(); // do the operation sc = pTiedObj->ScMaximize(); return sc.ToHr(); } /*+-------------------------------------------------------------------------* * * CMMCApplicationFrame::Minimize * * PURPOSE: * * RETURNS: * HRESULT * *+-------------------------------------------------------------------------*/ HRESULT CMMCApplicationFrame::Minimize() { DECLARE_SC(sc, TEXT("CMMCApplicationFrame::Minimize")); CMyTiedObject *pTiedObj = NULL; sc = ScGetTiedObject(pTiedObj); if(sc) return sc.ToHr(); // do the operation sc = pTiedObj->ScMinimize(); return sc.ToHr(); } /*+-------------------------------------------------------------------------* * * CMMCApplicationFrame::Restore * * PURPOSE: * * RETURNS: * HRESULT * *+-------------------------------------------------------------------------*/ HRESULT CMMCApplicationFrame::Restore() { DECLARE_SC(sc, TEXT("CMMCApplicationFrame::Restore")); CMyTiedObject *pTiedObj = NULL; sc = ScGetTiedObject(pTiedObj); if(sc) return sc.ToHr(); sc = pTiedObj->ScRestore(); return sc.ToHr(); } /*+-------------------------------------------------------------------------* * * CMMCApplicationFrame::GetCoordinate * * PURPOSE: * * PARAMETERS: * int * pCoordinate : * eCoordinate e : * * RETURNS: * HRESULT * *+-------------------------------------------------------------------------*/ HRESULT CMMCApplicationFrame::GetCoordinate(int *pCoordinate, eCoordinate e) { DECLARE_SC(sc, TEXT("CMMCApplicationFrame::GetCoordinate")); // check parameters if(!pCoordinate) { sc = E_POINTER; return sc.ToHr(); } CMyTiedObject *pTiedObj = NULL; sc = ScGetTiedObject(pTiedObj); if(sc) return sc.ToHr(); RECT rect; // do the operation sc = pTiedObj->ScGetPosition(rect); if(sc) return sc.ToHr(); switch(e) { case eTop: *pCoordinate = rect.top; break; case eBottom: *pCoordinate = rect.bottom; break; case eLeft: *pCoordinate = rect.left; break; case eRight: *pCoordinate = rect.right; break; default: ASSERT(0 && "Should not come here!!"); break; } return sc.ToHr(); } /*+-------------------------------------------------------------------------* * * CMMCApplicationFrame::PutCoordinate * * PURPOSE: * * PARAMETERS: * int coordinate : * eCoordinate e : * * RETURNS: * HRESULT * *+-------------------------------------------------------------------------*/ HRESULT CMMCApplicationFrame::PutCoordinate(int coordinate, eCoordinate e) { DECLARE_SC(sc, TEXT("CMMCApplicationFrame::PutCoordinate")); CMyTiedObject *pTiedObj = NULL; sc = ScGetTiedObject(pTiedObj); if(sc) return sc.ToHr(); RECT rect; sc = pTiedObj->ScGetPosition(rect); if(sc) return sc.ToHr(); switch(e) { case eTop: rect.top = coordinate; break; case eBottom: rect.bottom = coordinate; break; case eLeft: rect.left = coordinate; break; case eRight: rect.right = coordinate; break; default: ASSERT(0 && "Should not come here!!"); break; } sc = pTiedObj->ScSetPosition(rect); return sc.ToHr(); } //############################################################################ //############################################################################ // // Misc declarations // //############################################################################ //############################################################################ static TBBUTTON MainButtons[] = { { 0, ID_FILE_NEW , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 0 }, { 1, ID_FILE_OPEN , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 1 }, { 2, ID_FILE_SAVE , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 2 }, { 0, 0 , TBSTATE_ENABLED, TBSTYLE_SEP , {0,0}, 0L, 0 }, { 3, ID_WINDOW_NEW , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, 3 }, }; /* * remove the definition that WTL might have given us */ #ifdef ID_VIEW_REFRESH #undef ID_VIEW_REFRESH #endif enum DoWeNeedThis { ID_VIEW_REFRESH = 12797 }; //############################################################################ //############################################################################ // // Implementation of class CMainFrame // //############################################################################ //############################################################################ IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd) // CODEWORK message reflection not working yet BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_DRAWCLIPBOARD() ON_WM_CHANGECBCHAIN() ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateFilePrint) ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_SETUP, OnUpdateFilePrintSetup) ON_WM_CLOSE() ON_COMMAND(ID_VIEW_TOOLBAR, OnViewToolbar) ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateViewToolbar) ON_WM_SIZE() ON_COMMAND(ID_HELP_HELPTOPICS, OnHelpTopics) ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh) ON_UPDATE_COMMAND_UI(ID_VIEW_REFRESH, OnUpdateViewRefresh) ON_WM_DESTROY() ON_WM_SYSCOMMAND() ON_WM_INITMENUPOPUP() ON_COMMAND(ID_CONSOLE_PROPERTIES, OnConsoleProperties) ON_WM_MOVE() ON_WM_ACTIVATE() ON_WM_NCACTIVATE() ON_WM_NCPAINT() ON_WM_PALETTECHANGED() ON_WM_QUERYNEWPALETTE() ON_COMMAND(ID_WINDOW_NEW, OnWindowNew) ON_WM_SETTINGCHANGE() ON_WM_MENUSELECT() ON_MESSAGE(WM_UNINITMENUPOPUP, OnUnInitMenuPopup) //}}AFX_MSG_MAP #ifdef DBG ON_COMMAND(ID_MMC_TRACE_DIALOG, OnMMCTraceDialog) #endif ON_MESSAGE(WM_SETTEXT, OnSetText) ON_MESSAGE(MMC_MSG_PROP_SHEET_NOTIFY, OnPropertySheetNotify) ON_MESSAGE(MMC_MSG_SHOW_SNAPIN_HELP_TOPIC, OnShowSnapinHelpTopic) // The following entry is placed here for compatibilty with versions // of mmc.lib that were compiled with the incorrect value for message // MMC_MSG_SHOW_SNAPIN_HELP_TOPIC. MMC.lib function MMCPropertyHelp // sends this message to the mainframe window when called by a snap-in. ON_MESSAGE(MMC_MSG_SHOW_SNAPIN_HELP_TOPIC_ALT, OnShowSnapinHelpTopic) END_MESSAGE_MAP() //+------------------------------------------------------------------- // // Member: CMainFrame::OnMenuSelect // // Synopsis: Handles WM_MENUSELECT, sets status bar text for the // given menu item. // // Arguments: [nItemID] - the resource id of menu item. // [nFlags] - MF_* flags // [hMenu] - // // Returns: none // //-------------------------------------------------------------------- void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hMenu) { DECLARE_SC(sc, TEXT("CMainFrame::OnMenuSelect")); if (nFlags & MF_SYSMENU) return; CString strText = TEXT(""); CString strStatusText; /* * We need to handle special cases, most of the menu items have status text with them. * The exception being, the favoties list, the windows list in windows menu and popup menus. * The reason is the menu ids are not unique in main menu because we do TrackPopupMenu at * three places first one for File, Window & Help menus done in menubar.cpp, second for * Action & View menu in cmenu.cpp and third favorites menu in favui.cpp. */ /* * Special case 1: Check to see if current menu is favorites menu, if so need to get status * text for favorites list except for "Add to favorites.." and "Organize favorites.." items. * The below test can break if "Add to Favorites..." is moved in menu resource. */ if ((IDS_ADD_TO_FAVORITES != nItemID) && (IDS_ORGANIZEFAVORITES != nItemID) && (GetMenuItemID(hMenu, 0) == IDS_ADD_TO_FAVORITES) ) { strStatusText.LoadString(IDS_FAVORITES_ACTIVATE); } /* * Special case 2: Handle any popup menus (popup menus dont have any ID). */ else if (nFlags & MF_POPUP) { // do nothing } // Special case 3: Assume mmc supports maximum of 1024 windows for status bar text sake. else if ( (nItemID >= AFX_IDM_FIRST_MDICHILD) && (nItemID <= AFX_IDM_FIRST_MDICHILD+1024) ) { strStatusText.LoadString(ID_WINDOW_ACTIVATEWINDOW); } else { strText.LoadString(nItemID); int iSeparator = strText.Find(_T('\n')); if (iSeparator < 0) // No status text so use the menu text as status text. strStatusText = strText; else strStatusText = strText.Mid(iSeparator); } CChildFrame *pChildFrame = dynamic_cast(GetActiveFrame()); if (!pChildFrame) return; sc = pChildFrame->ScSetStatusText(strStatusText); if (sc) return; return; } /*+-------------------------------------------------------------------------* * * CMainFrame::ScGetFrame * * PURPOSE: Returns a pointer to the COM object that implements the * Frame interface. * * PARAMETERS: * Frame **ppFrame : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CMainFrame::ScGetFrame(Frame **ppFrame) { DECLARE_SC(sc, TEXT("CMainFrame::ScGetFrame") ); if(!ppFrame) { sc = E_POINTER; return sc; } *ppFrame = NULL; // NOTE the com object cannot be cached with a smart pointer owned by CMainFrame // since CMainFrame is VERY LONG living guy - it will lock mmc.exe from exitting // it could be used by creating CComObjectCached, but CTiedComObjectCreator does // not support that // see bug # 101564 CComPtr spFrame; // create a CMMCApplicationFrame if not already done so. sc = CTiedComObjectCreator::ScCreateAndConnect(*this, spFrame); if(sc) return sc; if(spFrame == NULL) { sc = E_UNEXPECTED; return sc; } *ppFrame = spFrame.Detach(); return sc; } /*+-------------------------------------------------------------------------* * * CMainFrame::ScMaximize * * PURPOSE: * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CMainFrame::ScMaximize() { DECLARE_SC(sc, TEXT("CMainFrame::ScMaximize")); ShowWindow(SW_MAXIMIZE); return sc; } /*+-------------------------------------------------------------------------* * * CMainFrame::ScMinimize * * PURPOSE: * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CMainFrame::ScMinimize() { DECLARE_SC(sc, TEXT("CMainFrame::ScMinimize")); ShowWindow(SW_MINIMIZE); return sc; } /*+-------------------------------------------------------------------------* * * CMainFrame::ScRestore * * PURPOSE: Restores the position of the main frame. * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CMainFrame::ScRestore() { DECLARE_SC(sc, TEXT("CMainFrame::ScRestore")); ShowWindow(SW_RESTORE); return sc; } /*+-------------------------------------------------------------------------* * * CMainFrame::ScSetPosition * * PURPOSE: Sets the position of the main frame * * PARAMETERS: * const RECT : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CMainFrame::ScSetPosition(const RECT &rect) { DECLARE_SC(sc, TEXT("CMainFrame::ScSetPosition")); int width = rect.right - rect.left + 1; int height = rect.bottom - rect.top + 1; SetWindowPos(NULL /*hWndInsertAfter*/, rect.left, rect.top, width, height, SWP_NOZORDER); return sc; } /*+-------------------------------------------------------------------------* * * CMainFrame::ScGetPosition * * PURPOSE: * * PARAMETERS: * RECT & rect : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CMainFrame::ScGetPosition(RECT &rect) { DECLARE_SC(sc, TEXT("CMainFrame::ScGetPosition")); GetWindowRect(&rect); return sc; } // OnActivate is overridden to work around a SQL snap-in problem under // Win9x. When SQL tries to force focus back to its property sheet it // causes an infinite recursion of the OnActivate call. // This override discards any activation that occurs during the processing // of a prior activation. void CMainFrame::OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized ) { Trace(tagMainFrame, TEXT("OnActivate: nState=%d"), nState); static bActivating = FALSE; m_fCurrentlyActive = (nState != WA_INACTIVE); // if activating if (m_fCurrentlyActive) { CAMCApp* pApp = AMCGetApp(); ASSERT(NULL != pApp); // if windows and we're already activating, prevent recursion if ( (NULL != pApp) && (pApp->IsWin9xPlatform() == true) && bActivating) return; // Process activation request bActivating = TRUE; CMDIFrameWnd::OnActivate(nState, pWndOther, bMinimized); bActivating = FALSE; } else { // if we have accelarators hilited (it happen when one press Alt+TAB) // we need to remove them now. SendMessage( WM_CHANGEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEACCEL | UISF_HIDEFOCUS)); // Let unactivate through CMDIFrameWnd::OnActivate(nState, pWndOther, bMinimized); } } CAMCView* CMainFrame::GetActiveAMCView() { CChildFrame *pChildFrame = dynamic_cast(GetActiveFrame()); if (!pChildFrame) return NULL; CAMCView* pAMCView = pChildFrame->GetAMCView(); ASSERT(pAMCView != NULL); ASSERT(::IsWindow(*pAMCView)); if (pAMCView && ::IsWindow(*pAMCView)) return pAMCView; return NULL; } CAMCTreeView* CMainFrame::_GetActiveAMCTreeView() { CAMCView* pAMCView = GetActiveAMCView(); CAMCTreeView* pAMCTreeView = pAMCView ? pAMCView->GetTreeCtrl() : NULL; if (pAMCTreeView && ::IsWindow(*pAMCTreeView)) return pAMCTreeView; return NULL; } void CMainFrame::OnDrawClipboard() { if (m_hwndToNotifyCBChange != NULL && ::IsWindow(m_hwndToNotifyCBChange)) { ::SendMessage(m_hwndToNotifyCBChange, WM_DRAWCLIPBOARD, 0, 0); m_hwndToNotifyCBChange = NULL; } if (m_hwndNextCB != NULL && ::IsWindow(m_hwndNextCB)) { ::SendMessage(m_hwndNextCB, WM_DRAWCLIPBOARD, 0, 0); } CAMCDoc* pAMCDoc = CAMCDoc::GetDocument(); if (pAMCDoc) { CAMCViewPosition pos = pAMCDoc->GetFirstAMCViewPosition(); while (pos != NULL) { CAMCView* v = pAMCDoc->GetNextAMCView(pos); if (v && ::IsWindow(*v)) v->OnUpdatePasteBtn(); } } } void CMainFrame::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter) { if (m_hwndNextCB == hWndRemove) m_hwndNextCB = hWndAfter; else if (m_hwndNextCB != NULL && ::IsWindow(m_hwndNextCB)) ::SendMessage(m_hwndNextCB, WM_CHANGECBCHAIN, (WPARAM)hWndRemove, (LPARAM)hWndAfter); } void CMainFrame::OnWindowNew() { // lock AppEvents until this function is done LockComEventInterface(AppEvents); CAMCDoc* pAMCDoc = CAMCDoc::GetDocument(); ASSERT(pAMCDoc != NULL); if (pAMCDoc != NULL) { pAMCDoc->SetMTNodeIDForNewView(ROOTNODEID); pAMCDoc->CreateNewView(true); } } ///////////////////////////////////////////////////////////////////////////// // CMainFrame construction/destruction CMainFrame::CMainFrame() : m_hwndToNotifyCBChange(NULL), m_hwndNextCB(NULL), m_fCurrentlyMinimized(false), m_fCurrentlyActive(false) { CommonConstruct(); } void CMainFrame::CommonConstruct(void) { m_pRebar = NULL; m_pMenuBar = NULL; m_pToolBar = NULL; m_pMDIChildWndFocused = NULL; m_hMenuCurrent = NULL; m_pToolbarTracker = NULL; SetInRenameMode(false); } CMainFrame::~CMainFrame() { delete m_pMenuBar; delete m_pToolBar; delete m_pRebar; delete m_pToolbarTracker; } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { DECLARE_SC(sc, TEXT("CMainFrame::OnCreate")); if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndMDIClient.SubclassWindow(m_hWndMDIClient)) { ASSERT(0 && "Failed to subclass MDI client window\n"); return -1; } ASSERT(m_wndMDIClient.m_hWnd == m_hWndMDIClient); // create the rebar m_pRebar = new CRebarDockWindow; m_pRebar->Create(this,WS_CHILD|WS_VISIBLE, IDR_REBAR); // Create the toolbar like we just created the stat bar //m_wndToolBar.Create(this, WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, 0x1003); m_ToolBarDockSite.Create(CDockSite::DSS_TOP); m_ToolBarDockSite.Attach(m_pRebar); m_ToolBarDockSite.Show(); m_DockingManager.Attach(&m_ToolBarDockSite); AddMainFrameBars(); m_hwndNextCB = SetClipboardViewer(); if (m_hwndNextCB == NULL) { LRESULT lr = GetLastError(); ASSERT(lr == 0); } // append our modifications to the system menu AppendToSystemMenu (this, eMode_Last + 1); // create the toolbar tracker m_pToolbarTracker = new CToolbarTracker (this); return 0; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { DECLARE_SC(sc, TEXT("CMainFrame::PreCreateWindow")); if (!CMDIFrameWnd::PreCreateWindow(cs)) return (FALSE); static TCHAR szClassName[countof (MAINFRAME_CLASS_NAME)]; static bool fFirstTime = true; if (fFirstTime) { USES_CONVERSION; sc = StringCchCopy(szClassName, countof (MAINFRAME_CLASS_NAME), W2T (MAINFRAME_CLASS_NAME)); if (sc) return FALSE; fFirstTime = false; } WNDCLASS wc; HINSTANCE hInst = AfxGetInstanceHandle(); BOOL fSuccess = GetClassInfo (hInst, szClassName, &wc); // if we haven't already registered... if (!fSuccess && ::GetClassInfo (hInst, cs.lpszClass, &wc)) { // ...register a uniquely-named window class so // MMCPropertyHelp the correct main window wc.lpszClassName = szClassName; wc.hIcon = GetDefaultIcon(); fSuccess = AfxRegisterClass (&wc); } if (fSuccess) { // Use the new child frame window class cs.lpszClass = szClassName; // remove MFC's title-munging styles cs.style &= ~(FWS_ADDTOTITLE | FWS_PREFIXTITLE); } return (fSuccess); } ///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics #ifdef _DEBUG void CMainFrame::AssertValid() const { CMDIFrameWnd::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CMDIFrameWnd::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers // this code is duplicated in ..\nodemgr\propsht.cpp BOOL CALLBACK MyEnumThreadWindProc (HWND current, LPARAM lParam) { // this enumerates non-child-windows created by a given thread if (!IsWindow (current)) return TRUE; // this shouldn't happen, but does!!! if (!IsWindowVisible (current)) // if they've explicitly hidden a window, return TRUE; // don't set focus to it. // we'll return hwnd in here HWND * phwnd = reinterpret_cast(lParam); // don't bother returning property sheet dialog window handle if (*phwnd == current) return TRUE; // also, don't return OleMainThreadWndClass window TCHAR szCaption[14]; if (GetWindowText (current, szCaption, countof(szCaption))) if (!lstrcmp (szCaption, _T("OLEChannelWnd"))) return TRUE; // anything else will do *phwnd = current; return FALSE; } /***************************************************************************\ * * METHOD: FArePropertySheetsOpen * * PURPOSE: Checks if there are propperty sheets open and asks to close them * It is implemented as the following steps: * 1. Collect all property pages (and their children) to the stack * 2. Bring all the pages to the front, maintainig their z-order * 3. Disable all those windows, plus MMC main window to disallow switching to them * untill message box is dissmissed * 4. Put all disabled windows to the stack, to be able to re-enable them * 5. (if there are any sheets) display message box asking to close the sheets * 6. Re-enable disabled windows * * PARAMETERS: * CString* pstrUserMsg - [in] message to display * bool bBringToFrontAndAskToClose [in] if need to proceed whole way. false -> just inspect and do nothing * * RETURNS: * bool - [true == there are windows to close] * \***************************************************************************/ bool FArePropertySheetsOpen(CString* pstrUserMsg, bool bBringToFrontAndAskToClose /* = true */ ) { std::stack > WindowStack; std::stack > EnableWindowStack; ASSERT (WindowStack.empty()); HWND hwndData = NULL; while (TRUE) { USES_CONVERSION; // Note: No need to localize this string hwndData = ::FindWindowEx(NULL, hwndData, W2T(DATAWINDOW_CLASS_NAME), NULL); if (hwndData == NULL) break; // No more windows ASSERT(IsWindow(hwndData)); // Check if the window belongs to the current process DWORD dwPid = 0; // Process Id ::GetWindowThreadProcessId(hwndData, &dwPid); if (dwPid != ::GetCurrentProcessId()) continue; DataWindowData* pData = GetDataWindowData (hwndData); ASSERT (pData != NULL); HWND hwndPropSheet = pData->hDlg; ASSERT (IsWindow (hwndPropSheet)); // don't allow lost data window to block mmc from exiting // windows bug #425049 ntbug9 6/27/2001 if ( !IsWindow (hwndPropSheet) ) continue; // if propsheet has other windows or prop pages up, // then we send focus to them.... // grab first one that isn't property sheet dialog HWND hwndOther = pData->hDlg; EnumThreadWindows (::GetWindowThreadProcessId(pData->hDlg, NULL), MyEnumThreadWindProc, (LPARAM)&hwndOther); // if we got another window for this property sheet, we'll want // it to be on top of the property sheet after the shuffle, so // put it under the property sheet on the stack if (IsWindow (hwndOther) && (hwndOther != hwndPropSheet)) WindowStack.push (hwndOther); // push the property sheet on the stack // of windows to bring to the foreground WindowStack.push (hwndPropSheet); } bool fFoundSheets = !WindowStack.empty(); // we did the investigation, see if we were asked to do more if ( !bBringToFrontAndAskToClose ) return (fFoundSheets); HWND hwndMsgBoxParent = NULL; // if we found property sheets, bring them to the foreground, // maintaining their original Z-order while (!WindowStack.empty()) { HWND hwnd = WindowStack.top(); WindowStack.pop(); SetActiveWindow (hwnd); SetForegroundWindow (hwnd); if ( ::IsWindowEnabled(hwnd) ) { // disable the pages while message box is displayed ::EnableWindow( hwnd, FALSE ); // remember to enable when done EnableWindowStack.push(hwnd); } hwndMsgBoxParent = hwnd; // the last one wins the right to be the parent :-) } if (fFoundSheets && pstrUserMsg) { // parent the message box on the top-most property page to make it obvios to the user CString strCaption; LPCTSTR szCaption = LoadString(strCaption, IDR_MAINFRAME) ? (LPCTSTR)strCaption : NULL; // disable main window as well CWnd *pMainWnd = AfxGetMainWnd(); if ( pMainWnd && pMainWnd->IsWindowEnabled() ) { pMainWnd->EnableWindow( FALSE ); // remember to enable when done EnableWindowStack.push( pMainWnd->m_hWnd ); } ::MessageBox( hwndMsgBoxParent, *pstrUserMsg, szCaption , MB_ICONSTOP | MB_OK ); } // make everything functional again while (!EnableWindowStack.empty()) { // enable the disabled window ::EnableWindow( EnableWindowStack.top(), TRUE ); EnableWindowStack.pop(); } return (fFoundSheets); } bool CanCloseDoc(void) { CString strMessage; CString strConsoleName; AfxGetMainWnd()->GetWindowText (strConsoleName); FormatString1 (strMessage, IDS_ClosePropertyPagesBeforeClosingTheDoc, strConsoleName); bool fPropSheets = FArePropertySheetsOpen(&strMessage); return !fPropSheets; } void CMainFrame::OnClose() { /* * Bug 233682: We need to make sure that we only handle WM_CLOSE when * it's dispatched from our main message pump. If it comes from elsewhere * (like the message pump in a modal dialog or message box), then we're * likely in a state where we can't shut down cleanly. */ CAMCApp* pApp = AMCGetApp(); if (!pApp->DidCloseComeFromMainPump()) { pApp->DelayCloseUntilIdle(); return; } // Reset the flag so that while processing this WM_CLOSE if there is // any more WM_CLOSE messages from other sources it will not be processed. pApp->ResetCloseCameFromMainPump(); if (!CanCloseDoc()) return; // since this process includes event posting // - we should guard the function from reentrance static bool bInProgress = false; if (!bInProgress) { bInProgress = true; CMDIFrameWnd::OnClose(); bInProgress = false; } } void CMainFrame::OnUpdateFilePrint(CCmdUI* pCmdUI) { pCmdUI->Enable(FALSE); } void CMainFrame::OnUpdateFilePrintSetup(CCmdUI* pCmdUI) { pCmdUI->Enable(FALSE); } #ifdef DBG /*+-------------------------------------------------------------------------* * * CMainFrame::OnMMCTraceDialog * * PURPOSE: In Debug mode, shows the Trace dialog, in response to the hotkey. * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CMainFrame::OnMMCTraceDialog() { DoDebugTraceDialog(); } #endif /***************************************************************************\ * * METHOD: ScUpdateAllScopes * * PURPOSE: Just calls CDocument::UpdateAllViews. * If we want to Update all views to delete empty views then * First it gets list of empty views and then it closes them. * * PARAMETERS: * lHint - [in] The action to perform. * lParam - [in] Extra context info. * * RETURNS: * SC * \***************************************************************************/ SC CMainFrame::ScUpdateAllScopes(LONG lHint, LPARAM lParam) { AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC(sc, TEXT("CMainFrame::ScUpdateAllScopes")); // Updating all scopes may be requested as a result of document being deleted // in that case we do not have a document, and thus do not have any views. // So we are done. if (NULL == CAMCDoc::GetDocument()) return sc; // Special case, we cannot destroy the view during CDocument::UpdateAllViews // as CDocument is enumerating the view collection. Nor we can do PostMessage // to close view as scripts in (479627) web pages execute. Therefore we get the // list of empty views and then destroy them. if (lHint == VIEW_UPDATE_DELETE_EMPTY_VIEW) { // Get the list of AMCViews to be deleted. if (lParam != NULL) return (sc = E_UNEXPECTED); CArray rgEmptyAMCViews; CAMCDoc::GetDocument()->UpdateAllViews (NULL, lHint, reinterpret_cast(&rgEmptyAMCViews)); // Now destroy each view. for (int i = 0; i < rgEmptyAMCViews.GetSize(); i++) { CAMCView *pAMCView = rgEmptyAMCViews.GetAt(i); sc = ScCheckPointers(pAMCView); if (sc) { sc.TraceAndClear(); continue; } CChildFrame* pFrame = pAMCView->GetParentFrame(); sc = ScCheckPointers(pFrame); if (sc) { sc.TraceAndClear(); continue; } // Send WM_CLOSE Synchronously else the web page views with scripts in them will // have their scripts executed and may AV. pFrame->SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0); } } else CAMCDoc::GetDocument()->UpdateAllViews (NULL, lHint, reinterpret_cast(lParam)); return (sc); } void CMainFrame::OnViewToolbar() { m_ToolBarDockSite.Toggle(); RenderDockSites(); } void CMainFrame::OnUpdateViewToolbar(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_ToolBarDockSite.IsVisible()); pCmdUI->Enable(true); } void CMainFrame::OnSize(UINT nType, int cx, int cy) { // Don't call MFC version to size window // CMDIFrameWnd::OnSize (nType, cx, cy); if (nType != SIZE_MINIMIZED) { RenderDockSites(); MDIIconArrange(); } CAMCDoc* pDoc = CAMCDoc::GetDocument(); if (pDoc != NULL) pDoc->SetFrameModifiedFlag(); /* * If we're moving to or from the minimized state, notify child windows. */ if (m_fCurrentlyMinimized != (nType == SIZE_MINIMIZED)) { m_fCurrentlyMinimized = (nType == SIZE_MINIMIZED); SendMinimizeNotifications (m_fCurrentlyMinimized); } } void CMainFrame::OnMove(int x, int y) { CMDIFrameWnd::OnMove (x, y); CAMCDoc* pDoc = CAMCDoc::GetDocument(); if (pDoc != NULL) pDoc->SetFrameModifiedFlag(); } void CMainFrame::RenderDockSites() { ASSERT_VALID (this); CRect clientRect; GetClientRect(&clientRect); m_DockingManager.BeginLayout(); m_DockingManager.RenderDockSites(m_hWndMDIClient, clientRect); m_DockingManager.EndLayout(); } void CMainFrame::AddMainFrameBars(void) { /* * activate our fusion context so the bars will be themed */ CThemeContextActivator activator; AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC(sc, _T("CMainFrame::AddMainFrameBars")); sc = ScCheckPointers(m_pRebar); if (sc) return; // insert the menu bar ASSERT (m_pMenuBar == NULL); m_pMenuBar = new CMenuBar; sc = ScCheckPointers(m_pMenuBar); if (sc) return; m_pMenuBar->Create (this, m_pRebar, WS_VISIBLE, ID_MENUBAR); m_pMenuBar->SetMenu (GetMenu ()); m_pMenuBar->Show (TRUE); ASSERT(NULL == m_pToolBar); m_pToolBar = new CMMCToolBar(); sc = ScCheckPointers(m_pToolBar); if (sc) return; // Create the toolbar. sc = m_pToolBar->ScInit(m_pRebar); if (sc) return; m_pToolBar->Show(TRUE, true /* In new line*/); } SC CMainFrame::ScCreateNewView (CreateNewViewStruct* pcnvs, bool bEmitScriptEvents /*= true*/) { AFX_MANAGE_STATE (AfxGetAppModuleState()); // lock AppEvents until this function is done LockComEventInterface(AppEvents); DECLARE_SC (sc, _T("CMainFrame::ScCreateNewView")); CAMCView* pNewView = NULL; // avoid "initialization skipped by 'goto Error'" CAMCDoc* pAMCDoc = CAMCDoc::GetDocument(); ASSERT(pAMCDoc != NULL); if (pAMCDoc == NULL) return (sc = E_UNEXPECTED); if (pcnvs == NULL) return (sc = E_POINTER); if ((AMCGetApp()->GetMode() == eMode_User_SDI) && pcnvs->fVisible) return (sc = E_FAIL); pAMCDoc->SetMTNodeIDForNewView (pcnvs->idRootNode); pAMCDoc->SetNewWindowOptions (pcnvs->lWindowOptions); pNewView = pAMCDoc->CreateNewView (pcnvs->fVisible, bEmitScriptEvents); if (pNewView == NULL) { pcnvs->pViewData = NULL; return (sc = E_FAIL); } pcnvs->pViewData = pNewView->GetViewData(); pcnvs->hRootNode = pNewView->GetRootNode(); return (sc); } void CMainFrame::OnHelpTopics() { ScOnHelpTopics(); } SC CMainFrame::ScOnHelpTopics() { DECLARE_SC(sc, _T("CMainFrame::ScOnHelpTopics")); /* * if there is a view, route through it so the snap-in gets a crack * at the help message (just like Help Topics from the Help menu). */ CConsoleView* pConsoleView = NULL; sc = ScGetActiveConsoleView (pConsoleView); if (sc) return (sc); if (pConsoleView != NULL) { sc = pConsoleView->ScHelpTopics (); return sc; } HH_WINTYPE hhWinType; ZeroMemory(&hhWinType, sizeof(hhWinType)); CAMCApp* pAMCApp = AMCGetApp(); if (NULL == pAMCApp) return (sc = E_UNEXPECTED); sc = pAMCApp->ScShowHtmlHelp(SC::GetHelpFile(), 0); return sc; } void CMainFrame::OnViewRefresh() { // if this doesn't fire before 10/1/99, remove this, OnUpdateViewRefresh, and all references to ID_VIEW_REFRESH (vivekj) 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"); CAMCTreeView* pAMCTreeView = _GetActiveAMCTreeView(); if (pAMCTreeView) pAMCTreeView->ScReselect(); } void CMainFrame::OnUpdateViewRefresh(CCmdUI* pCmdUI) { // if this doesn't fire before 10/1/99, remove this, OnUpdateView, and all references to ID_VIEW_REFRESH (vivekj) 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"); pCmdUI->Enable(TRUE); } void CMainFrame::OnDestroy() { DECLARE_SC(sc, _T("CMainFrame::OnDestroy")); // NTRAID#NTBUG9-684811-2002/09/10 - MMC does not send WM_CHANGECBCHAIN message on shutdown if next viewer is NULL. // since MMC could be the last window in the chain, it needs to call ChangeClipboardChain even // if m_hwndNextCB is null if (ChangeClipboardChain(m_hwndNextCB) == FALSE) { sc.FromLastError(); sc.TraceAndClear(); } CMDIFrameWnd::OnDestroy(); } void CMainFrame::OnUpdateFrameMenu(HMENU hMenuAlt) { // let the base class select the right menu CMDIFrameWnd::OnUpdateFrameMenu (hMenuAlt); // by now, the right menu is on the frame; reflect it to the toolbar NotifyMenuChanged (); } void CMainFrame::NotifyMenuChanged () { CMenu* pMenuCurrent = NULL; // make sure we don't have menus for MDI or SDI User mode switch (AMCGetApp()->GetMode()) { case eMode_Author: case eMode_User: case eMode_User_MDI: case eMode_User_SDI: pMenuCurrent = CWnd::GetMenu(); break; default: ASSERT (false); break; } m_hMenuCurrent = pMenuCurrent->GetSafeHmenu(); if (m_pMenuBar != NULL) { // reflect the new menu on the menu bar m_pMenuBar->SetMenu (pMenuCurrent); // detach the menu from the frame SetMenu (NULL); } } BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) { /* * If mainframe is not the active window then do not translate * the messages. (See Bug# 119355) */ if (!m_fCurrentlyActive) return (FALSE); CRebarWnd* pwndRebar = m_pRebar->GetRebar(); // give the rebar a crack if (pwndRebar && pwndRebar->PreTranslateMessage (pMsg)) return (TRUE); // give the menu bar a crack (for menu accelerators) if (m_pMenuBar && m_pMenuBar->PreTranslateMessage (pMsg)) return (TRUE); // give the base class a crack if ((InRenameMode() == false) && (CMDIFrameWnd::PreTranslateMessage(pMsg))) return (TRUE); // not translated return (FALSE); } void CMainFrame::OnIdle () { if (m_pMenuBar != NULL) { CMDIChildWnd* pwndActive = MDIGetActive (); // The menus are always visible in SDI & MDI modes. switch (AMCGetApp()->GetMode()) { case eMode_User_SDI: { BOOL bMaximized = (pwndActive != NULL) ? pwndActive->IsZoomed () : false; ASSERT (bMaximized); ASSERT (IsMenuVisible()); } break; case eMode_User_MDI: ASSERT (pwndActive != NULL); ASSERT (IsMenuVisible()); break; } ASSERT (m_pMenuBar->GetMenu() != NULL); m_pMenuBar->OnIdle (); } } void CMainFrame::ShowMenu (bool fShow) { CRebarWnd * pwndRebar = m_pRebar->GetRebar(); pwndRebar->ShowBand (pwndRebar->IdToIndex (ID_MENUBAR), fShow); /*---------------------------------------------------------------------*/ /* if we're showing, the rebar must be showing, too; */ /* if we're hiding, the rebar should be hidden if no bands are visible */ /*---------------------------------------------------------------------*/ if ( fShow && !m_pRebar->IsVisible()) { m_pRebar->Show (fShow); RenderDockSites (); } } static bool IsRebarBandVisible (CRebarWnd* pwndRebar, int nBandID) { REBARBANDINFO rbbi; ZeroMemory (&rbbi, sizeof (rbbi)); rbbi.cbSize = sizeof (rbbi); rbbi.fMask = RBBIM_STYLE; pwndRebar->GetBandInfo (pwndRebar->IdToIndex (nBandID), &rbbi); return ((rbbi.fStyle & RBBS_HIDDEN) == 0); } bool CMainFrame::IsMenuVisible () { return (IsRebarBandVisible (m_pRebar->GetRebar(), ID_MENUBAR)); } ///////////////////////////////////////////////////////////////////////////// // Special UI processing depending on current active child CString CMainFrame::GetFrameTitle() { /* * If there's no active child window, then the document * is being closed. Just use the default title. */ if (MDIGetActive() != NULL) { CAMCDoc* pDocument = CAMCDoc::GetDocument(); /* * If there's a document, use its title. */ if (pDocument != NULL) return (pDocument->GetCustomTitle()); } return (m_strGenericTitle); } void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle) { AfxSetWindowText(m_hWnd, GetFrameTitle()); } BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext) { if (!CMDIFrameWnd::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext)) return (FALSE); // save the title we'll use for the main frame if there's no console open m_strGenericTitle = m_strTitle; return (TRUE); } void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) { switch (nID) { case ID_HELP_HELPTOPICS: OnHelpTopics (); break; case ID_CUSTOMIZE_VIEW: { CChildFrame* pwndActive = dynamic_cast(MDIGetActive ()); if (pwndActive != NULL) pwndActive->OnSysCommand (nID, lParam); else CMDIFrameWnd::OnSysCommand(nID, lParam); break; } default: CMDIFrameWnd::OnSysCommand(nID, lParam); break; } } void CMainFrame::UpdateChildSystemMenus () { ProgramMode eMode = AMCGetApp()->GetMode(); // make necessary modifications to existing windows' system menus for (CWnd* pwndT = MDIGetActive(); pwndT != NULL; pwndT = pwndT->GetWindow (GW_HWNDNEXT)) { CMenu* pSysMenu = pwndT->GetSystemMenu (FALSE); if (pSysMenu != NULL) { // if not in author mode, protect author mode windows from // user close if (eMode != eMode_Author) { // Get AMCView object for this frame CChildFrame *pChildFrm = dynamic_cast(pwndT); ASSERT(pChildFrm != NULL); CAMCView* pView = pChildFrm->GetAMCView(); ASSERT(pView != NULL); // if it's an author mode view, don't let user close it if (pView && pView->IsAuthorModeView()) pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); } // if we're not in SDI User mode, append common stuff if (eMode != eMode_User_SDI) AppendToSystemMenu (pwndT, eMode); } } } void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); if (bSysMenu) { int nEnable = MF_GRAYED; CChildFrame* pwndActive = dynamic_cast(MDIGetActive ()); // if there's an active child, let it handle system menu validation if ((pwndActive != NULL) && (pwndActive->IsCustomizeViewEnabled())) nEnable = MF_ENABLED; pPopupMenu->EnableMenuItem (ID_CUSTOMIZE_VIEW, MF_BYCOMMAND | nEnable); } else { // Check if Help menu by testing for "Help Topics" item if (pPopupMenu->GetMenuState(ID_HELP_HELPTOPICS, MF_BYCOMMAND) != UINT(-1)) { // View will update item CAMCView* pView = GetActiveAMCView(); if (pView != NULL) { pView->UpdateSnapInHelpMenus(pPopupMenu); } } } } LRESULT CMainFrame::OnShowSnapinHelpTopic (WPARAM wParam, LPARAM lParam) { DECLARE_SC (sc, _T("CMainFrame::OnShowSnapinHelpTopic")); CConsoleView* pConsoleView; sc = ScGetActiveConsoleView (pConsoleView); if (sc) return (sc.ToHr()); /* * ScGetActiveConsoleView will return success (S_FALSE) even if there's no * active view. This is a valid case, occuring when there's no console * file open. In this particular circumstance, it is an unexpected * failure since we shouldn't get to this point in the code if there's * no view. */ sc = ScCheckPointers (pConsoleView, E_UNEXPECTED); if (sc) return (sc.ToHr()); // forward this on the the active AMC view window USES_CONVERSION; sc = pConsoleView->ScShowSnapinHelpTopic (W2T (reinterpret_cast(lParam))); return (sc.ToHr()); } SC CMainFrame::ScGetMenuAccelerators (LPTSTR pBuffer, int cchBuffer) { AFX_MANAGE_STATE (AfxGetAppModuleState()); if ((m_pMenuBar != NULL) && IsMenuVisible()) m_pMenuBar->GetAccelerators (cchBuffer, pBuffer); else if (cchBuffer > 0) pBuffer[0] = 0; return (S_OK); } //+------------------------------------------------------------------- // // Member: CMainFrame::ScShowMMCMenus // // Synopsis: Show or hide MMC menus. (Action/View/Favs) // // Arguments: bShow // // Returns: SC // //-------------------------------------------------------------------- SC CMainFrame::ScShowMMCMenus (bool bShow) { AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC(sc, _T("CMainFrame::ScShowMMCMenus")); if ((m_pMenuBar != NULL) && IsMenuVisible()) sc = m_pMenuBar->ScShowMMCMenus(bShow); else return (sc = E_UNEXPECTED); return (sc); } ////////////////////////////////////////////////////////////////////////////// // This message is received from the node manager whenever a property // sheet use the MMCPropertyChangeNotify() api. // The wParam contains a copy of the handle information which must be freed. // LRESULT CMainFrame::OnPropertySheetNotify(WPARAM wParam, LPARAM lParam) { TRACE_METHOD(CAMCView, OnPropertySheetNotify); ASSERT(wParam != 0); LPPROPERTYNOTIFYINFO pNotify = reinterpret_cast(wParam); // Crack the information from the handle object and send a notify to the snap-in ASSERT((pNotify->pComponent != NULL || pNotify->pComponentData != NULL)); if (pNotify->pComponent != NULL) pNotify->pComponent->Notify(NULL, MMCN_PROPERTY_CHANGE, pNotify->fScopePane, lParam); else if (pNotify->pComponentData != NULL) pNotify->pComponentData->Notify(NULL, MMCN_PROPERTY_CHANGE, pNotify->fScopePane, lParam); ::GlobalFree(pNotify); return TRUE; } LRESULT CMainFrame::OnSetText (WPARAM wParam, LPARAM lParam) { LRESULT rc; CAMCDoc* pDoc = CAMCDoc::GetDocument(); /* * If the document has a custom title, we don't want to append * the maxed child's title to the main frame's title. To do this, * we'll bypass DefFrameProc and go directly to DefWindowProc. */ if ((pDoc != NULL) && pDoc->HasCustomTitle()) rc = CWnd::DefWindowProc (WM_SETTEXT, wParam, lParam); else rc = Default(); DrawFrameCaption (this, m_fCurrentlyActive); return (rc); } void CMainFrame::OnPaletteChanged( CWnd* pwndFocus) { if (pwndFocus != this) { CAMCDoc* pAMCDoc = CAMCDoc::GetDocument(); if (pAMCDoc) { HWND hwndFocus = pwndFocus->GetSafeHwnd(); CAMCViewPosition pos = pAMCDoc->GetFirstAMCViewPosition(); while (pos != NULL) { CAMCView* pv = pAMCDoc->GetNextAMCView(pos); if (pv) pv->SendMessage(WM_PALETTECHANGED, (WPARAM)hwndFocus); } } } CMDIFrameWnd::OnPaletteChanged(pwndFocus); } BOOL CMainFrame::OnQueryNewPalette() { CAMCView* pAMCView = GetActiveAMCView(); if (pAMCView != NULL) return pAMCView->SendMessage(WM_QUERYNEWPALETTE); return CMDIFrameWnd::OnQueryNewPalette(); } void CMainFrame::OnConsoleProperties() { CConsolePropSheet().DoModal(); } void CMainFrame::SetIconEx (HICON hIcon, BOOL fBig) { if (hIcon == NULL) hIcon = GetDefaultIcon(); SetIcon (hIcon, fBig); /* * make sure the child icon on the menu bar gets updated */ ASSERT (m_pMenuBar != NULL); m_pMenuBar->InvalidateMaxedChildIcon(); } /*+-------------------------------------------------------------------------* * CMainFrame::GetDefaultIcon * * *--------------------------------------------------------------------------*/ HICON CMainFrame::GetDefaultIcon () const { return (AfxGetApp()->LoadIcon (IDR_MAINFRAME)); } /*+-------------------------------------------------------------------------* * CMainFrame::SendMinimizeNotifications * * Causes each CChildFrame to send NCLBK_MINIMIZED. *--------------------------------------------------------------------------*/ void CMainFrame::SendMinimizeNotifications (bool fMinimized) const { CWnd* pwndMDIChild; for (pwndMDIChild = m_wndMDIClient.GetWindow (GW_CHILD); pwndMDIChild != NULL; pwndMDIChild = pwndMDIChild->GetWindow (GW_HWNDNEXT)) { // There used to be an ASSERT_ISKINDOF. However, that had to change to an if // since the active background denies that assumption. See bug 428906. if(pwndMDIChild->IsKindOf(RUNTIME_CLASS(CChildFrame))) (static_cast(pwndMDIChild))->SendMinimizeNotification (fMinimized); } } /*+-------------------------------------------------------------------------* * CMainFrame::OnNcActivate * * WM_NCACTIVATE handler for CMainFrame. *--------------------------------------------------------------------------*/ BOOL CMainFrame::OnNcActivate(BOOL bActive) { BOOL rc = CMDIFrameWnd::OnNcActivate(bActive); DrawFrameCaption (this, m_fCurrentlyActive); return (rc); } /*+-------------------------------------------------------------------------* * CMainFrame::OnNcPaint * * WM_NCPAINT handler for CMainFrame. *--------------------------------------------------------------------------*/ void CMainFrame::OnNcPaint() { Default(); DrawFrameCaption (this, m_fCurrentlyActive); } /*+-------------------------------------------------------------------------* * MsgForwardingEnumProc * * *--------------------------------------------------------------------------*/ static BOOL CALLBACK MsgForwardingEnumProc (HWND hwnd, LPARAM lParam) { /* * if this isn't an MFC window, forward the message */ if (CWnd::FromHandlePermanent(hwnd) == NULL) { const MSG* pMsg = (const MSG*) lParam; SendMessage (hwnd, pMsg->message, pMsg->wParam, pMsg->lParam); } /* * continue enumeration */ return (true); } /*+-------------------------------------------------------------------------* * CMainFrame::OnSettingChange * * WM_SETTINGCHANGE handler for CMainFrame. *--------------------------------------------------------------------------*/ void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) { CMDIFrameWnd::OnSettingChange(uFlags, lpszSection); /* * MFC will send WM_SETTINGCHANGEs to all descendent MFC windows. * There are some non-MFC windows owned by nodemgr that we also want * to get this message. We'll send these manually. */ const MSG* pMsg = GetCurrentMessage(); EnumChildWindows (m_hWnd, MsgForwardingEnumProc, (LPARAM) pMsg); /* * If we're in SDI mode, then there can be some redrawing problems * around the caption if the caption height changes significantly. * (This is a USER MDI bug.) We can work around it by manually * placing the maximized child window within the MDI client. * * Note that restoring and re-maximizing the active child window * will put the window in the right place, it has the side effect * of undesired window flicker (see 375430, et al) as well as * a bunch of annoying sound effects if you have sounds associated * with the "Restore Down" and/or "Maximize" sound events. */ if (AMCGetApp()->GetMode() == eMode_User_SDI) { CMDIChildWnd* pwndActive = MDIGetActive(); if (pwndActive) { /* * get the size of the MDI client */ CRect rect; m_wndMDIClient.GetClientRect (rect); /* * inflate the MDI client's client rect by the size of sizing * borders, and add room for the caption at the top */ rect.InflateRect (GetSystemMetrics (SM_CXFRAME), GetSystemMetrics (SM_CYFRAME)); rect.top -= GetSystemMetrics (SM_CYCAPTION); /* * put the window in the right place */ pwndActive->MoveWindow (rect); } } } /*+-------------------------------------------------------------------------* * CMainFrame::ScGetActiveStatusBar * * Returns the CConsoleStatusBar interface for the active view. If there's no * active view, pStatusBar is set to NULL and S_FALSE is returned. *--------------------------------------------------------------------------*/ SC CMainFrame::ScGetActiveStatusBar ( CConsoleStatusBar*& pStatusBar) /* O:CConsoleStatusBar for active view*/ { AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC (sc, _T("CMainFrame::ScGetActiveStatusBar")); pStatusBar = dynamic_cast(GetActiveFrame()); if (pStatusBar == NULL) sc = S_FALSE; return (sc); } /*+-------------------------------------------------------------------------* * CMainFrame::ScGetActiveConsoleView * * Returns the CConsoleView interface for the active view. If there's no * active view, pConsoleView is set to NULL and S_FALSE is returned. *--------------------------------------------------------------------------*/ SC CMainFrame::ScGetActiveConsoleView ( CConsoleView*& pConsoleView) /* O:CConsoleView for active view */ { AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC (sc, _T("CMainFrame::ScGetActiveConsoleView")); pConsoleView = GetActiveAMCView(); if (pConsoleView == NULL) sc = S_FALSE; return (sc); } /***************************************************************************\ * * METHOD: CMainFrame::OnUnInitMenuPopup * * PURPOSE: Used to remove accelerators once system menus are dismissed * * PARAMETERS: * WPARAM wParam * LPARAM lParam * * RETURNS: * LRESULT - result code * \***************************************************************************/ afx_msg LRESULT CMainFrame::OnUnInitMenuPopup(WPARAM wParam, LPARAM lParam) { // hide accelerators whenever leaving system popup if ( HIWORD(lParam) & MF_SYSMENU ) { SendMessage( WM_CHANGEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEACCEL | UISF_HIDEFOCUS)); } return 0; }