viewcore.cpp 14 KB

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