home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / winfrm.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  64.3 KB  |  2,359 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #ifndef _DDEHEADER_INCLUDED_
  13. #include <dde.h>        // for DDE execute shell requests
  14. #endif
  15.  
  16. #ifdef AFX_CORE4_SEG
  17. #pragma code_seg(AFX_CORE4_SEG)
  18. #endif
  19.  
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24.  
  25. #define new DEBUG_NEW
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CRect for creating windows with the default position/size
  29.  
  30. const AFX_DATADEF CRect CFrameWnd::rectDefault(
  31.     WCE_IF(0,CW_USEDEFAULT), WCE_IF(0,CW_USEDEFAULT),
  32.     WCE_IF(CW_USEDEFAULT,0 /* 2*CW_USEDEFAULT */), WCE_IF(CW_USEDEFAULT,0 /* 2*CW_USEDEFAULT */));
  33.  
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CFrameWnd
  36.  
  37. #if !defined(_WIN32_WCE)
  38. // register for Windows 95 or Windows NT 3.51
  39. AFX_STATIC UINT _afxMsgMouseWheel =
  40.    (((::GetVersion() & 0x80000000) && LOBYTE(LOWORD(::GetVersion()) == 4)) ||
  41.      (!(::GetVersion() & 0x80000000) && LOBYTE(LOWORD(::GetVersion()) == 3)))
  42.      ? ::RegisterWindowMessage(MSH_MOUSEWHEEL) : 0;
  43. #endif // _WIN32_WCE
  44.  
  45. BEGIN_MESSAGE_MAP(CFrameWnd, CWnd)
  46.     //{{AFX_MSG_MAP(CFrameWnd)
  47. WCE_DEL    ON_WM_INITMENU()
  48.     ON_WM_INITMENUPOPUP()
  49. WCE_DEL    ON_WM_MENUSELECT()
  50. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  51.     ON_MESSAGE(WM_POPMESSAGESTRING, OnPopMessageString)
  52.     ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
  53.     ON_MESSAGE(WM_HELPPROMPTADDR, OnHelpPromptAddr)
  54. #endif // _WIN32_WCE_NO_CONTROLBARS
  55.     ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
  56. WCE_DEL ON_WM_ENTERIDLE()
  57.     ON_WM_HSCROLL()
  58.     ON_WM_VSCROLL()
  59.     ON_WM_SETFOCUS()
  60.     ON_WM_CREATE()
  61.     ON_WM_DESTROY()
  62.     ON_WM_CLOSE()
  63.     ON_WM_SIZE()
  64.     ON_WM_ERASEBKGND()
  65.     ON_WM_ACTIVATE()
  66. WCE_DEL    ON_WM_NCACTIVATE()
  67.     ON_WM_SYSCOMMAND()
  68. WCE_DEL    ON_WM_DROPFILES()
  69. WCE_DEL    ON_WM_QUERYENDSESSION()
  70. WCE_DEL    ON_WM_ENDSESSION()
  71. #if !defined(_WIN32_WCE_NO_CURSOR)
  72.     ON_WM_SETCURSOR()
  73. #endif // _WIN32_WCE_NO_CURSOR
  74.     ON_WM_ENABLE()
  75.     // OLE palette support
  76.     ON_WM_QUERYNEWPALETTE()
  77.     ON_WM_PALETTECHANGED()
  78.     ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
  79.     ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
  80.     ON_MESSAGE(WM_ACTIVATETOPLEVEL, OnActivateTopLevel)
  81.     // turning on and off standard frame gadgetry
  82. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  83.     ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR, OnUpdateControlBarMenu)
  84.     ON_COMMAND_EX(ID_VIEW_STATUS_BAR, OnBarCheck)
  85.     ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateControlBarMenu)
  86.     ON_COMMAND_EX(ID_VIEW_TOOLBAR, OnBarCheck)
  87.     ON_UPDATE_COMMAND_UI(ID_VIEW_REBAR, OnUpdateControlBarMenu)
  88.     ON_COMMAND_EX(ID_VIEW_REBAR, OnBarCheck)
  89.     // turning on and off standard mode indicators
  90.     ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS, OnUpdateKeyIndicator)
  91.     ON_UPDATE_COMMAND_UI(ID_INDICATOR_NUM, OnUpdateKeyIndicator)
  92.     ON_UPDATE_COMMAND_UI(ID_INDICATOR_SCRL, OnUpdateKeyIndicator)
  93.     ON_UPDATE_COMMAND_UI(ID_INDICATOR_KANA, OnUpdateKeyIndicator)
  94. #endif // _WIN32_WCE_NO_CONTROLBARS
  95.     // standard help handling
  96. WCE_DEL ON_UPDATE_COMMAND_UI(ID_CONTEXT_HELP, OnUpdateContextHelp)
  97.     // toolbar "tooltip" notification
  98. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  99. #if !defined(_WIN32_WCE_NO_TOOLTIPS)
  100.     ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
  101.     ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
  102. #endif // _WIN32_WCE_NO_TOOLTIPS
  103. #endif // _WIN32_WCE_NO_CONTROLBARS
  104.     //}}AFX_MSG_MAP
  105.     // message handling for standard DDE commands
  106. WCE_DEL    ON_MESSAGE(WM_DDE_INITIATE, OnDDEInitiate)
  107. WCE_DEL    ON_MESSAGE(WM_DDE_EXECUTE, OnDDEExecute)
  108. WCE_DEL    ON_MESSAGE(WM_DDE_TERMINATE, OnDDETerminate)
  109. WCE_DEL ON_REGISTERED_MESSAGE(_afxMsgMouseWheel, OnRegisteredMouseWheel)
  110. END_MESSAGE_MAP()
  111.  
  112. /////////////////////////////////////////////////////////////////////////////
  113. // CFrameWnd construction/destruction
  114.  
  115. CFrameWnd::CFrameWnd()
  116. {
  117.     ASSERT(m_hWnd == NULL);
  118.  
  119.     m_nWindow = -1;                 // unknown window ID
  120.     m_bAutoMenuEnable = TRUE;       // auto enable on by default
  121.     m_lpfnCloseProc = NULL;
  122.     m_hMenuDefault = NULL;
  123.     m_hAccelTable = NULL;
  124.     m_nIDHelp = 0;
  125.     m_nIDTracking = 0;
  126.     m_nIDLastMessage = 0;
  127.     m_pViewActive = NULL;
  128.  
  129.     m_cModalStack = 0;              // initialize modality support
  130.     m_phWndDisable = NULL;
  131. #if !defined(_WIN32_WCE)
  132.     m_pNotifyHook = NULL;
  133. #endif // _WIN32_WCE
  134.     m_hMenuAlt = NULL;
  135.     m_nIdleFlags = 0;               // no idle work at start
  136.     m_rectBorder.SetRectEmpty();
  137.  
  138.     m_bHelpMode = HELP_INACTIVE;    // not in Shift+F1 help mode
  139.     m_dwPromptContext = 0;
  140.  
  141.     m_pNextFrameWnd = NULL;         // not in list yet
  142.  
  143.     m_bInRecalcLayout = FALSE;
  144. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  145.     m_pFloatingFrameClass = NULL;
  146. #endif // _WIN32_WCE_NO_DOCKBARS
  147.     m_nShowDelay = -1;              // no delay pending
  148.  
  149.     m_poCommandBar = this;
  150.     AddFrameWnd();
  151. }
  152.  
  153. CFrameWnd::~CFrameWnd()
  154. {
  155.     RemoveFrameWnd();
  156.     if (m_phWndDisable != NULL)
  157.         delete[] (void*)m_phWndDisable;
  158. }
  159.  
  160. void CFrameWnd::AddFrameWnd()
  161. {
  162.     // hook it into the CFrameWnd list
  163.     AFX_MODULE_THREAD_STATE* pState = _AFX_CMDTARGET_GETSTATE()->m_thread;
  164.     pState->m_frameList.AddHead(this);
  165. }
  166.  
  167. void CFrameWnd::RemoveFrameWnd()
  168. {
  169.     // remove this frame window from the list of frame windows
  170.     AFX_MODULE_THREAD_STATE* pState = _AFX_CMDTARGET_GETSTATE()->m_thread;
  171.     pState->m_frameList.Remove(this);
  172. }
  173.  
  174. /////////////////////////////////////////////////////////////////////////////
  175. // Special processing etc
  176.  
  177. BOOL CFrameWnd::LoadAccelTable(LPCTSTR lpszResourceName)
  178. {
  179.     ASSERT(m_hAccelTable == NULL);  // only do once
  180.     ASSERT(lpszResourceName != NULL);
  181.  
  182.     HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_ACCELERATOR);
  183.     m_hAccelTable = ::LoadAccelerators(hInst, lpszResourceName);
  184.     return (m_hAccelTable != NULL);
  185. }
  186.  
  187. HACCEL CFrameWnd::GetDefaultAccelerator()
  188. {
  189.     // use document specific accelerator table over m_hAccelTable
  190.     HACCEL hAccelTable = m_hAccelTable;
  191.     HACCEL hAccel;
  192.     CDocument* pDoc = GetActiveDocument();
  193.     if (pDoc != NULL && (hAccel = pDoc->GetDefaultAccelerator()) != NULL)
  194.         hAccelTable = hAccel;
  195.  
  196.     return hAccelTable;
  197. }
  198.  
  199. BOOL CFrameWnd::PreTranslateMessage(MSG* pMsg)
  200. {
  201.     // check for special cancel modes for combo boxes
  202.     if (pMsg->message == WM_LBUTTONDOWN || pMsg->message == WCE_IF(WM_LBUTTONDOWN,WM_NCLBUTTONDOWN))
  203.         AfxCancelModes(pMsg->hwnd);    // filter clicks
  204.  
  205.     // allow tooltip messages to be filtered
  206.     if (CWnd::PreTranslateMessage(pMsg))
  207.         return TRUE;
  208.  
  209. #if !defined(_WIN32_WCE)
  210. #ifndef _AFX_NO_OLE_SUPPORT
  211.     // allow hook to consume message
  212.     if (m_pNotifyHook != NULL && m_pNotifyHook->OnPreTranslateMessage(pMsg))
  213.         return TRUE;
  214. #endif
  215. #endif // _WIN32_WCE
  216.  
  217.     if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
  218.     {
  219.         // finally, translate the message
  220.         HACCEL hAccel = GetDefaultAccelerator();
  221.         return hAccel != NULL &&  ::TranslateAccelerator(m_hWnd, hAccel, pMsg);
  222.     }
  223.     return FALSE;
  224. }
  225.  
  226. void CFrameWnd::PostNcDestroy()
  227. {
  228.     // default for frame windows is to allocate them on the heap
  229.     //  the default post-cleanup is to 'delete this'.
  230.     // never explicitly call 'delete' on a CFrameWnd, use DestroyWindow instead
  231.     delete this;
  232. }
  233.  
  234. void CFrameWnd::OnPaletteChanged(CWnd* pFocusWnd)
  235. {
  236.     CWnd::OnPaletteChanged(pFocusWnd);
  237. #if !defined(_WIN32_WCE)
  238. #ifndef _AFX_NO_OLE_SUPPORT
  239.     if (m_pNotifyHook != NULL)
  240.         m_pNotifyHook->OnPaletteChanged(pFocusWnd);
  241. #endif
  242. #endif // _WIN32_WCE
  243. }
  244.  
  245. BOOL CFrameWnd::OnQueryNewPalette()
  246. {
  247. #if !defined(_WIN32_WCE)
  248. #ifndef _AFX_NO_OLE_SUPPORT
  249.     if (m_pNotifyHook != NULL && m_pNotifyHook->OnQueryNewPalette())
  250.         return TRUE;
  251. #endif
  252. #endif // _WIN32_WCE
  253.     return CWnd::OnQueryNewPalette();
  254. }
  255.  
  256. /////////////////////////////////////////////////////////////////////////////
  257. // CFrameWnd support for context sensitive help.
  258.  
  259. #if !defined(_WIN32_WCE)
  260. void CFrameWnd::ExitHelpMode()
  261. {
  262.     // if not in help mode currently, this is a no-op
  263.     if (!m_bHelpMode)
  264.         return;
  265.  
  266.     // only post new WM_EXITHELPMODE message if one doesn't already exist
  267.     //  in the queue.
  268.     MSG msg;
  269.     if (!::PeekMessage(&msg, m_hWnd, WM_EXITHELPMODE, WM_EXITHELPMODE,
  270.         PM_REMOVE|PM_NOYIELD))
  271.     {
  272.         VERIFY(::PostMessage(m_hWnd, WM_EXITHELPMODE, 0, 0));
  273.     }
  274.  
  275.     // release capture if this window has it
  276.     if (::GetCapture() == m_hWnd)
  277.         ReleaseCapture();
  278.  
  279.     CFrameWnd* pFrameWnd = GetTopLevelFrame();
  280.     ASSERT_VALID(pFrameWnd);
  281.     pFrameWnd->m_bHelpMode = m_bHelpMode = HELP_INACTIVE;
  282.     PostMessage(WM_KICKIDLE);   // trigger idle update
  283. }
  284. #endif // _WIN32_WCE
  285.  
  286. #if !defined(_WIN32_WCE_NO_CURSOR)
  287. BOOL CFrameWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  288. {
  289.     CFrameWnd* pFrameWnd = GetTopLevelFrame();
  290.     ASSERT_VALID(pFrameWnd);
  291.     if (pFrameWnd->m_bHelpMode)
  292.     {
  293.         SetCursor(afxData.hcurHelp);
  294.         return TRUE;
  295.     }
  296.     return CWnd::OnSetCursor(pWnd, nHitTest, message);
  297. }
  298. #endif // _WIN32_WCE_NO_CURSOR
  299.  
  300. LRESULT CFrameWnd::OnCommandHelp(WPARAM, LPARAM lParam)
  301. {
  302.     if (lParam == 0)
  303.     {
  304.         if (IsTracking())
  305.             lParam = HID_BASE_COMMAND+m_nIDTracking;
  306.         else
  307.             lParam = HID_BASE_RESOURCE+m_nIDHelp;
  308.     }
  309.     if (lParam != 0)
  310.     {
  311.         CWinApp* pApp = AfxGetApp();
  312.         if (pApp != NULL)
  313.             pApp->WinHelp(lParam);
  314.         return TRUE;
  315.     }
  316.     return FALSE;
  317. }
  318.  
  319. LRESULT CFrameWnd::OnHelpHitTest(WPARAM, LPARAM)
  320. {
  321.     if (m_nIDHelp != 0)
  322.         return HID_BASE_RESOURCE+m_nIDHelp;
  323.     else
  324.         return 0;
  325. }
  326.  
  327. BOOL CFrameWnd::OnCommand(WPARAM wParam, LPARAM lParam)
  328.     // return TRUE if command invocation was attempted
  329. {
  330.     HWND hWndCtrl = (HWND)lParam;
  331.     UINT nID = LOWORD(wParam);
  332.  
  333.     CFrameWnd* pFrameWnd = GetTopLevelFrame();
  334.     ASSERT_VALID(pFrameWnd);
  335.     if (pFrameWnd->m_bHelpMode && hWndCtrl == NULL &&
  336.         nID != ID_HELP && nID != ID_DEFAULT_HELP && nID != ID_CONTEXT_HELP)
  337.     {
  338.         // route as help
  339.         if (!SendMessage(WM_COMMANDHELP, 0, HID_BASE_COMMAND+nID))
  340.             SendMessage(WM_COMMAND, ID_DEFAULT_HELP);
  341.         return TRUE;
  342.     }
  343.  
  344.     // route as normal command
  345.     return CWnd::OnCommand(wParam, lParam);
  346. }
  347.  
  348. /////////////////////////////////////////////////////////////////////////////
  349. // CFrameWnd support for modality
  350.  
  351. BOOL AFXAPI AfxIsDescendant(HWND hWndParent, HWND hWndChild)
  352.     // helper for detecting whether child descendent of parent
  353.     //  (works with owned popups as well)
  354. {
  355.     ASSERT(::IsWindow(hWndParent));
  356.     ASSERT(::IsWindow(hWndChild));
  357.  
  358.     do
  359.     {
  360.         if (hWndParent == hWndChild)
  361.             return TRUE;
  362.  
  363.         hWndChild = AfxGetParentOwner(hWndChild);
  364.     } while (hWndChild != NULL);
  365.  
  366.     return FALSE;
  367. }
  368.  
  369. #if defined(_WIN32_WCE)
  370. void CFrameWnd::BeginModalState() 
  371.     ASSERT(m_hWnd != NULL); 
  372.     ASSERT(::IsWindow(m_hWnd)); 
  373.  
  374.     // allow stacking, but don't do anything 
  375.     if (++m_cModalStack > 1) 
  376.         return; 
  377.  
  378.     // determine top-level parent, since that is the true parent of any 
  379.     //  modeless windows anyway... 
  380.     CWnd* pParent = GetTopLevelParent(); 
  381.  
  382.     UINT    nCount = 0; 
  383.     HWND    hWnd = m_hWnd; 
  384.     if (::IsWindowEnabled(hWnd) && (CWnd::FromHandlePermanent(hWnd) != NULL) &&  
  385.         AfxIsDescendant(pParent->m_hWnd, hWnd) && (::SendMessage(hWnd, WM_DISABLEMODAL, 0, 0) == 0)) 
  386.     {
  387.         ++nCount;
  388.     }
  389.     if (nCount == 0)
  390.         return;
  391.  
  392.     m_phWndDisable = new HWND[nCount+1];
  393.  
  394.     // disable all windows connected to this frame (and add them to the list)
  395.     // WinCE supports only a single window
  396.     UINT nIndex = 0;
  397.     hWnd = m_hWnd;
  398.     if (::IsWindowEnabled(hWnd) && (CWnd::FromHandlePermanent(hWnd) != NULL) && 
  399.         AfxIsDescendant(pParent->m_hWnd, hWnd) && (::SendMessage(hWnd, WM_DISABLEMODAL, 0, 0) == 0))
  400.     {
  401.         ::EnableWindow(hWnd, FALSE);
  402.         ASSERT(nIndex < nCount);
  403.         m_phWndDisable[nIndex] = hWnd;
  404.         ++nIndex;
  405.     }
  406.  
  407.     // terminate the list with a NULL
  408.     ASSERT(nIndex < nCount+1);
  409.     m_phWndDisable[nIndex] = NULL;
  410. }
  411. #else // _WIN32_WCE
  412. void CFrameWnd::BeginModalState()
  413. {
  414.     ASSERT(m_hWnd != NULL);
  415.     ASSERT(::IsWindow(m_hWnd));
  416.  
  417.     // allow stacking, but don't do anything
  418.     if (++m_cModalStack > 1)
  419.         return;
  420.  
  421.     // determine top-level parent, since that is the true parent of any
  422.     //  modeless windows anyway...
  423.     CWnd* pParent = GetTopLevelParent();
  424.  
  425.     // first count all windows that need to be disabled
  426.     UINT nCount = 0;
  427.     HWND hWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
  428.     while (hWnd != NULL)
  429.     {
  430.         if (::IsWindowEnabled(hWnd) &&
  431.             CWnd::FromHandlePermanent(hWnd) != NULL &&
  432.             AfxIsDescendant(pParent->m_hWnd, hWnd) &&
  433.             ::SendMessage(hWnd, WM_DISABLEMODAL, 0, 0) == 0)
  434.         {
  435.             ++nCount;
  436.         }
  437.         hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  438.     }
  439.     if (nCount == 0)
  440.         return;
  441.  
  442.     m_phWndDisable = new HWND[nCount+1];
  443.  
  444.     // disable all windows connected to this frame (and add them to the list)
  445.     UINT nIndex = 0;
  446.     hWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
  447.     while (hWnd != NULL)
  448.     {
  449.         if (::IsWindowEnabled(hWnd) &&
  450.             CWnd::FromHandlePermanent(hWnd) != NULL &&
  451.             AfxIsDescendant(pParent->m_hWnd, hWnd) &&
  452.             ::SendMessage(hWnd, WM_DISABLEMODAL, 0, 0) == 0)
  453.         {
  454.             ::EnableWindow(hWnd, FALSE);
  455.             ASSERT(nIndex < nCount);
  456.             m_phWndDisable[nIndex] = hWnd;
  457.             ++nIndex;
  458.         }
  459.         hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  460.     }
  461.  
  462.     // terminate the list with a NULL
  463.     ASSERT(nIndex < nCount+1);
  464.     m_phWndDisable[nIndex] = NULL;
  465. }
  466. #endif // _WIN32_WCE
  467.  
  468. void CFrameWnd::EndModalState()
  469. {
  470.     // pop one off the stack (don't undo modalness unless stack is down to zero)
  471.     if (m_cModalStack == 0 || --m_cModalStack > 0 || m_phWndDisable == NULL)
  472.         return;
  473.  
  474.     // enable all the windows disabled by BeginModalState
  475.     ASSERT(m_phWndDisable != NULL);
  476.     UINT nIndex = 0;
  477.     while (m_phWndDisable[nIndex] != NULL)
  478.     {
  479.         ASSERT(m_phWndDisable[nIndex] != NULL);
  480.         if (::IsWindow(m_phWndDisable[nIndex]))
  481.             ::EnableWindow(m_phWndDisable[nIndex], TRUE);
  482.         ++nIndex;
  483.     }
  484.     delete[] (void*)m_phWndDisable;
  485.     m_phWndDisable = NULL;
  486. }
  487.  
  488. void CFrameWnd::ShowOwnedWindows(BOOL bShow)
  489. {
  490.     // walk through all top-level windows
  491.     HWND hWnd = ::GetWindow(::WCE_FCTN(GetDesktopWindow)(), GW_CHILD);
  492.     while (hWnd != NULL)
  493.     {
  494.         CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
  495.         if (pWnd != NULL && m_hWnd != hWnd && AfxIsDescendant(m_hWnd, hWnd))
  496.         {
  497.             DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE);
  498.             if (!bShow && (dwStyle & (WS_VISIBLE|WS_DISABLED)) == WS_VISIBLE)
  499.             {
  500.                 ::ShowWindow(hWnd, SW_HIDE);
  501.                 pWnd->m_nFlags |= WF_TEMPHIDE;
  502.             }
  503.             else if (bShow && (dwStyle & (WS_VISIBLE|WS_DISABLED)) == 0 &&
  504.                 (pWnd->m_nFlags & WF_TEMPHIDE))
  505.             {
  506.                 ::ShowWindow(hWnd, SW_SHOWNOACTIVATE);
  507.                 pWnd->m_nFlags &= ~WF_TEMPHIDE;
  508.             }
  509.         }
  510.         hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  511.     }
  512. }
  513.  
  514. void CFrameWnd::OnEnable(BOOL bEnable)
  515. {
  516.     if (bEnable && (m_nFlags & WF_STAYDISABLED))
  517.     {
  518.         // Work around for MAPI support. This makes sure the main window
  519.         // remains disabled even when the mail system is booting.
  520.         EnableWindow(FALSE);
  521.         ::SetFocus(NULL);
  522.         return;
  523.     }
  524.  
  525.     // only for top-level (and non-owned) windows
  526.     if (GetParent() != NULL)
  527.         return;
  528.  
  529.     // this causes modal dialogs to be "truly modal"
  530.     if (!bEnable && !InModalState())
  531.     {
  532.         ASSERT((m_nFlags & WF_MODALDISABLE) == 0);
  533.         m_nFlags |= WF_MODALDISABLE;
  534.         BeginModalState();
  535.     }
  536.     else if (bEnable && (m_nFlags & WF_MODALDISABLE))
  537.     {
  538.         m_nFlags &= ~WF_MODALDISABLE;
  539.         EndModalState();
  540.  
  541.         // cause normal focus logic to kick in
  542.         if (::GetActiveWindow() == m_hWnd)
  543.             SendMessage(WM_ACTIVATE, WA_ACTIVE);
  544.     }
  545.  
  546.     // force WM_NCACTIVATE because Windows may think it is unecessary
  547. #if !defined(_WIN32_WCE)
  548.     if (bEnable && (m_nFlags & WF_STAYACTIVE))
  549.         SendMessage(WM_NCACTIVATE, TRUE);
  550.     // force WM_NCACTIVATE for floating windows too
  551. #endif // _WIN32_WCE
  552. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  553.     NotifyFloatingWindows(bEnable ? FS_ENABLE : FS_DISABLE);
  554. #endif // _WIN32_WCE_NO_DOCKBARS
  555. }
  556.  
  557. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  558. void CFrameWnd::NotifyFloatingWindows(DWORD dwFlags)
  559. {
  560.     ASSERT_VALID(this);
  561.     ASSERT(m_hWnd != NULL);
  562.  
  563.     // get top level parent frame window first unless this is a child window
  564.     CFrameWnd* pParent = (GetStyle() & WS_CHILD) ? this : GetTopLevelFrame();
  565.     ASSERT(pParent != NULL);
  566.     if (dwFlags & (FS_DEACTIVATE|FS_ACTIVATE))
  567.     {
  568.         // update parent window activation state
  569.         BOOL bActivate = !(dwFlags & FS_DEACTIVATE);
  570.         BOOL bEnabled = pParent->IsWindowEnabled();
  571.  
  572.         if (bActivate && bEnabled && pParent != this)
  573.         {
  574.             // Excel will try to Activate itself when it receives a
  575.             // WM_NCACTIVATE so we need to keep it from doing that here.
  576.             m_nFlags |= WF_KEEPMINIACTIVE;
  577.             pParent->SendMessage(WM_NCACTIVATE, TRUE);
  578.             m_nFlags &= ~WF_KEEPMINIACTIVE;
  579.         }
  580.         else
  581.         {
  582.             pParent->SendMessage(WM_NCACTIVATE, FALSE);
  583.         }
  584.     }
  585.  
  586.     // then update the state of all floating windows owned by the parent
  587.     HWND hWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
  588.     while (hWnd != NULL)
  589.     {
  590.         if (AfxIsDescendant(pParent->m_hWnd, hWnd))
  591.             ::SendMessage(hWnd, WM_FLOATSTATUS, dwFlags, 0);
  592.         hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  593.     }
  594. }
  595. #endif // _WIN32_WCE_NO_DOCKBARS
  596.  
  597. /////////////////////////////////////////////////////////////////////////////
  598. // CFrameWnd second phase creation
  599.  
  600. BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
  601. {
  602.     if (cs.lpszClass == NULL)
  603.     {
  604.         VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
  605.         cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background
  606.     }
  607.  
  608.     if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
  609.         cs.style |= FWS_PREFIXTITLE;
  610.  
  611. #if !defined(_WIN32_WCE)
  612. // WinCE: FrameWindows should not have borders.
  613.     if (afxData.bWin4)
  614.         cs.dwExStyle |= WS_EX_CLIENTEDGE;
  615. #endif // _WIN32_WCE
  616.  
  617.     return TRUE;
  618. }
  619.  
  620. BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
  621.     LPCTSTR lpszWindowName,
  622.     DWORD dwStyle,
  623.     const RECT& rect,
  624.     CWnd* pParentWnd,
  625.     LPCTSTR lpszMenuName,
  626.     DWORD dwExStyle,
  627.     CCreateContext* pContext)
  628. {
  629.     HMENU hMenu = NULL;
  630. #if defined(_WIN32_WCE)
  631. // WinCE: cache the menu resource id for old command bar compatibility
  632.     m_lpszMenuName = lpszMenuName;
  633. #else // _WIN32_WCE
  634.     if (lpszMenuName != NULL)
  635.     {
  636.         // load in a menu that will get destroyed when window gets destroyed
  637.         HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU);
  638.         if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL)
  639.         {
  640.             TRACE0("Warning: failed to load menu for CFrameWnd.\n");
  641.             PostNcDestroy();            // perhaps delete the C++ object
  642.             return FALSE;
  643.         }
  644.     }
  645. #endif // _WIN32_WCE
  646.  
  647.     m_strTitle = lpszWindowName;    // save title for later
  648.  
  649.     if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
  650.         rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
  651.         pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext))
  652.     {
  653.         TRACE0("Warning: failed to create CFrameWnd.\n");
  654.         if (hMenu != NULL)
  655.             DestroyMenu(hMenu);
  656.         return FALSE;
  657.     }
  658.  
  659. #if defined(_WIN32_WCE)
  660. //WinCE: set icon image for taskbar
  661.     if(lpszMenuName != NULL)
  662.     {
  663.         HICON hIcon = NULL;
  664.         HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_ICON);
  665.         if ((hIcon = (HICON)::LoadImage(hInst, lpszMenuName,  
  666.             IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR)) != NULL)
  667.         {
  668.             PostMessage(WM_SETICON, FALSE, (LPARAM)hIcon);
  669.         }
  670.     }
  671. #endif // _WIN32_WCE
  672.     return TRUE;
  673. }
  674.  
  675. CWnd* CFrameWnd::CreateView(CCreateContext* pContext, UINT nID)
  676. {
  677.     ASSERT(m_hWnd != NULL);
  678.     ASSERT(::IsWindow(m_hWnd));
  679.     ASSERT(pContext != NULL);
  680.     ASSERT(pContext->m_pNewViewClass != NULL);
  681.  
  682.     // Note: can be a CWnd with PostNcDestroy self cleanup
  683.     CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();
  684.     if (pView == NULL)
  685.     {
  686.         TRACE1("Warning: Dynamic create of view type %hs failed.\n",
  687.             pContext->m_pNewViewClass->m_lpszClassName);
  688.         return NULL;
  689.     }
  690.     ASSERT_KINDOF(CWnd, pView);
  691.  
  692. #if defined(_WIN32_WCE)
  693.     RECT rcMain;
  694.     ::GetClientRect( m_hWnd, &rcMain );
  695.     CRect initRect(0, 0, rcMain.right, rcMain.bottom);
  696.  
  697.     // views are always created with a border! 
  698.     if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,    initRect, this, nID, pContext))
  699.     {
  700.         TRACE0("Warning: could not create view for frame.\n");
  701.         return NULL;        // can't continue without a view
  702.     }
  703. #else // _WIN32_WCE
  704.     // views are always created with a border!
  705.     if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  706.         CRect(0,0,0,0), this, nID, pContext))
  707.     {
  708.         TRACE0("Warning: could not create view for frame.\n");
  709.         return NULL;        // can't continue without a view
  710.     }
  711.  
  712.     if (afxData.bWin4 && (pView->GetExStyle() & WS_EX_CLIENTEDGE))
  713.     {
  714.         // remove the 3d style from the frame, since the view is
  715.         //  providing it.
  716.         // make sure to recalc the non-client area
  717.         ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);
  718.     }
  719. #endif // _WIN32_WCE
  720.     return pView;
  721. }
  722.  
  723. BOOL CFrameWnd::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext)
  724. {
  725.     // default create client will create a view if asked for it
  726.     if (pContext != NULL && pContext->m_pNewViewClass != NULL)
  727.     {
  728.         if (CreateView(pContext, AFX_IDW_PANE_FIRST) == NULL)
  729.             return FALSE;
  730.     }
  731.     return TRUE;
  732. }
  733.  
  734. int CFrameWnd::OnCreate(LPCREATESTRUCT lpcs)
  735. {
  736.     CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;
  737.     return OnCreateHelper(lpcs, pContext);
  738. }
  739.  
  740. int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext* pContext)
  741. {
  742.     if (CWnd::OnCreate(lpcs) == -1)
  743.         return -1;
  744.  
  745.     // create special children first
  746.     if (!OnCreateClient(lpcs, pContext))
  747.     {
  748.         TRACE0("Failed to create client pane/view for frame.\n");
  749.         return -1;
  750.     }
  751.  
  752.     // post message for initial message string
  753.     PostMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
  754.  
  755.     // make sure the child windows have been properly sized
  756.     RecalcLayout();
  757.  
  758.     return 0;   // create ok
  759. }
  760.  
  761. LPCTSTR CFrameWnd::GetIconWndClass(DWORD dwDefaultStyle, UINT nIDResource)
  762. {
  763.     ASSERT_VALID_IDR(nIDResource);
  764.     HINSTANCE hInst = AfxFindResourceHandle(
  765.         MAKEINTRESOURCE(nIDResource), RT_GROUP_ICON);
  766.     HICON hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(nIDResource));
  767.     if (hIcon != NULL)
  768.     {
  769.         CREATESTRUCT cs;
  770.         memset(&cs, 0, sizeof(CREATESTRUCT));
  771.         cs.style = dwDefaultStyle;
  772.         PreCreateWindow(cs);
  773.             // will fill lpszClassName with default WNDCLASS name
  774.             // ignore instance handle from PreCreateWindow.
  775.  
  776.         WNDCLASS wndcls;
  777.         if (cs.lpszClass != NULL &&
  778.             GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls) &&
  779.             wndcls.hIcon != hIcon)
  780.         {
  781.             // register a very similar WNDCLASS
  782.             return AfxRegisterWndClass(wndcls.style,
  783.                 wndcls.hCursor, wndcls.hbrBackground, hIcon);
  784.         }
  785.     }
  786.     return NULL;        // just use the default
  787. }
  788.  
  789. BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
  790.     CWnd* pParentWnd, CCreateContext* pContext)
  791. {
  792.     // only do this once
  793.     ASSERT_VALID_IDR(nIDResource);
  794.     ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);
  795.  
  796.     m_nIDHelp = nIDResource;    // ID for help context (+HID_BASE_RESOURCE)
  797.  
  798.     CString strFullString;
  799.     if (strFullString.LoadString(nIDResource))
  800.         AfxExtractSubString(m_strTitle, strFullString, 0);    // first sub-string
  801.  
  802.     VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
  803.  
  804.     // attempt to create the window
  805.     LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
  806.     LPCTSTR lpszTitle = m_strTitle;
  807.     if (!Create(lpszClass, lpszTitle, WCE_IF(WS_VISIBLE, dwDefaultStyle), rectDefault,
  808.       pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
  809.     {
  810.         return FALSE;   // will self destruct on failure normally
  811.     }
  812.  
  813.     // save the default menu handle
  814.     ASSERT(m_hWnd != NULL);
  815.  
  816.     // load accelerator resource
  817.     LoadAccelTable(MAKEINTRESOURCE(nIDResource));
  818.  
  819.     if (pContext == NULL)   // send initial update
  820.         SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
  821.  
  822.     return TRUE;
  823. }
  824.  
  825. void CFrameWnd::OnUpdateFrameMenu(HMENU hMenuAlt)
  826. {
  827.     if (hMenuAlt == NULL)
  828.     {
  829.         // attempt to get default menu from document
  830.         CDocument* pDoc = GetActiveDocument();
  831.         if (pDoc != NULL)
  832.             hMenuAlt = pDoc->GetDefaultMenu();
  833.         // use default menu stored in frame if none from document
  834.         if (hMenuAlt == NULL)
  835.             hMenuAlt = m_hMenuDefault;
  836.     }
  837.     // finally, set the menu
  838.     ::WCE_FCTN(SetMenu)(m_hWnd, hMenuAlt);
  839. }
  840.  
  841. void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible)
  842. {
  843.     // if the frame does not have an active view, set to first pane
  844.     CView* pView = NULL;
  845.     if (GetActiveView() == NULL)
  846.     {
  847.         CWnd* pWnd = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
  848.         if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)))
  849.         {
  850.             pView = (CView*)pWnd;
  851.             SetActiveView(pView, FALSE);
  852.         }
  853.     }
  854.  
  855.     if (bMakeVisible)
  856.     {
  857.         // send initial update to all views (and other controls) in the frame
  858.         SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
  859.  
  860.         // give view a chance to save the focus (CFormView needs this)
  861.         if (pView != NULL)
  862.             pView->OnActivateFrame(WA_INACTIVE, this);
  863.  
  864.         // finally, activate the frame
  865.         // (send the default show command unless the main desktop window)
  866.         int nCmdShow = -1;      // default
  867.         CWinApp* pApp = AfxGetApp();
  868.         if (pApp != NULL && pApp->m_pMainWnd == this)
  869.         {
  870.             nCmdShow = pApp->m_nCmdShow; // use the parameter from WinMain
  871.             pApp->m_nCmdShow = -1; // set to default after first time
  872.         }
  873.         ActivateFrame(nCmdShow);
  874.         if (pView != NULL)
  875.             pView->OnActivateView(TRUE, pView, pView);
  876.     }
  877.  
  878.     // update frame counts and frame title (may already have been visible)
  879.     if (pDoc != NULL)
  880.         pDoc->UpdateFrameCounts();
  881.     OnUpdateFrameTitle(TRUE);
  882. }
  883.  
  884. /////////////////////////////////////////////////////////////////////////////
  885. // CFrameWnd closing down
  886.  
  887. void CFrameWnd::OnClose()
  888. {
  889.     if (m_lpfnCloseProc != NULL && !(*m_lpfnCloseProc)(this))
  890.         return;
  891.  
  892.     // Note: only queries the active document
  893.     CDocument* pDocument = GetActiveDocument();
  894.     if (pDocument != NULL && !pDocument->CanCloseFrame(this))
  895.     {
  896.         // document can't close right now -- don't close it
  897.         return;
  898.     }
  899.     CWinApp* pApp = AfxGetApp();
  900.     if (pApp != NULL && pApp->m_pMainWnd == this)
  901.     {
  902.         // attempt to save all documents
  903.         if (pDocument == NULL && !pApp->SaveAllModified())
  904.             return;     // don't close it
  905.  
  906.         // hide the application's windows before closing all the documents
  907.         pApp->HideApplication();
  908.  
  909.         // close all documents first
  910.         pApp->CloseAllDocuments(FALSE);
  911.  
  912. #if !defined(_WIN32_WCE_NO_OLE)
  913.         // don't exit if there are outstanding component objects
  914.         if (!AfxOleCanExitApp())
  915.         {
  916.             // take user out of control of the app
  917.             AfxOleSetUserCtrl(FALSE);
  918.  
  919.             // don't destroy the main window and close down just yet
  920.             //  (there are outstanding component (OLE) objects)
  921.             return;
  922.         }
  923. #endif // _WIN32_WCE_NO_OLE
  924.  
  925.         // there are cases where destroying the documents may destroy the
  926.         //  main window of the application.
  927.         if (!afxContextIsDLL && pApp->m_pMainWnd == NULL)
  928.         {
  929.             AfxPostQuitMessage(0);
  930.             return;
  931.         }
  932.     }
  933.  
  934.     // detect the case that this is the last frame on the document and
  935.     // shut down with OnCloseDocument instead.
  936.     if (pDocument != NULL && pDocument->m_bAutoDelete)
  937.     {
  938.         BOOL bOtherFrame = FALSE;
  939.         POSITION pos = pDocument->GetFirstViewPosition();
  940.         while (pos != NULL)
  941.         {
  942.             CView* pView = pDocument->GetNextView(pos);
  943.             ASSERT_VALID(pView);
  944.             if (pView->GetParentFrame() != this)
  945.             {
  946.                 bOtherFrame = TRUE;
  947.                 break;
  948.             }
  949.         }
  950.         if (!bOtherFrame)
  951.         {
  952.             pDocument->OnCloseDocument();
  953.             return;
  954.         }
  955.  
  956.         // allow the document to cleanup before the window is destroyed
  957.         pDocument->PreCloseFrame(this);
  958.     }
  959.  
  960.     // then destroy the window
  961.     DestroyWindow();
  962. }
  963.  
  964. void CFrameWnd::OnDestroy()
  965. {
  966. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  967.     DestroyDockBars();
  968. #endif // _WIN32_WCE_NO_DOCKBARS
  969.  
  970.     // reset menu to default before final shutdown
  971.     if (m_hMenuDefault != NULL && ::WCE_FCTN(GetMenu)(m_hWnd) != m_hMenuDefault)
  972.     {
  973.         ::WCE_FCTN(SetMenu)(m_hWnd, m_hMenuDefault);
  974.         ASSERT(::WCE_FCTN(GetMenu)(m_hWnd) == m_hMenuDefault);
  975.     }
  976.  
  977. #if !defined(_WIN32_WCE)
  978.     // Automatically quit when the main window is destroyed.
  979.     CWinApp* pApp = AfxGetApp();
  980.     if (pApp != NULL && pApp->m_pMainWnd == this)
  981.     {
  982.         // closing the main application window
  983.         ::WinHelp(m_hWnd, NULL, HELP_QUIT, 0L);
  984.  
  985.         // will call PostQuitMessage in CWnd::OnNcDestroy
  986.     }
  987. #endif // _WIN32_WCE
  988.  
  989.     CWnd::OnDestroy();
  990. }
  991.  
  992. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  993. void CFrameWnd::RemoveControlBar(CControlBar *pBar)
  994. {
  995.     POSITION pos = m_listControlBars.Find(pBar);
  996.     if (pos != NULL)
  997.         m_listControlBars.RemoveAt(pos);
  998. }
  999. #endif // _WIN32_WCE_NO_CONTROLBARS
  1000.  
  1001. /////////////////////////////////////////////////////////////////////////////
  1002. // CFrameWnd command/message routing
  1003.  
  1004. BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
  1005.     AFX_CMDHANDLERINFO* pHandlerInfo)
  1006. {
  1007.     CPushRoutingFrame push(this);
  1008.  
  1009.     // pump through current view FIRST
  1010.     CView* pView = GetActiveView();
  1011.     if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  1012.         return TRUE;
  1013.  
  1014.     // then pump through frame
  1015.     if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  1016.         return TRUE;
  1017.  
  1018.     // last but not least, pump through app
  1019.     CWinApp* pApp = AfxGetApp();
  1020.     if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  1021.         return TRUE;
  1022.  
  1023.     return FALSE;
  1024. }
  1025.  
  1026. // Delegate scroll messages to active view as well
  1027. void CFrameWnd::OnHScroll(UINT, UINT, CScrollBar*)
  1028. {
  1029.     CWnd* pActiveView = GetActiveView();
  1030.     if (pActiveView != NULL)
  1031.     {
  1032.         const MSG* pMsg = GetCurrentMessage();
  1033.         pActiveView->SendMessage(WM_HSCROLL, pMsg->wParam, pMsg->lParam);
  1034.     }
  1035. }
  1036.  
  1037. void CFrameWnd::OnVScroll(UINT, UINT, CScrollBar*)
  1038. {
  1039.     CWnd* pActiveView = GetActiveView();
  1040.     if (pActiveView != NULL)
  1041.     {
  1042.         const MSG* pMsg = GetCurrentMessage();
  1043.         pActiveView->SendMessage(WM_VSCROLL, pMsg->wParam, pMsg->lParam);
  1044.     }
  1045. }
  1046.  
  1047. LRESULT CFrameWnd::OnActivateTopLevel(WPARAM wParam, LPARAM lParam)
  1048. {
  1049.     CWnd::OnActivateTopLevel(wParam, lParam);
  1050.  
  1051. #if !defined(_WIN32_WCE)
  1052.     // exit Shift+F1 help mode on activation changes
  1053.     ExitHelpMode();
  1054.  
  1055. #ifndef _AFX_NO_OLE_SUPPORT
  1056.     // allow OnFrameWindowActivate to be sent to in-place items
  1057.     if (m_pNotifyHook != NULL)
  1058.     {
  1059.         // activate when active and when not minimized
  1060.         m_pNotifyHook->OnActivate(
  1061.             LOWORD(wParam) != WA_INACTIVE && !HIWORD(wParam));
  1062.     }
  1063. #endif
  1064. #endif // _WIN32_WCE
  1065.  
  1066.     // deactivate current active view
  1067.     if (AfxGetThread()->m_pMainWnd == this)
  1068.     {
  1069.         CView* pActiveView = GetActiveView();
  1070.         if (pActiveView == NULL)
  1071.             pActiveView = GetActiveFrame()->GetActiveView();
  1072.         if (pActiveView != NULL)
  1073.             pActiveView->OnActivateView(FALSE, pActiveView, pActiveView);
  1074.     }
  1075.  
  1076.     // force idle processing to update any key state indicators
  1077.     PostMessage(WM_KICKIDLE);
  1078.  
  1079.     return 0;
  1080. }
  1081.  
  1082. void CFrameWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
  1083. {
  1084.     CWnd::OnActivate(nState, pWndOther, bMinimized);
  1085.  
  1086.     // get top level frame unless this is a child window
  1087.     // determine if window should be active or not
  1088.     CFrameWnd* pTopLevel = (GetStyle() & WS_CHILD) ? this : GetTopLevelFrame();
  1089.     ASSERT(pTopLevel != NULL);
  1090.     CWnd* pActive = (nState == WA_INACTIVE ? pWndOther : this);
  1091.     BOOL bStayActive =
  1092.         (pTopLevel == pActive ||
  1093.         (pTopLevel == pActive->GetTopLevelFrame() &&
  1094.         (pActive == pTopLevel ||
  1095.             pActive->SendMessage(WM_FLOATSTATUS, FS_SYNCACTIVE) != 0)));
  1096.     pTopLevel->m_nFlags &= ~WF_STAYACTIVE;
  1097.     if (bStayActive)
  1098.         pTopLevel->m_nFlags |= WF_STAYACTIVE;
  1099.  
  1100. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  1101.     // sync floating windows to the new state
  1102.     NotifyFloatingWindows(bStayActive ? FS_ACTIVATE : FS_DEACTIVATE);
  1103. #endif // _WIN32_WCE_NO_DOCKBARS
  1104.  
  1105.     // get active view (use active frame if no active view)
  1106.     CView* pActiveView = GetActiveView();
  1107.     if (pActiveView == NULL)
  1108.         pActiveView = GetActiveFrame()->GetActiveView();
  1109.  
  1110.     // when frame gets activated, re-activate current view
  1111.     if (pActiveView != NULL)
  1112.     {
  1113.         if (nState != WA_INACTIVE && !bMinimized)
  1114.             pActiveView->OnActivateView(TRUE, pActiveView, pActiveView);
  1115.  
  1116.         // always notify the view of frame activations
  1117.         pActiveView->OnActivateFrame(nState, this);
  1118.     }
  1119. }
  1120.  
  1121. #if !defined(_WIN32_WCE)
  1122. BOOL CFrameWnd::OnNcActivate(BOOL bActive)
  1123. {
  1124.     // stay active if WF_STAYACTIVE bit is on
  1125.     if (m_nFlags & WF_STAYACTIVE)
  1126.         bActive = TRUE;
  1127.  
  1128.     // but do not stay active if the window is disabled
  1129.     if (!IsWindowEnabled())
  1130.         bActive = FALSE;
  1131.  
  1132.     // do not call the base class because it will call Default()
  1133.     //  and we may have changed bActive.
  1134.     return (BOOL)DefWindowProc(WM_NCACTIVATE, bActive, 0L);
  1135. }
  1136. #endif // _WIN32_WCE
  1137.  
  1138. void CFrameWnd::OnSysCommand(UINT nID, LONG lParam)
  1139. {
  1140.     CFrameWnd* pFrameWnd = GetTopLevelFrame();
  1141.     ASSERT_VALID(pFrameWnd);
  1142.  
  1143.     // set status bar as appropriate
  1144.     UINT nItemID = (nID & 0xFFF0);
  1145.  
  1146.     // don't interfere with system commands if not in help mode
  1147. #if !defined(_WIN32_WCE)
  1148.     if (pFrameWnd->m_bHelpMode)
  1149.     {
  1150.         switch (nItemID)
  1151.         {
  1152.         case SC_SIZE:
  1153.         case SC_MOVE:
  1154.         case SC_MINIMIZE:
  1155.         case SC_MAXIMIZE:
  1156.         case SC_NEXTWINDOW:
  1157.         case SC_PREVWINDOW:
  1158.         case SC_CLOSE:
  1159.         case SC_RESTORE:
  1160.         case SC_TASKLIST:
  1161.             if (!SendMessage(WM_COMMANDHELP, 0,
  1162.               HID_BASE_COMMAND+ID_COMMAND_FROM_SC(nItemID)))
  1163.                 SendMessage(WM_COMMAND, ID_DEFAULT_HELP);
  1164.             return;
  1165.         }
  1166.     }
  1167. #endif // _WIN32_WCE
  1168.  
  1169.     // call default functionality
  1170.     CWnd::OnSysCommand(nID, lParam);
  1171. }
  1172.  
  1173. /////////////////////////////////////////////////////////////////////////////
  1174. // default frame processing
  1175.  
  1176. #if !defined(_WIN32_WCE)
  1177. // default drop processing will attempt to open the file
  1178. void CFrameWnd::OnDropFiles(HDROP hDropInfo)
  1179. {
  1180.     SetActiveWindow();      // activate us first !
  1181.     UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
  1182.  
  1183.     CWinApp* pApp = AfxGetApp();
  1184.     ASSERT(pApp != NULL);
  1185.     for (UINT iFile = 0; iFile < nFiles; iFile++)
  1186.     {
  1187.         TCHAR szFileName[_MAX_PATH];
  1188.         ::DragQueryFile(hDropInfo, iFile, szFileName, _MAX_PATH);
  1189.         pApp->OpenDocumentFile(szFileName);
  1190.     }
  1191.     ::DragFinish(hDropInfo);
  1192. }
  1193.  
  1194. // query end session for main frame will attempt to close it all down
  1195. BOOL CFrameWnd::OnQueryEndSession()
  1196. {
  1197.     CWinApp* pApp = AfxGetApp();
  1198.     if (pApp != NULL && pApp->m_pMainWnd == this)
  1199.         return pApp->SaveAllModified();
  1200.  
  1201.     return TRUE;
  1202. }
  1203.  
  1204. // when Windows session ends, close all documents
  1205. void CFrameWnd::OnEndSession(BOOL bEnding)
  1206. {
  1207.     if (!bEnding)
  1208.         return;
  1209.  
  1210.     CWinApp* pApp = AfxGetApp();
  1211.     if (pApp != NULL && pApp->m_pMainWnd == this)
  1212.     {
  1213.         AfxOleSetUserCtrl(TRUE);    // keeps from randomly shutting down
  1214.         pApp->CloseAllDocuments(TRUE);
  1215.  
  1216.         // allow application to save settings, etc.
  1217.         pApp->ExitInstance();
  1218.     }
  1219. }
  1220. #endif // _WIN32_WCE
  1221.  
  1222. #if !defined(_WIN32_WCE)
  1223. /////////////////////////////////////////////////////////////////////////////
  1224. // Support for Shell DDE Execute messages
  1225.  
  1226. LRESULT CFrameWnd::OnDDEInitiate(WPARAM wParam, LPARAM lParam)
  1227. {
  1228.     CWinApp* pApp = AfxGetApp();
  1229.     if (pApp != NULL && 
  1230.         LOWORD(lParam) != 0 && HIWORD(lParam) != 0 &&
  1231.         (ATOM)LOWORD(lParam) == pApp->m_atomApp &&
  1232.         (ATOM)HIWORD(lParam) == pApp->m_atomSystemTopic)
  1233.     {
  1234.         // make duplicates of the incoming atoms (really adding a reference)
  1235.         TCHAR szAtomName[_MAX_PATH];
  1236.         VERIFY(GlobalGetAtomName(pApp->m_atomApp,
  1237.             szAtomName, _MAX_PATH - 1) != 0);
  1238.         VERIFY(GlobalAddAtom(szAtomName) == pApp->m_atomApp);
  1239.         VERIFY(GlobalGetAtomName(pApp->m_atomSystemTopic,
  1240.             szAtomName, _MAX_PATH - 1) != 0);
  1241.         VERIFY(GlobalAddAtom(szAtomName) == pApp->m_atomSystemTopic);
  1242.  
  1243.         // send the WM_DDE_ACK (caller will delete duplicate atoms)
  1244.         ::SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hWnd,
  1245.             MAKELPARAM(pApp->m_atomApp, pApp->m_atomSystemTopic));
  1246.     }
  1247.     return 0L;
  1248. }
  1249.  
  1250. // always ACK the execute command - even if we do nothing
  1251. LRESULT CFrameWnd::OnDDEExecute(WPARAM wParam, LPARAM lParam)
  1252. {
  1253.     // unpack the DDE message
  1254.     UINT unused;
  1255.     HGLOBAL hData;
  1256.     VERIFY(UnpackDDElParam(WM_DDE_EXECUTE, lParam, &unused, (UINT*)&hData));
  1257.  
  1258.     // get the command string
  1259.     TCHAR szCommand[_MAX_PATH * 2];
  1260.     LPCTSTR lpsz = (LPCTSTR)GlobalLock(hData);
  1261.     lstrcpyn(szCommand, lpsz, _countof(szCommand));
  1262.     GlobalUnlock(hData);
  1263.  
  1264.     // acknowledge now - before attempting to execute
  1265.     ::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hWnd,
  1266.         ReuseDDElParam(lParam, WM_DDE_EXECUTE, WM_DDE_ACK,
  1267.         (UINT)0x8000, (UINT)hData));
  1268.  
  1269.     // don't execute the command when the window is disabled
  1270.     if (!IsWindowEnabled())
  1271.     {
  1272.         TRACE1("Warning: DDE command '%s' ignored because window is disabled.\n",
  1273.             szCommand);
  1274.         return 0;
  1275.     }
  1276.  
  1277.     // execute the command
  1278.     if (!AfxGetApp()->OnDDECommand(szCommand))
  1279.         TRACE1("Error: failed to execute DDE command '%s'.\n", szCommand);
  1280.  
  1281.     return 0L;
  1282. }
  1283.  
  1284. LRESULT CFrameWnd::OnDDETerminate(WPARAM wParam, LPARAM lParam)
  1285. {
  1286.     ::PostMessage((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)m_hWnd, lParam);
  1287.     return 0L;
  1288. }
  1289. #endif // _WIN32_WCE
  1290.  
  1291. /////////////////////////////////////////////////////////////////////////////
  1292. // CFrameWnd attributes
  1293.  
  1294. CView* CFrameWnd::GetActiveView() const
  1295. {
  1296.     ASSERT(m_pViewActive == NULL ||
  1297.         m_pViewActive->IsKindOf(RUNTIME_CLASS(CView)));
  1298.     return m_pViewActive;
  1299. }
  1300.  
  1301. void CFrameWnd::SetActiveView(CView* pViewNew, BOOL bNotify)
  1302. {
  1303. #ifdef _DEBUG
  1304.     if (pViewNew != NULL)
  1305.     {
  1306.         ASSERT(IsChild(pViewNew));
  1307.         ASSERT_KINDOF(CView, pViewNew);
  1308.     }
  1309. #endif //_DEBUG
  1310.  
  1311.     CView* pViewOld = m_pViewActive;
  1312.     if (pViewNew == pViewOld)
  1313.         return;     // do not re-activate if SetActiveView called more than once
  1314.  
  1315.     m_pViewActive = NULL;   // no active for the following processing
  1316.  
  1317.     // deactivate the old one
  1318.     if (pViewOld != NULL)
  1319.         pViewOld->OnActivateView(FALSE, pViewNew, pViewOld);
  1320.  
  1321.     // if the OnActivateView moves the active window,
  1322.     //    that will veto this change
  1323.     if (m_pViewActive != NULL)
  1324.         return;     // already set
  1325.     m_pViewActive = pViewNew;
  1326.  
  1327.     // activate
  1328.     if (pViewNew != NULL && bNotify)
  1329.         pViewNew->OnActivateView(TRUE, pViewNew, pViewOld);
  1330. }
  1331.  
  1332. /////////////////////////////////////////////////////////////////////////////
  1333. // Special view swapping/activation
  1334.  
  1335. void CFrameWnd::OnSetFocus(CWnd* pOldWnd)
  1336. {
  1337.     if (m_pViewActive != NULL)
  1338.         m_pViewActive->SetFocus();
  1339.     else
  1340.         CWnd::OnSetFocus(pOldWnd);
  1341. }
  1342.  
  1343. CDocument* CFrameWnd::GetActiveDocument()
  1344. {
  1345.     ASSERT_VALID(this);
  1346.     CView* pView = GetActiveView();
  1347.     if (pView != NULL)
  1348.         return pView->GetDocument();
  1349.     return NULL;
  1350. }
  1351.  
  1352. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  1353. void CFrameWnd::ShowControlBar(CControlBar* pBar, BOOL bShow, BOOL bDelay)
  1354. {
  1355.     ASSERT(pBar != NULL);
  1356.     CFrameWnd* pParentFrame = pBar->GetDockingFrame();
  1357.     ASSERT(pParentFrame->GetTopLevelParent() == GetTopLevelParent());
  1358.         // parent frame of bar must be related
  1359.  
  1360.     if (bDelay)
  1361.     {
  1362.         pBar->DelayShow(bShow);
  1363.         pParentFrame->DelayRecalcLayout();
  1364.     }
  1365.     else
  1366.     {
  1367.         pBar->SetWindowPos(NULL, 0, 0, 0, 0,
  1368.             SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
  1369.             (bShow ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
  1370.         // call DelayShow to clear any contradictory DelayShow
  1371.         pBar->DelayShow(bShow);
  1372.         if (bShow || !pBar->IsFloating())
  1373.             pParentFrame->RecalcLayout(FALSE);
  1374.     }
  1375.  
  1376. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  1377.     // show or hide the floating frame as appropriate
  1378.     if (pBar->IsFloating())
  1379.     {
  1380.         int nVisCount = pBar->m_pDockBar != NULL ?
  1381.             pBar->m_pDockBar->GetDockedVisibleCount() : bShow ? 1 : 0;
  1382.         if (nVisCount == 1 && bShow)
  1383.         {
  1384.             pParentFrame->m_nShowDelay = -1;
  1385.             if (bDelay)
  1386.             {
  1387.                 pParentFrame->m_nShowDelay = SW_SHOWNA;
  1388.                 pParentFrame->RecalcLayout(FALSE);
  1389.             }
  1390.             else
  1391.                 pParentFrame->ShowWindow(SW_SHOWNA);
  1392.         }
  1393.         else if (nVisCount == 0)
  1394.         {
  1395.             ASSERT(!bShow);
  1396.             pParentFrame->m_nShowDelay = -1;
  1397.             if (bDelay)
  1398.                 pParentFrame->m_nShowDelay = SW_HIDE;
  1399.             else
  1400.                 pParentFrame->ShowWindow(SW_HIDE);
  1401.         }
  1402.         else if (!bDelay)
  1403.         {
  1404.             pParentFrame->RecalcLayout(FALSE);
  1405.         }
  1406.     }
  1407. #endif // _WIN32_WCE_NO_DOCKBARS
  1408. }
  1409. #endif // _WIN32_WCE_NO_CONTROLBARS
  1410.  
  1411. /////////////////////////////////////////////////////////////////////////////
  1412. // Command prompts
  1413.  
  1414. #if !defined(_WIN32_WCE)
  1415. void CFrameWnd::OnInitMenu(CMenu* pMenu)
  1416. {
  1417. #ifndef _AFX_NO_OLE_SUPPORT
  1418.     // allow hook to consume message
  1419.     if (m_pNotifyHook != NULL)
  1420.     {
  1421. #ifdef _AFXDLL
  1422.         ASSERT(m_pModuleState != NULL);
  1423.         if (m_pModuleState->m_dwVersion >= 0x423)
  1424. #endif
  1425.             m_pNotifyHook->OnInitMenu(pMenu);
  1426. #endif
  1427.     }
  1428.  
  1429.     Default();
  1430. }
  1431. #endif // _WIN32_WCE
  1432.  
  1433. void CFrameWnd::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)
  1434. {
  1435.     AfxCancelModes(m_hWnd);
  1436.  
  1437.     if (bSysMenu)
  1438.         return;     // don't support system menu
  1439.  
  1440. #if !defined(_WIN32_WCE)
  1441. #ifndef _AFX_NO_OLE_SUPPORT
  1442.     // allow hook to consume message
  1443.     if (m_pNotifyHook != NULL)
  1444.     {
  1445. #ifdef _AFXDLL
  1446.         ASSERT(m_pModuleState != NULL);
  1447.         if (m_pModuleState->m_dwVersion >= 0x423)
  1448. #endif
  1449.             if (m_pNotifyHook->OnInitMenuPopup(pMenu, nIndex, bSysMenu))
  1450.                 return;
  1451.     }
  1452. #endif
  1453. #endif // _WIN32_WCE
  1454.  
  1455.     ASSERT(pMenu != NULL);
  1456.     // check the enabled state of various menu items
  1457.  
  1458.     CCmdUI state;
  1459.     state.m_pMenu = pMenu;
  1460.     ASSERT(state.m_pOther == NULL);
  1461.     ASSERT(state.m_pParentMenu == NULL);
  1462.  
  1463.     // determine if menu is popup in top-level menu and set m_pOther to
  1464.     //  it if so (m_pParentMenu == NULL indicates that it is secondary popup)
  1465.     HMENU hParentMenu;
  1466.     if (AfxGetThreadState()->m_hTrackingMenu == pMenu->m_hMenu)
  1467.         state.m_pParentMenu = pMenu;    // parent == child for tracking popup
  1468.     else if ((hParentMenu = ::WCE_FCTN(GetMenu)(m_hWnd)) != NULL)
  1469.     {
  1470.         CWnd* pParent = GetTopLevelParent();
  1471.             // child windows don't have menus -- need to go to the top!
  1472.         if (pParent != NULL &&
  1473.             (hParentMenu = ::WCE_FCTN(GetMenu)(pParent->m_hWnd)) != NULL)
  1474.         {
  1475.             int nIndexMax = ::WCE_FCTN(GetMenuItemCount)(hParentMenu);
  1476.             for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
  1477.             {
  1478.                 if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
  1479.                 {
  1480.                     // when popup is found, m_pParentMenu is containing menu
  1481.                     state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
  1482.                     break;
  1483.                 }
  1484.             }
  1485.         }
  1486.     }
  1487.  
  1488.     state.m_nIndexMax = pMenu->GetMenuItemCount();
  1489.     for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  1490.       state.m_nIndex++)
  1491.     {
  1492.         state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
  1493.         if (state.m_nID == 0)
  1494.             continue; // menu separator or invalid cmd - ignore it
  1495.  
  1496.         ASSERT(state.m_pOther == NULL);
  1497.         ASSERT(state.m_pMenu != NULL);
  1498.         if (state.m_nID == (UINT)-1)
  1499.         {
  1500.             // possibly a popup menu, route to first item of that popup
  1501.             state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
  1502.             if (state.m_pSubMenu == NULL ||
  1503.                 (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
  1504.                 state.m_nID == (UINT)-1)
  1505.             {
  1506.                 continue;       // first item of popup can't be routed to
  1507.             }
  1508.             state.DoUpdate(this, FALSE);    // popups are never auto disabled
  1509.         }
  1510.         else
  1511.         {
  1512.             // normal menu item
  1513.             // Auto enable/disable if frame window has 'm_bAutoMenuEnable'
  1514.             //    set and command is _not_ a system command.
  1515.             state.m_pSubMenu = NULL;
  1516.             state.DoUpdate(this, m_bAutoMenuEnable && state.m_nID < 0xF000);
  1517.         }
  1518.  
  1519.         // adjust for menu deletions and additions
  1520.         UINT nCount = pMenu->GetMenuItemCount();
  1521.         if (nCount < state.m_nIndexMax)
  1522.         {
  1523.             state.m_nIndex -= (state.m_nIndexMax - nCount);
  1524.             while (state.m_nIndex < nCount &&
  1525.                 pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
  1526.             {
  1527.                 state.m_nIndex++;
  1528.             }
  1529.         }
  1530.         state.m_nIndexMax = nCount;
  1531.     }
  1532. }
  1533.  
  1534. #if !defined(_WIN32_WCE)
  1535. void CFrameWnd::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
  1536. {
  1537.     CFrameWnd* pFrameWnd = GetTopLevelFrame();
  1538.     ASSERT_VALID(pFrameWnd);
  1539.  
  1540. #ifndef _AFX_NO_OLE_SUPPORT
  1541.     // allow hook to consume message
  1542.     if (m_pNotifyHook != NULL)
  1543.     {
  1544. #ifdef _AFXDLL
  1545.         ASSERT(m_pModuleState != NULL);
  1546.         if (m_pModuleState->m_dwVersion >= 0x423)
  1547. #endif
  1548.             if (m_pNotifyHook->OnMenuSelect(nItemID, nFlags, hSysMenu))
  1549.                 return;
  1550.     }
  1551. #endif
  1552.  
  1553.     // set the tracking state (update on idle)
  1554.     if (nFlags == 0xFFFF)
  1555.     {
  1556.         // cancel menu operation (go back to idle now)
  1557.         m_nFlags &= ~WF_NOPOPMSG;
  1558.         if (!pFrameWnd->m_bHelpMode)
  1559.             m_nIDTracking = AFX_IDS_IDLEMESSAGE;
  1560.         else
  1561.             m_nIDTracking = AFX_IDS_HELPMODEMESSAGE;
  1562.         SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
  1563.         ASSERT(m_nIDTracking == m_nIDLastMessage);
  1564.  
  1565.         // update right away
  1566.         CWnd* pWnd = GetMessageBar();
  1567.         if (pWnd != NULL)
  1568.             pWnd->UpdateWindow();
  1569.     }
  1570.     else
  1571.     {
  1572.         if (nItemID == 0 || nFlags & (MF_SEPARATOR|MF_POPUP))
  1573.         {
  1574.             // nothing should be displayed
  1575.             m_nIDTracking = 0;
  1576.         }
  1577.         else if (nItemID >= 0xF000 && nItemID < 0xF1F0) // max of 31 SC_s
  1578.         {
  1579.             // special strings table entries for system commands
  1580.             m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
  1581.             ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
  1582.                 m_nIDTracking < AFX_IDS_SCFIRST + 31);
  1583.         }
  1584.         else if (nItemID >= AFX_IDM_FIRST_MDICHILD)
  1585.         {
  1586.             // all MDI Child windows map to the same help id
  1587.             m_nIDTracking = AFX_IDS_MDICHILD;
  1588.         }
  1589.         else
  1590.         {
  1591.             // track on idle
  1592.             m_nIDTracking = nItemID;
  1593.         }
  1594.         pFrameWnd->m_nFlags |= WF_NOPOPMSG;
  1595.     }
  1596.  
  1597.     // when running in-place, it is necessary to cause a message to
  1598.     //  be pumped through the queue.
  1599.     if (m_nIDTracking != m_nIDLastMessage && GetParent() != NULL)
  1600.         PostMessage(WM_KICKIDLE);
  1601. }
  1602. #endif // _WIN32_WCE
  1603.  
  1604. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  1605. void CFrameWnd::GetMessageString(UINT nID, CString& rMessage) const
  1606. {
  1607.     // load appropriate string
  1608.     LPTSTR lpsz = rMessage.GetBuffer(255);
  1609.     if (AfxLoadString(nID, lpsz) != 0)
  1610.     {
  1611.         // first newline terminates actual string
  1612.         lpsz = _tcschr(lpsz, '\n');
  1613.         if (lpsz != NULL)
  1614.             *lpsz = '\0';
  1615.     }
  1616.     else
  1617.     {
  1618.         // not found
  1619.         TRACE1("Warning: no message line prompt for ID 0x%04X.\n", nID);
  1620.     }
  1621.     rMessage.ReleaseBuffer();
  1622. }
  1623.  
  1624. LRESULT CFrameWnd::OnPopMessageString(WPARAM wParam, LPARAM lParam)
  1625. {
  1626.     if (m_nFlags & WF_NOPOPMSG)
  1627.         return 0;
  1628.  
  1629.     return SendMessage(WM_SETMESSAGESTRING, wParam, lParam);
  1630. }
  1631.  
  1632. LRESULT CFrameWnd::OnSetMessageString(WPARAM wParam, LPARAM lParam)
  1633. {
  1634.     UINT nIDLast = m_nIDLastMessage;
  1635.     m_nFlags &= ~WF_NOPOPMSG;
  1636.  
  1637.     CWnd* pMessageBar = GetMessageBar();
  1638.     if (pMessageBar != NULL)
  1639.     {
  1640.         LPCTSTR lpsz = NULL;
  1641.         CString strMessage;
  1642.  
  1643.         // set the message bar text
  1644.         if (lParam != 0)
  1645.         {
  1646.             ASSERT(wParam == 0);    // can't have both an ID and a string
  1647.             lpsz = (LPCTSTR)lParam; // set an explicit string
  1648.         }
  1649.         else if (wParam != 0)
  1650.         {
  1651.             // map SC_CLOSE to PREVIEW_CLOSE when in print preview mode
  1652.             if (wParam == AFX_IDS_SCCLOSE && m_lpfnCloseProc != NULL)
  1653.                 wParam = AFX_IDS_PREVIEW_CLOSE;
  1654.  
  1655.             // get message associated with the ID indicated by wParam
  1656.             GetMessageString(wParam, strMessage);
  1657.             lpsz = strMessage;
  1658.         }
  1659.         pMessageBar->SetWindowText(lpsz);
  1660.  
  1661.         // update owner of the bar in terms of last message selected
  1662.         CFrameWnd* pFrameWnd = pMessageBar->GetParentFrame();
  1663.         if (pFrameWnd != NULL)
  1664.         {
  1665.             pFrameWnd->m_nIDLastMessage = (UINT)wParam;
  1666.             pFrameWnd->m_nIDTracking = (UINT)wParam;
  1667.         }
  1668.     }
  1669.  
  1670.     m_nIDLastMessage = (UINT)wParam;    // new ID (or 0)
  1671.     m_nIDTracking = (UINT)wParam;       // so F1 on toolbar buttons work
  1672.     return nIDLast;
  1673. }
  1674.  
  1675. LRESULT CFrameWnd::OnHelpPromptAddr(WPARAM, LPARAM)
  1676. {
  1677.     return (LRESULT)&m_dwPromptContext;
  1678. }
  1679.  
  1680. CWnd* CFrameWnd::GetMessageBar()
  1681. {
  1682.     return GetDescendantWindow(AFX_IDW_STATUS_BAR, TRUE);
  1683. }
  1684.  
  1685. #if !defined(_WIN32_WCE)
  1686. void CFrameWnd::OnEnterIdle(UINT nWhy, CWnd* pWho)
  1687. {
  1688.     CWnd::OnEnterIdle(nWhy, pWho);
  1689.  
  1690.     if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
  1691.         return;
  1692.  
  1693.     SetMessageText(m_nIDTracking);
  1694.     ASSERT(m_nIDTracking == m_nIDLastMessage);
  1695. }
  1696. #endif // _WIN32_WCE
  1697.  
  1698. void CFrameWnd::SetMessageText(LPCTSTR lpszText)
  1699. {
  1700.     SendMessage(WM_SETMESSAGESTRING, 0, (LPARAM)lpszText);
  1701. }
  1702.  
  1703. void CFrameWnd::SetMessageText(UINT nID)
  1704. {
  1705.     SendMessage(WM_SETMESSAGESTRING, (WPARAM)nID);
  1706. }
  1707.  
  1708. /////////////////////////////////////////////////////////////////////////////
  1709. // CFrameWnd standard control bar management
  1710.  
  1711. #if defined(_WIN32_WCE_NO_DOCKBARS)
  1712. void CFrameWnd::DestroyDockBars()
  1713. {
  1714.     POSITION pos = m_listControlBars.GetHeadPosition();
  1715.     while (pos != NULL)
  1716.     {
  1717.         CControlBar* pControlBar = (CControlBar*)m_listControlBars.GetNext(pos);
  1718.         ASSERT(pControlBar != NULL);
  1719.         pControlBar->DestroyWindow();
  1720.     }
  1721. }
  1722. #else // _WIN32_WCE_NO_DOCKBARS
  1723. void CFrameWnd::DestroyDockBars()
  1724. {
  1725.     // create a list of all the dock bars
  1726.     // this is necessary because m_listControlBars will change
  1727.     // as the dock bars and floating frames are destroyed
  1728.     CPtrList listDockBars;
  1729.     POSITION pos = m_listControlBars.GetHeadPosition();
  1730.     while (pos != NULL)
  1731.     {
  1732.         DockBar* pDockBar = (CDockBar*)m_listControlBars.GetNext(pos);
  1733.         ASSERT(pDockBar != NULL);
  1734.         if (pDockBar->IsDockBar())
  1735.             listDockBars.AddTail(pDockBar);
  1736.     }
  1737.     pos = listDockBars.GetHeadPosition();
  1738.     while (pos != NULL)
  1739.     {
  1740.         CDockBar* pDockBar = (CDockBar*)listDockBars.GetNext(pos);
  1741.         if (pDockBar->m_bFloating)
  1742.         {
  1743.             CFrameWnd* pFrameWnd = pDockBar->GetParentFrame();
  1744.             ASSERT_VALID(pFrameWnd);
  1745.             pFrameWnd->DestroyWindow();
  1746.         }
  1747.         else
  1748.             pDockBar->DestroyWindow();
  1749.     }
  1750. }
  1751. #endif // _WIN32_WCE_NO_DOCKBARS
  1752.  
  1753. CControlBar* CFrameWnd::GetControlBar(UINT nID)
  1754. {
  1755.     if (nID == 0)
  1756.         return NULL;
  1757.     POSITION pos = m_listControlBars.GetHeadPosition();
  1758.     while (pos != NULL)
  1759.     {
  1760.         CControlBar* pBar = (CControlBar*)m_listControlBars.GetNext(pos);
  1761.         ASSERT(pBar != NULL);
  1762.         if (_AfxGetDlgCtrlID(pBar->m_hWnd) == nID)
  1763.         {
  1764.             ASSERT_KINDOF(CControlBar, pBar);
  1765.             return pBar;
  1766.         }
  1767.     }
  1768.     return NULL;
  1769. }
  1770.  
  1771. void CFrameWnd::OnUpdateControlBarMenu(CCmdUI* pCmdUI)
  1772. {
  1773.     ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);
  1774.     ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);
  1775.     ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR);
  1776.  
  1777.     CControlBar* pBar = GetControlBar(pCmdUI->m_nID);
  1778.     if (pBar != NULL)
  1779.     {
  1780.         pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0);
  1781.         return;
  1782.     }
  1783.     pCmdUI->ContinueRouting();
  1784. }
  1785.  
  1786. BOOL CFrameWnd::OnBarCheck(UINT nID)
  1787. {
  1788.     ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);
  1789.     ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);
  1790.     ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR);
  1791.  
  1792.     CControlBar* pBar = GetControlBar(nID);
  1793.     if (pBar != NULL)
  1794.     {
  1795.         ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE);
  1796.         return TRUE;
  1797.     }
  1798.     return FALSE;
  1799. }
  1800.  
  1801. #if !defined(_WIN32_WCE_NO_TOOLTIPS)
  1802. BOOL CFrameWnd::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
  1803. {
  1804.     ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
  1805.  
  1806.     // need to handle both ANSI and UNICODE versions of the message
  1807.     TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  1808.     TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  1809.     TCHAR szFullText[256];
  1810.     CString strTipText;
  1811.     UINT nID = pNMHDR->idFrom;
  1812.     if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
  1813.         pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
  1814.     {
  1815.         // idFrom is actually the HWND of the tool
  1816.         nID = _AfxGetDlgCtrlID((HWND)nID);
  1817.     }
  1818.  
  1819.     if (nID != 0) // will be zero on a separator
  1820.     {
  1821.         // don't handle the message if no string resource found
  1822.         if (AfxLoadString(nID, szFullText) == 0)
  1823.             return FALSE;
  1824.  
  1825.         // this is the command id, not the button index
  1826.         AfxExtractSubString(strTipText, szFullText, 1, '\n');
  1827.     }
  1828. #ifndef _UNICODE
  1829.     if (pNMHDR->code == TTN_NEEDTEXTA)
  1830.         lstrcpyn(pTTTA->szText, strTipText, _countof(pTTTA->szText));
  1831.     else
  1832.         _mbstowcsz(pTTTW->szText, strTipText, _countof(pTTTW->szText));
  1833. #else
  1834.     if (pNMHDR->code == TTN_NEEDTEXTA)
  1835.         _wcstombsz(pTTTA->szText, strTipText, _countof(pTTTA->szText));
  1836.     else
  1837.         lstrcpyn(pTTTW->szText, strTipText, _countof(pTTTW->szText));
  1838. #endif
  1839.     *pResult = 0;
  1840.  
  1841.     // bring the tooltip window above other popup windows
  1842.     ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
  1843.         SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
  1844.  
  1845.     return TRUE;    // message was handled
  1846. }
  1847. #endif // _WIN32_WCE_NO_TOOLTIPS
  1848.  
  1849.  
  1850. /////////////////////////////////////////////////////////////////////////////
  1851. // Support for standard status bar
  1852.  
  1853. void CFrameWnd::OnUpdateKeyIndicator(CCmdUI* pCmdUI)
  1854. {
  1855.     UINT nVK;
  1856.     UINT flag = 0x0001;
  1857.  
  1858.     switch (pCmdUI->m_nID)
  1859.     {
  1860.     case ID_INDICATOR_CAPS:
  1861.         nVK = VK_CAPITAL;
  1862.         break;
  1863.  
  1864.     case ID_INDICATOR_NUM:
  1865.         nVK = VK_NUMLOCK;
  1866.         break;
  1867.  
  1868.     case ID_INDICATOR_SCRL:
  1869.         nVK = VK_SCROLL;
  1870.         break;
  1871.  
  1872.     case ID_INDICATOR_KANA:
  1873.         nVK = VK_KANA;
  1874.         // WINBUG: Special case for Windows 3.x.  The wrong bit was toggled
  1875.         // in those systems so this must be special cased.  This is fixed
  1876.         // on systems whose version is 4.x or greater.
  1877.         if (!afxData.bWin4)
  1878.             flag = 0x8000;
  1879.         break;
  1880.  
  1881.     default:
  1882.         TRACE1("Warning: OnUpdateKeyIndicator - unknown indicator 0x%04X.\n",
  1883.             pCmdUI->m_nID);
  1884.         pCmdUI->ContinueRouting();
  1885.         return; // not for us
  1886.     }
  1887.  
  1888.     pCmdUI->Enable(::GetKeyState(nVK) & flag);
  1889.         // enable static text based on toggled key state
  1890.     ASSERT(pCmdUI->m_bEnableChanged);
  1891. }
  1892. #endif // _WIN32_WCE_NO_CONTROLBARS
  1893.  
  1894.  
  1895. #if !defined(_WIN32_WCE)
  1896. void CFrameWnd::OnUpdateContextHelp(CCmdUI* pCmdUI)
  1897. {
  1898.     if (AfxGetMainWnd() == this)
  1899.         pCmdUI->SetCheck(!!m_bHelpMode);
  1900.     else
  1901.         pCmdUI->ContinueRouting();
  1902. }
  1903. #endif // _WIN32_WCE
  1904.  
  1905. /////////////////////////////////////////////////////////////////////////////
  1906. // Setting title of frame window - UISG standard
  1907.  
  1908. void CFrameWnd::OnUpdateFrameTitle(BOOL bAddToTitle)
  1909. {
  1910.     if ((GetStyle() & FWS_ADDTOTITLE) == 0)
  1911.         return;     // leave it alone!
  1912.  
  1913. #if !defined(_WIN32_WCE)
  1914. #ifndef _AFX_NO_OLE_SUPPORT
  1915.     // allow hook to set the title (used for OLE support)
  1916.     if (m_pNotifyHook != NULL && m_pNotifyHook->OnUpdateFrameTitle())
  1917.         return;
  1918. #endif
  1919. #endif // _WIN32_WCE
  1920.  
  1921.     CDocument* pDocument = GetActiveDocument();
  1922.     if (bAddToTitle && pDocument != NULL)
  1923.         UpdateFrameTitleForDocument(pDocument->GetTitle());
  1924.     else
  1925.         UpdateFrameTitleForDocument(NULL);
  1926. }
  1927.  
  1928. void CFrameWnd::UpdateFrameTitleForDocument(LPCTSTR lpszDocName)
  1929. {
  1930.     // copy first part of title loaded at time of frame creation
  1931.     TCHAR szText[256+_MAX_PATH];
  1932.  
  1933.     if (GetStyle() & FWS_PREFIXTITLE)
  1934.     {
  1935.         szText[0] = '\0';   // start with nothing
  1936.  
  1937.         // get name of currently active view
  1938.         if (lpszDocName != NULL)
  1939.         {
  1940.             lstrcpy(szText, lpszDocName);
  1941.             // add current window # if needed
  1942.             if (m_nWindow > 0)
  1943.                 wsprintf(szText + lstrlen(szText), _T(":%d"), m_nWindow);
  1944.             lstrcat(szText, _T(" - "));
  1945.         }
  1946.         lstrcat(szText, m_strTitle);
  1947.     }
  1948.     else
  1949.     {
  1950.         // get name of currently active view
  1951.         lstrcpy(szText, m_strTitle);
  1952.         if (lpszDocName != NULL)
  1953.         {
  1954.             lstrcat(szText, _T(" - "));
  1955.             lstrcat(szText, lpszDocName);
  1956.             // add current window # if needed
  1957.             if (m_nWindow > 0)
  1958.                 wsprintf(szText + lstrlen(szText), _T(":%d"), m_nWindow);
  1959.         }
  1960.     }
  1961.  
  1962.     // set title if changed, but don't remove completely
  1963.     // Note: will be excessive for MDI Frame with maximized child
  1964.     AfxSetWindowText(m_hWnd, szText);
  1965. }
  1966.  
  1967. /////////////////////////////////////////////////////////////////////////////
  1968.  
  1969. #if !defined(_WIN32_WCE)
  1970. void CFrameWnd::OnSetPreviewMode(BOOL bPreview, CPrintPreviewState* pState)
  1971. {
  1972.     // default implementation changes control bars, menu and main pane window
  1973.  
  1974. #ifndef _AFX_NO_OLE_SUPPORT
  1975.     CFrameWnd* pActiveFrame = GetActiveFrame();
  1976.     ASSERT_VALID(pActiveFrame);
  1977.     if (bPreview && pActiveFrame->m_pNotifyHook != NULL)
  1978.         pActiveFrame->m_pNotifyHook->OnDocActivate(FALSE);
  1979. #endif
  1980.  
  1981.     // Set visibility of standard ControlBars (only the first 32)
  1982.     DWORD dwOldStates = 0;
  1983.     POSITION pos = m_listControlBars.GetHeadPosition();
  1984.     while (pos != NULL)
  1985.     {
  1986.         CControlBar* pBar = (CControlBar*)m_listControlBars.GetNext(pos);
  1987.         ASSERT_VALID(pBar);
  1988.         UINT nID = _AfxGetDlgCtrlID(pBar->m_hWnd);
  1989.         if (nID >= AFX_IDW_CONTROLBAR_FIRST && nID <= AFX_IDW_CONTROLBAR_FIRST+31)
  1990.         {
  1991.             DWORD dwMask = 1L << (nID - AFX_IDW_CONTROLBAR_FIRST);
  1992.             if (pBar->IsVisible())
  1993.                 dwOldStates |= dwMask;      // save if previously visible
  1994.             if (!pBar->IsDockBar() || nID != AFX_IDW_DOCKBAR_FLOAT)
  1995.                 ShowControlBar(pBar, (pState->dwStates & dwMask), TRUE);
  1996.         }
  1997.     }
  1998.     pState->dwStates = dwOldStates; // save for restore
  1999.  
  2000.     if (bPreview)
  2001.     {
  2002.         // Entering Print Preview
  2003.         ASSERT(m_lpfnCloseProc == NULL);    // no chaining
  2004.         m_lpfnCloseProc = pState->lpfnCloseProc;
  2005.  
  2006.         // show any modeless dialogs, popup windows, float tools, etc
  2007.         ShowOwnedWindows(FALSE);
  2008.  
  2009.         // Hide the main pane
  2010.         HWND hWnd = ::GetDlgItem(m_hWnd, pState->nIDMainPane);
  2011.         ASSERT(hWnd != NULL);       // must be one that we are hiding!
  2012.         ::ShowWindow(hWnd, SW_HIDE);
  2013.  
  2014.         // Get rid of the menu first (will resize the window)
  2015.         pState->hMenu = ::GetMenu(m_hWnd);
  2016.         if (pState->hMenu != NULL)
  2017.         {
  2018.             // Invalidate before SetMenu since we are going to replace
  2019.             //  the frame's client area anyway
  2020.             Invalidate();
  2021.             SetMenu(NULL);
  2022.             m_nIdleFlags &= ~idleMenu;  // avoid any idle menu processing
  2023.         }
  2024.  
  2025.         // Save the accelerator table and remove it.
  2026.         pState->hAccelTable = m_hAccelTable;
  2027.         m_hAccelTable = NULL;
  2028.         LoadAccelTable(MAKEINTRESOURCE(AFX_IDR_PREVIEW_ACCEL));
  2029.  
  2030.         // Make room for the PreviewView by changing AFX_IDW_PANE_FIRST's ID
  2031.         //  to AFX_IDW_PREVIEW_FIRST
  2032.         if (pState->nIDMainPane != AFX_IDW_PANE_FIRST)
  2033.             hWnd = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_FIRST);
  2034.         if (hWnd != NULL)
  2035.             _AfxSetDlgCtrlID(hWnd, AFX_IDW_PANE_SAVE);
  2036.  
  2037. #ifdef _DEBUG
  2038.         if ((::GetWindowLong(m_hWnd, GWL_STYLE) & (WS_HSCROLL|WS_VSCROLL)) != 0)
  2039.             TRACE0("Warning: scroll bars in frame windows may cause unusual behaviour.\n");
  2040. #endif
  2041.     }
  2042.     else
  2043.     {
  2044.         // Leaving Preview
  2045.         m_lpfnCloseProc = NULL;
  2046.  
  2047.         // shift original AFX_IDW_PANE_FIRST back to its rightful ID
  2048.         HWND hWnd = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_SAVE);
  2049.         if (hWnd != NULL)
  2050.         {
  2051.             HWND hWndTemp = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_FIRST);
  2052.             if (hWndTemp != NULL)
  2053.                 _AfxSetDlgCtrlID(hWndTemp, AFX_IDW_PANE_SAVE);
  2054.             _AfxSetDlgCtrlID(hWnd, AFX_IDW_PANE_FIRST);
  2055.         }
  2056.  
  2057.         // put the menu back in place if it was removed before
  2058.         if (pState->hMenu != NULL)
  2059.         {
  2060.             // Invalidate before SetMenu since we are going to replace
  2061.             //  the frame's client area anyway
  2062.             Invalidate();
  2063.             ::SetMenu(m_hWnd, pState->hMenu);
  2064.         }
  2065.  
  2066.         // recalc layout now, before showing the main pane
  2067. #ifndef _AFX_NO_OLE_SUPPORT
  2068.         if (pActiveFrame->m_pNotifyHook != NULL)
  2069.             pActiveFrame->m_pNotifyHook->OnDocActivate(TRUE);
  2070. #endif
  2071.         RecalcLayout();
  2072.  
  2073.         // now show main pane that was hidden
  2074.         if (pState->nIDMainPane != AFX_IDW_PANE_FIRST)
  2075.             hWnd = ::GetDlgItem(m_hWnd, pState->nIDMainPane);
  2076.         ASSERT(hWnd != NULL);
  2077.         ::ShowWindow(hWnd, SW_SHOW);
  2078.  
  2079.         // Restore the Accelerator table
  2080.         m_hAccelTable = pState->hAccelTable;
  2081.  
  2082.         // show any modeless dialogs, popup windows, float tools, etc
  2083.         ShowOwnedWindows(TRUE);
  2084.     }
  2085. }
  2086. #endif // _WIN32_WCE
  2087.  
  2088. void CFrameWnd::DelayUpdateFrameMenu(HMENU hMenuAlt)
  2089. {
  2090.     m_hMenuAlt = hMenuAlt;
  2091.     m_nIdleFlags |= idleMenu;
  2092. }
  2093.  
  2094. void CFrameWnd::OnIdleUpdateCmdUI()
  2095. {
  2096.     // update menu if necessary
  2097.     if (m_nIdleFlags & idleMenu)
  2098.         OnUpdateFrameMenu(m_hMenuAlt);
  2099.  
  2100.     // update title if necessary
  2101.     if (m_nIdleFlags & idleTitle)
  2102.         OnUpdateFrameTitle(TRUE);
  2103.  
  2104.     // recalc layout if necessary
  2105.     if (m_nIdleFlags & idleLayout)
  2106.     {
  2107.         RecalcLayout(m_nIdleFlags & idleNotify);
  2108.         UpdateWindow();
  2109.     }
  2110.  
  2111. #if !defined(_WIN32_WCE_NO_TOOLTIPS)
  2112.     // set the current message string if necessary
  2113.     if (m_nIDTracking != m_nIDLastMessage)
  2114.     {
  2115.         SetMessageText(m_nIDTracking);
  2116.         ASSERT(m_nIDTracking == m_nIDLastMessage);
  2117.     }
  2118. #endif // _WIN32_WCE_NO_TOOLTIPS
  2119.     m_nIdleFlags = 0;
  2120. }
  2121.  
  2122. CFrameWnd* CFrameWnd::GetActiveFrame()
  2123. {
  2124.     // by default, the active frame is the frame itself (MDI is different)
  2125.     return this;
  2126. }
  2127.  
  2128. void CFrameWnd::RecalcLayout(BOOL bNotify)
  2129. {
  2130.     if (m_bInRecalcLayout)
  2131.         return;
  2132.  
  2133.     m_bInRecalcLayout = TRUE;
  2134.     // clear idle flags for recalc layout if called elsewhere
  2135.     if (m_nIdleFlags & idleNotify)
  2136.         bNotify = TRUE;
  2137.     m_nIdleFlags &= ~(idleLayout|idleNotify);
  2138.  
  2139. #if !defined(_WIN32_WCE)
  2140. #ifndef _AFX_NO_OLE_SUPPORT
  2141.     // call the layout hook -- OLE support uses this hook
  2142.     if (bNotify && m_pNotifyHook != NULL)
  2143.         m_pNotifyHook->OnRecalcLayout();
  2144. #endif
  2145. #endif // _WIN32_WCE
  2146.  
  2147.     // reposition all the child windows (regardless of ID)
  2148.     if (GetStyle() & FWS_SNAPTOBARS)
  2149.     {
  2150.         CRect rect(0, 0, 32767, 32767);
  2151.         RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,
  2152.             &rect, &rect, FALSE);
  2153.         RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra,
  2154.             &m_rectBorder, &rect, TRUE);
  2155.         CalcWindowRect(&rect);
  2156.         SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
  2157.             SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
  2158.     }
  2159.     else
  2160.         RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra, &m_rectBorder);
  2161.     m_bInRecalcLayout = FALSE;
  2162. }
  2163.  
  2164. #if !defined(_WIN32_WCE_NO_OLE)
  2165. // CFrameWnd implementation of OLE border space negotiation
  2166. BOOL CFrameWnd::NegotiateBorderSpace(UINT nBorderCmd, LPRECT lpRectBorder)
  2167. {
  2168.     CRect border, request;
  2169.  
  2170.     switch (nBorderCmd)
  2171.     {
  2172.     case borderGet:
  2173.         ASSERT(lpRectBorder != NULL);
  2174.         RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,
  2175.             lpRectBorder);
  2176.         break;
  2177.  
  2178.     case borderRequest:
  2179.         return TRUE;
  2180.  
  2181.     case borderSet:
  2182.         if (lpRectBorder == NULL)
  2183.         {
  2184.             if (!m_rectBorder.IsRectNull())
  2185.             {
  2186.                 // releasing all border space -- recalc needed
  2187.                 m_rectBorder.SetRectEmpty();
  2188.                 return TRUE;
  2189.             }
  2190.             // original rect is empty & lpRectBorder is NULL, no recalc needed
  2191.             return FALSE;
  2192.         }
  2193.         if (!::EqualRect(m_rectBorder, lpRectBorder))
  2194.         {
  2195.             // the rects are different -- recalc needed
  2196.             m_rectBorder.CopyRect(lpRectBorder);
  2197.             return TRUE;
  2198.         }
  2199.         return FALSE;   // no recalc needed
  2200.  
  2201.     default:
  2202.         ASSERT(FALSE);  // invalid CFrameWnd::BorderCmd
  2203.     }
  2204.  
  2205.     return TRUE;
  2206. }
  2207. #endif // _WIN32_WCE_NO_OLE
  2208.  
  2209. void CFrameWnd::OnSize(UINT nType, int cx, int cy)
  2210. {
  2211.     CWnd::OnSize(nType, cx, cy);    // important for MDI Children
  2212.     if (nType != SIZE_MINIMIZED)
  2213.         RecalcLayout();
  2214. }
  2215.  
  2216. BOOL CFrameWnd::OnEraseBkgnd(CDC* pDC)
  2217. {
  2218.     if (m_pViewActive != NULL)
  2219.         return TRUE;        // active view will erase/paint itself
  2220.     // for view-less frame just use the default background fill
  2221.     return CWnd::OnEraseBkgnd(pDC);
  2222. }
  2223.  
  2224. #if !defined(_WIN32_WCE)
  2225. LRESULT CFrameWnd::OnRegisteredMouseWheel(WPARAM wParam, LPARAM lParam)
  2226. {
  2227.     // convert from MSH_MOUSEWHEEL to WM_MOUSEWHEEL
  2228.  
  2229.     WORD keyState = 0;
  2230.     keyState |= (::GetKeyState(VK_CONTROL) < 0) ? MK_CONTROL : 0;
  2231.     keyState |= (::GetKeyState(VK_SHIFT) < 0) ? MK_SHIFT : 0;
  2232.  
  2233.     LRESULT lResult;
  2234.     HWND hwFocus = ::GetFocus();
  2235.     const HWND hwDesktop = ::GetDesktopWindow();
  2236.  
  2237.     if (hwFocus == NULL)
  2238.         lResult = SendMessage(WM_MOUSEWHEEL, (wParam << 16) | keyState, lParam);
  2239.     else
  2240.     {
  2241.         do {
  2242.             lResult = ::SendMessage(hwFocus, WM_MOUSEWHEEL,
  2243.                 (wParam << 16) | keyState, lParam);
  2244.             hwFocus = ::GetParent(hwFocus);
  2245.         }
  2246.         while (lResult == 0 && hwFocus != NULL && hwFocus != hwDesktop);
  2247.     }
  2248.     return lResult;
  2249. }
  2250. #endif // _WIN32_WCE
  2251.  
  2252. void CFrameWnd::ActivateFrame(int nCmdShow)
  2253.     // nCmdShow is the normal show mode this frame should be in
  2254. {
  2255.     // translate default nCmdShow (-1)
  2256.     if (nCmdShow == -1)
  2257.     {
  2258.         if (!IsWindowVisible())
  2259.             nCmdShow = SW_SHOWNORMAL;
  2260.         else if (IsIconic())
  2261.             nCmdShow = SW_RESTORE;
  2262.     }
  2263.  
  2264.     // bring to top before showing
  2265.     BringToTop(nCmdShow);
  2266.  
  2267.     if (nCmdShow != -1)
  2268.     {
  2269.         // show the window as specified
  2270.         ShowWindow(nCmdShow);
  2271.  
  2272.         // and finally, bring to top after showing
  2273.         BringToTop(nCmdShow);
  2274.     }
  2275. }
  2276.  
  2277. void CFrameWnd::BringToTop(int nCmdShow)
  2278. {
  2279.     // place the window on top except for certain nCmdShow
  2280.     if (nCmdShow != SW_HIDE &&
  2281.         nCmdShow != SW_MINIMIZE && nCmdShow != SW_SHOWMINNOACTIVE &&
  2282.         nCmdShow != SW_SHOWNA && nCmdShow != SW_SHOWNOACTIVATE)
  2283.     {
  2284.         // if no last active popup, it will return m_hWnd
  2285.         HWND hWndLastPop = ::WCE_FCTN(GetLastActivePopup)(m_hWnd);
  2286.         ::BringWindowToTop(hWndLastPop);
  2287.     }
  2288. }
  2289.  
  2290. /////////////////////////////////////////////////////////////////////////////
  2291. // CFrameWnd Diagnostics
  2292.  
  2293. #ifdef _DEBUG
  2294. void CFrameWnd::AssertValid() const
  2295. {
  2296.     CWnd::AssertValid();
  2297.     if (m_pViewActive != NULL)
  2298.         ASSERT_VALID(m_pViewActive);
  2299. }
  2300.  
  2301. void CFrameWnd::Dump(CDumpContext& dc) const
  2302. {
  2303.     CWnd::Dump(dc);
  2304.  
  2305.     dc << "m_hAccelTable = " << (UINT)m_hAccelTable;
  2306.     dc << "\nm_nWindow = " << m_nWindow;
  2307.     dc << "\nm_nIDHelp = " << m_nIDHelp;
  2308.     dc << "\nm_nIDTracking = " << m_nIDTracking;
  2309.     dc << "\nm_nIDLastMessage = " << m_nIDLastMessage;
  2310.     if (m_pViewActive != NULL)
  2311.         dc << "\nwith active view: " << m_pViewActive;
  2312.     else
  2313.         dc << "\nno active view";
  2314.  
  2315.     dc << "\n";
  2316. }
  2317. #endif //_DEBUG
  2318.  
  2319. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  2320. /////////////////////////////////////////////////////////////////////////////
  2321. // CControlBar segmentation
  2322.  
  2323. CFrameWnd* CControlBar::GetDockingFrame() const
  2324. {
  2325.     CFrameWnd* pFrameWnd = GetParentFrame();
  2326.     if (pFrameWnd == NULL)
  2327.         pFrameWnd = m_pDockSite;
  2328.  
  2329.     ASSERT(pFrameWnd != NULL);
  2330.     ASSERT_KINDOF(CFrameWnd, pFrameWnd);
  2331.     return pFrameWnd;
  2332. }
  2333.  
  2334. BOOL CControlBar::IsFloating() const
  2335. {
  2336. #if defined(_WIN32_WCE_NO_DOCKBARS)
  2337.     return FALSE;
  2338. #else // _WIN32_WCE_NO_DOCKBARS
  2339.     if (IsDockBar())
  2340.         return ((CDockBar*)this)->m_bFloating;
  2341.     else
  2342.         return m_pDockBar != NULL && m_pDockBar->m_bFloating;
  2343. #endif // _WIN32_WCE_NO_DOCKBARS
  2344. }
  2345. #endif // _WIN32_WCE_NO_CONTROLBARS
  2346.  
  2347. #ifdef AFX_INIT_SEG
  2348. #pragma code_seg(AFX_INIT_SEG)
  2349. #endif
  2350.  
  2351. // in this file for IsKindOf library granularity (IsKindOf references these)
  2352. IMPLEMENT_DYNCREATE(CFrameWnd, CWnd)
  2353. IMPLEMENT_DYNAMIC(CView, CWnd)
  2354. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  2355. IMPLEMENT_DYNAMIC(CControlBar, CWnd)
  2356. #endif // _WIN32_WCE_NO_CONTROLBARS
  2357. /////////////////////////////////////////////////////////////////////////////
  2358.