home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / VIEWCORE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-02  |  14.5 KB  |  574 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 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.  
  13. #ifdef AFX_CORE2_SEG
  14. #pragma code_seg(AFX_CORE2_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CView
  24.  
  25. BEGIN_MESSAGE_MAP(CView, CWnd)
  26.     //{{AFX_MSG_MAP(CView)
  27.     ON_WM_PAINT()
  28.     ON_WM_MOUSEACTIVATE()
  29.     ON_WM_CREATE()
  30.     ON_WM_DESTROY()
  31.  
  32.     // Standard commands for split pane
  33.     ON_COMMAND_EX(ID_WINDOW_SPLIT, OnSplitCmd)
  34.     ON_UPDATE_COMMAND_UI(ID_WINDOW_SPLIT, OnUpdateSplitCmd)
  35.  
  36.     // Standard commands for next pane
  37.     ON_UPDATE_COMMAND_UI(ID_NEXT_PANE, OnUpdateNextPaneMenu)
  38.     ON_COMMAND_EX(ID_NEXT_PANE, OnNextPaneCmd)
  39.     ON_UPDATE_COMMAND_UI(ID_PREV_PANE, OnUpdateNextPaneMenu)
  40.     ON_COMMAND_EX(ID_PREV_PANE, OnNextPaneCmd)
  41.     //}}AFX_MSG_MAP
  42.     // special command for Initial Update
  43.     ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
  44. END_MESSAGE_MAP()
  45.  
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CView construction/destruction
  48.  
  49. CView::CView()
  50. {
  51.     m_pDocument = NULL;
  52. }
  53.  
  54. CView::~CView()
  55. {
  56.     if (m_pDocument != NULL)
  57.         m_pDocument->RemoveView(this);
  58. }
  59.  
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CView second phase construction - bind to document
  62.  
  63. BOOL CView::PreCreateWindow(CREATESTRUCT & cs)
  64. {
  65.     ASSERT(cs.style & WS_CHILD);
  66.  
  67.     if (cs.lpszClass == NULL)
  68.     {
  69.         if (!AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG))
  70.             return FALSE;
  71.         cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background
  72.     }
  73.  
  74.     if (afxData.bWin4 && (cs.style & WS_BORDER))
  75.     {
  76.         cs.dwExStyle |= WS_EX_CLIENTEDGE;
  77.         cs.style &= ~WS_BORDER;
  78.     }
  79.  
  80.     return TRUE;
  81. }
  82.  
  83. int CView::OnCreate(LPCREATESTRUCT lpcs)
  84. {
  85.     if (CWnd::OnCreate(lpcs) == -1)
  86.         return -1;
  87.  
  88.     // if ok, wire in the current document
  89.     ASSERT(m_pDocument == NULL);
  90.     CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;
  91.  
  92.     // A view should be created in a given context!
  93.     if (pContext != NULL && pContext->m_pCurrentDoc != NULL)
  94.     {
  95.         pContext->m_pCurrentDoc->AddView(this);
  96.         ASSERT(m_pDocument != NULL);
  97.     }
  98.     else
  99.     {
  100.         TRACE0("Warning: Creating a pane with no CDocument.\n");
  101.     }
  102.  
  103.     return 0;   // ok
  104. }
  105.  
  106. void CView::OnDestroy()
  107. {
  108.     CFrameWnd* pFrame = GetParentFrame();
  109.     if (pFrame != NULL && pFrame->GetActiveView() == this)
  110.         pFrame->SetActiveView(NULL);    // deactivate during death
  111.     CWnd::OnDestroy();
  112. }
  113.  
  114. // self destruction
  115. void CView::PostNcDestroy()
  116. {
  117.     // default for views is to allocate them on the heap
  118.     //  the default post-cleanup is to 'delete this'.
  119.     //  never explicitly call 'delete' on a view
  120.     delete this;
  121. }
  122.  
  123. void CView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
  124. {
  125.     if (nAdjustType != 0)
  126.     {
  127.         // allow for special client-edge style
  128.         ::AdjustWindowRectEx(lpClientRect, 0, FALSE, GetExStyle());
  129.  
  130.         // default behavior for in-place editing handles scrollbars
  131.         DWORD dwStyle = GetStyle();
  132.         if (dwStyle & WS_VSCROLL)
  133.         {
  134.             int nAdjust = afxData.cxVScroll;
  135.             if (dwStyle & WS_BORDER)
  136.                 nAdjust -= CX_BORDER;
  137.             lpClientRect->right += nAdjust;
  138.         }
  139.         if (dwStyle & WS_HSCROLL)
  140.         {
  141.             int nAdjust = afxData.cyHScroll;
  142.             if (dwStyle & WS_BORDER)
  143.                 nAdjust -= CY_BORDER;
  144.             lpClientRect->bottom += nAdjust;
  145.         }
  146.         return;
  147.     }
  148.  
  149.     // call default to place borders outside of client rect
  150.     CWnd::CalcWindowRect(lpClientRect, nAdjustType);
  151. }
  152.  
  153. /////////////////////////////////////////////////////////////////////////////
  154. // Command routing
  155.  
  156. BOOL CView::OnCmdMsg(UINT nID, int nCode, void* pExtra,
  157.     AFX_CMDHANDLERINFO* pHandlerInfo)
  158. {
  159.     // first pump through pane
  160.     if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  161.         return TRUE;
  162.  
  163.     // then pump through document
  164.     BOOL bHandled = FALSE;
  165.     if (m_pDocument != NULL)
  166.     {
  167.         // special state for saving view before routing to document
  168.         _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
  169.         CView* pOldRoutingView = pThreadState->m_pRoutingView;
  170.         pThreadState->m_pRoutingView = this;
  171.         bHandled = m_pDocument->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  172.         pThreadState->m_pRoutingView = pOldRoutingView;
  173.     }
  174.  
  175.     return bHandled;
  176. }
  177.  
  178. /////////////////////////////////////////////////////////////////////////////
  179. // CView drawing support
  180.  
  181. void CView::OnPaint()
  182. {
  183.     // standard paint routine
  184.     CPaintDC dc(this);
  185.     OnPrepareDC(&dc);
  186.     OnDraw(&dc);
  187. }
  188.  
  189. void CView::OnInitialUpdate()
  190. {
  191.     OnUpdate(NULL, 0, NULL);        // initial update
  192. }
  193.  
  194. void CView::OnUpdate(CView* pSender, LPARAM /*lHint*/, CObject* /*pHint*/)
  195. {
  196.     ASSERT(pSender != this);
  197.     UNUSED(pSender);     // unused in release builds
  198.  
  199.     // invalidate the entire pane, erase background too
  200.     Invalidate(TRUE);
  201. }
  202.  
  203. void CView::OnPrint(CDC* pDC, CPrintInfo*)
  204. {
  205.     ASSERT_VALID(pDC);
  206.  
  207.     // Override and set printing variables based on page number
  208.     OnDraw(pDC);                    // Call Draw
  209. }
  210.  
  211. void CView::OnDraw(CDC*)
  212. {
  213. }
  214.  
  215. /////////////////////////////////////////////////////////////////////////////
  216. // CView selection support
  217.  
  218. BOOL CView::IsSelected(const CObject* pDocItem) const
  219. {
  220.     ASSERT_VALID(pDocItem);
  221.     UNUSED(pDocItem);    // unused in release builds
  222.  
  223.     return FALSE;   // not implemented, so not selected
  224. }
  225.  
  226. void CView::OnActivateView(BOOL bActivate, CView* pActivateView, CView*)
  227. {
  228.     UNUSED(pActivateView);   // unused in release builds
  229.  
  230.     if (bActivate)
  231.     {
  232.         ASSERT(pActivateView == this);
  233.  
  234.         // take the focus if this frame/view/pane is now active
  235.         if (IsTopParentActive())
  236.             SetFocus();
  237.     }
  238. }
  239.  
  240. void CView::OnActivateFrame(UINT /*nState*/, CFrameWnd* /*pFrameWnd*/)
  241. {
  242. }
  243.  
  244. int CView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
  245. {
  246.     int nResult = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
  247.     if (nResult == MA_NOACTIVATE || nResult == MA_NOACTIVATEANDEAT)
  248.         return nResult;   // frame does not want to activate
  249.  
  250.     CFrameWnd* pParentFrame = GetParentFrame();
  251.     if (pParentFrame != NULL)
  252.     {
  253.         // eat it if this will cause activation
  254.         ASSERT(pParentFrame == pDesktopWnd || pDesktopWnd->IsChild(pParentFrame));
  255.  
  256.         // either re-activate the current view, or set this view to be active
  257.         CView* pView = pParentFrame->GetActiveView();
  258.         HWND hWndFocus = ::GetFocus();
  259.         if (pView == this &&
  260.             m_hWnd != hWndFocus && !::IsChild(m_hWnd, hWndFocus))
  261.         {
  262.             // re-activate this view
  263.             OnActivateView(TRUE, this, this);
  264.         }
  265.         else
  266.         {
  267.             // activate this view
  268.             pParentFrame->SetActiveView(this);
  269.         }
  270.     }
  271.     return nResult;
  272. }
  273.  
  274. /////////////////////////////////////////////////////////////////////////////
  275. // CView scrolling support
  276.  
  277. BOOL CView::OnScroll(UINT /*nScrollCode*/, UINT /*nPos*/, BOOL /*bDoScroll*/)
  278. {
  279.     return FALSE;
  280. }
  281.  
  282. BOOL CView::OnScrollBy(CSize /*sizeScroll*/, BOOL /*bDoScroll*/)
  283. {
  284.     return FALSE;
  285. }
  286.  
  287. /////////////////////////////////////////////////////////////////////////////
  288. // CView drag/drop support
  289.  
  290. DROPEFFECT CView::OnDragScroll(DWORD /*dwKeyState*/, CPoint /*point*/)
  291. {
  292. #ifndef _AFX_NO_OLE_SUPPORT
  293.     return DROPEFFECT_SCROLL; // this means do the default
  294. #else
  295.     return 0;
  296. #endif
  297. }
  298.  
  299. DROPEFFECT CView::OnDragEnter(COleDataObject* /*pDataObject*/,
  300.     DWORD /*dwKeyState*/, CPoint /*point*/)
  301. {
  302.     return 0;   // DROPEFFECT_NONE
  303. }
  304.  
  305. DROPEFFECT CView::OnDragOver(COleDataObject* /*pDataObject*/,
  306.     DWORD /*dwKeyState*/, CPoint /*point*/)
  307. {
  308.     return 0;   // DROPEFFECT_NONE
  309. }
  310.  
  311. BOOL CView::OnDrop(COleDataObject* /*pDataObject*/,
  312.     DROPEFFECT /*dropEffect*/, CPoint /*point*/)
  313. {
  314.     return FALSE;
  315. }
  316.  
  317. DROPEFFECT CView::OnDropEx(COleDataObject* /*pDataObject*/,
  318.     DROPEFFECT /*dropEffect*/, DROPEFFECT /*dropEffectList*/, CPoint /*point*/)
  319. {
  320.     return (DROPEFFECT)-1;  // not implemented
  321. }
  322.  
  323. void CView::OnDragLeave()
  324. {
  325. }
  326.  
  327. /////////////////////////////////////////////////////////////////////////////
  328. // CView splitting commands
  329.  
  330. CSplitterWnd* PASCAL
  331. CView::GetParentSplitter(const CWnd* pWnd, BOOL bAnyState)
  332. {
  333.     CSplitterWnd* pSplitter = (CSplitterWnd*)pWnd->GetParent();
  334.     if (!pSplitter->IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
  335.         return NULL;        // not a splitter
  336.     if (!bAnyState)
  337.     {
  338.         // ignore splitters in minimized (iconic) windows
  339.         while ((pWnd = pWnd->GetParent()) != NULL)
  340.             if (pWnd->IsIconic())
  341.                 return NULL;
  342.     }
  343.     return pSplitter;
  344. }
  345.  
  346. CScrollBar* CView::GetScrollBarCtrl(int nBar) const
  347. {
  348.     ASSERT(nBar == SB_HORZ || nBar == SB_VERT);
  349.     if (GetStyle() & ((nBar == SB_HORZ) ? WS_HSCROLL : WS_VSCROLL))
  350.     {
  351.         // it has a regular windows style scrollbar (no control)
  352.         return NULL;
  353.     }
  354.  
  355.     CWnd* pParent = GetParentSplitter(this, TRUE);
  356.     if (pParent == NULL)
  357.         return NULL;            // no splitter
  358.  
  359.     UINT nID = _AfxGetDlgCtrlID(m_hWnd);
  360.     if (nID < AFX_IDW_PANE_FIRST || nID > AFX_IDW_PANE_LAST)
  361.         return NULL;            // not a standard pane ID
  362.  
  363.     // appropriate PANE id - look for sibling (splitter, or just frame)
  364.     UINT nIDScroll;
  365.     if (nBar == SB_HORZ)
  366.         nIDScroll = AFX_IDW_HSCROLL_FIRST + (nID - AFX_IDW_PANE_FIRST) % 16;
  367.     else
  368.         nIDScroll = AFX_IDW_VSCROLL_FIRST + (nID - AFX_IDW_PANE_FIRST) / 16;
  369.  
  370.     // return shared scroll bars that are immediate children of splitter
  371.     return (CScrollBar*)pParent->GetDlgItem(nIDScroll);
  372. }
  373.  
  374.  
  375. void CView::OnUpdateSplitCmd(CCmdUI* pCmdUI)
  376. {
  377.     CSplitterWnd* pSplitter = GetParentSplitter(this, FALSE);
  378.     pCmdUI->Enable(pSplitter != NULL && !pSplitter->IsTracking());
  379. }
  380.  
  381. BOOL CView::OnSplitCmd(UINT)
  382. {
  383.     CSplitterWnd* pSplitter = GetParentSplitter(this, FALSE);
  384.     if (pSplitter == NULL)
  385.         return FALSE;
  386.  
  387.     ASSERT(!pSplitter->IsTracking());
  388.     pSplitter->DoKeyboardSplit();
  389.     return TRUE;    // attempted at least
  390. }
  391.  
  392. void CView::OnUpdateNextPaneMenu(CCmdUI* pCmdUI)
  393. {
  394.     ASSERT(pCmdUI->m_nID == ID_NEXT_PANE ||
  395.         pCmdUI->m_nID == ID_PREV_PANE);
  396.     CSplitterWnd* pSplitter = GetParentSplitter(this, FALSE);
  397.     pCmdUI->Enable(pSplitter != NULL &&
  398.         pSplitter->CanActivateNext(pCmdUI->m_nID == ID_PREV_PANE));
  399. }
  400.  
  401. BOOL CView::OnNextPaneCmd(UINT nID)
  402. {
  403.     CSplitterWnd* pSplitter = GetParentSplitter(this, FALSE);
  404.     if (pSplitter == NULL)
  405.         return FALSE;
  406.  
  407.     ASSERT(nID == ID_NEXT_PANE || nID == ID_PREV_PANE);
  408.     pSplitter->ActivateNext(nID == ID_PREV_PANE);
  409.     return TRUE;
  410. }
  411.  
  412. /////////////////////////////////////////////////////////////////////////////
  413. // Printing support virtual functions (others in viewpr.cpp)
  414.  
  415. void CView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
  416. {
  417.     ASSERT_VALID(pDC);
  418.     UNUSED(pDC); // unused in release builds
  419.  
  420.     // Default to one page printing if doc length not known
  421.     if (pInfo != NULL)
  422.         pInfo->m_bContinuePrinting =
  423.             (pInfo->GetMaxPage() != 0xffff || (pInfo->m_nCurPage == 1));
  424. }
  425.  
  426. BOOL CView::OnPreparePrinting(CPrintInfo*)
  427. {
  428.     // Do print DC initialization here
  429.     // override and call DoPreparePrinting (in viewprnt.cpp)
  430.  
  431.     return TRUE;
  432. }
  433.  
  434. void CView::OnBeginPrinting(CDC* pDC, CPrintInfo*)
  435. {
  436.     ASSERT_VALID(pDC);
  437.     UNUSED(pDC);     // unused in release builds
  438.  
  439.     // Do printing initialization here
  440. }
  441.  
  442. void CView::OnEndPrinting(CDC* pDC, CPrintInfo*)
  443. {
  444.     ASSERT_VALID(pDC);
  445.     UNUSED(pDC);     // unused in release builds
  446.  
  447.     // Do printing cleanup here
  448. }
  449.  
  450. // OnEndPrintPreview is here for swap tuning reasons
  451. //  (see viewprev.cpp for complete preview mode implementation)
  452. void CView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo,
  453.             POINT, CPreviewView* pView)
  454. {
  455.     ASSERT_VALID(pDC);
  456.     ASSERT_VALID(pView);
  457.  
  458.     if (pView->m_pPrintView != NULL)
  459.         pView->m_pPrintView->OnEndPrinting(pDC, pInfo);
  460.  
  461.     CFrameWnd* pParent;
  462.     CWnd* pNaturalParent = pView->GetParentFrame();
  463.     pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
  464.     if (pParent == NULL || pParent->IsIconic())
  465.         pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
  466.  
  467.     ASSERT_VALID(pParent);
  468.     ASSERT_KINDOF(CFrameWnd, pParent);
  469.  
  470.     // restore the old main window
  471.     pParent->OnSetPreviewMode(FALSE, pView->m_pPreviewState);
  472.  
  473.     // Force active view back to old one
  474.     pParent->SetActiveView(pView->m_pPreviewState->pViewActiveOld);
  475.     if (pParent != GetParentFrame())
  476.         OnActivateView(TRUE, this, this);   // re-activate view in real frame
  477.     pView->DestroyWindow();     // destroy preview view
  478.             // C++ object will be deleted in PostNcDestroy
  479.  
  480.     // restore main frame layout and idle message
  481.     pParent->RecalcLayout();
  482.     pParent->SendMessage(WM_SETMESSAGESTRING, (WPARAM)AFX_IDS_IDLEMESSAGE, 0L);
  483.     pParent->UpdateWindow();
  484. }
  485.  
  486. /////////////////////////////////////////////////////////////////////////////
  487. // CView diagnostics
  488.  
  489. #ifdef _DEBUG
  490. void CView::Dump(CDumpContext& dc) const
  491. {
  492.     CWnd::Dump(dc);
  493.  
  494.     if (m_pDocument != NULL)
  495.         dc << "with document: " << m_pDocument;
  496.     else
  497.         dc << "with no document\n";
  498. }
  499.  
  500. void CView::AssertValid() const
  501. {
  502.     CWnd::AssertValid();
  503. }
  504. #endif //_DEBUG
  505.  
  506. /////////////////////////////////////////////////////////////////////////////
  507. // CCtrlView
  508.  
  509. BEGIN_MESSAGE_MAP(CCtrlView, CView)
  510.     ON_WM_PAINT()
  511. END_MESSAGE_MAP()
  512.  
  513. CCtrlView::CCtrlView(LPCTSTR lpszClass, DWORD dwStyle)
  514. {
  515.     m_strClass = lpszClass;
  516.     m_dwDefaultStyle = dwStyle;
  517. }
  518.  
  519. BOOL CCtrlView::PreCreateWindow(CREATESTRUCT& cs)
  520. {
  521.     ASSERT(cs.lpszClass == NULL);
  522.     cs.lpszClass = m_strClass;
  523.  
  524.     // initialize common controls
  525.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));
  526.  
  527.     // map default CView style to default style
  528.     // WS_BORDER is insignificant
  529.     if ((cs.style | WS_BORDER) == AFX_WS_DEFAULT_VIEW)
  530.         cs.style = m_dwDefaultStyle & (cs.style | ~WS_BORDER);
  531.  
  532.     return CView::PreCreateWindow(cs);
  533. }
  534.  
  535. void CCtrlView::OnDraw(CDC*)
  536. {
  537.     ASSERT(FALSE);
  538. }
  539.  
  540. void CCtrlView::OnPaint()
  541. {
  542.     // this is done to avoid CView::OnPaint
  543.     Default();
  544. }
  545.  
  546. /////////////////////////////////////////////////////////////////////////////
  547. // CCtrlView diagnostics
  548.  
  549. #ifdef _DEBUG
  550. void CCtrlView::Dump(CDumpContext& dc) const
  551. {
  552.     CView::Dump(dc);
  553.     dc << "\nClass Name: " << m_strClass;
  554.     dc << "\nDefault Style: " << (void*)m_dwDefaultStyle;
  555. }
  556.  
  557. void CCtrlView::AssertValid() const
  558. {
  559.     CWnd::AssertValid();
  560.     ASSERT(!m_strClass.IsEmpty());
  561. }
  562. #endif //_DEBUG
  563.  
  564. #ifdef AFX_INIT_SEG
  565. #pragma code_seg(AFX_INIT_SEG)
  566. #endif
  567.  
  568. // IMPLEMENT_DYNAMIC for CView is in wincore.cpp for .OBJ granularity reasons
  569.  
  570. IMPLEMENT_DYNAMIC(CSplitterWnd, CWnd)   // for swap tuning
  571. IMPLEMENT_DYNAMIC(CCtrlView, CView)
  572.  
  573. /////////////////////////////////////////////////////////////////////////////
  574.