ClipSampView.cpp
上传用户:biuytresa
上传日期:2007-12-07
资源大小:721k
文件大小:11k
源码类别:

DNA

开发平台:

Visual C++

  1. // ClipSampView.cpp : implementation of the CClipSampView class
  2. //
  3. #include "stdafx.h"
  4. #include "ClipSamp.h"
  5. #include "dib.h"
  6. #include "ClipSampDoc.h"
  7. #include "ClipSampView.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CClipSampView
  15. IMPLEMENT_DYNCREATE(CClipSampView, CScrollView)
  16. BEGIN_MESSAGE_MAP(CClipSampView, CScrollView)
  17. //{{AFX_MSG_MAP(CClipSampView)
  18. // NOTE - the ClassWizard will add and remove mapping macros here.
  19. //    DO NOT EDIT what you see in these blocks of generated code!
  20.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  21.     ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
  22.     ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  23.     ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  24.     ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
  25.     ON_WM_LBUTTONDOWN()
  26.     ON_UPDATE_COMMAND_UI(ID_EDIT_COPYTO, OnUpdateEditCopy)
  27.     ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCopy)
  28.     ON_WM_SETCURSOR()
  29. //}}AFX_MSG_MAP
  30. // Standard printing commands
  31.     ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
  32.     ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  33.     ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  34. END_MESSAGE_MAP()
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CClipSampView construction/destruction
  37. CClipSampView::CClipSampView() : m_sizeTotal(800, 1050), // 8-by-10.5 inches
  38.                                                    //  when printed
  39.     m_rectTracker(50, 50, 250, 250),
  40.     m_dragOffset(0, 0), 
  41. m_rectTrackerEnter(50, 50, 250, 250) 
  42. {
  43. // TODO: add construction code here
  44. }
  45. CClipSampView::~CClipSampView()
  46. {
  47. }
  48. BOOL CClipSampView::PreCreateWindow(CREATESTRUCT& cs)
  49. {
  50. // TODO: Modify the Window class or styles here by modifying
  51. //  the CREATESTRUCT cs
  52. return CScrollView::PreCreateWindow(cs);
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CClipSampView drawing
  56. void CClipSampView::OnDraw(CDC* pDC)
  57. {
  58. CClipSampDoc* pDoc = GetDocument();
  59. ASSERT_VALID(pDoc);
  60.     CDib& dib = pDoc->m_dib;
  61.     m_tracker.m_rect = m_rectTracker;
  62.     pDC->LPtoDP(m_tracker.m_rect);    // tracker wants device coords
  63.     m_tracker.Draw(pDC);
  64.     dib.UsePalette(pDC);
  65.     dib.Draw(pDC, m_rectTracker.TopLeft(), m_rectTracker.Size());
  66. }
  67. /////////////////////////////////////////////////////////////////////////////
  68. // CClipSampView printing
  69. BOOL CClipSampView::OnPreparePrinting(CPrintInfo* pInfo)
  70. {
  71.     pInfo->SetMaxPage(1);
  72.     return DoPreparePrinting(pInfo);
  73. }
  74. void CClipSampView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  75. {
  76. // TODO: add extra initialization before printing
  77. }
  78. void CClipSampView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  79. {
  80. // TODO: add cleanup after printing
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CClipSampView diagnostics
  84. #ifdef _DEBUG
  85. void CClipSampView::AssertValid() const
  86. {
  87. CScrollView::AssertValid();
  88. }
  89. void CClipSampView::Dump(CDumpContext& dc) const
  90. {
  91. CScrollView::Dump(dc);
  92. }
  93. CClipSampDoc* CClipSampView::GetDocument() // non-debug version is inline
  94. {
  95. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClipSampDoc)));
  96. return (CClipSampDoc*)m_pDocument;
  97. }
  98. #endif //_DEBUG
  99. //////////////////////////////////////////////////////////////////////
  100. // helper functions used for clipboard and drag-drop 
  101. BOOL CClipSampView::DoPasteDib(COleDataObject* pDataObject)
  102. {
  103.     // update command UI should keep us out of here if not CF_DIB
  104.     if (!pDataObject->IsDataAvailable(CF_DIB)) {
  105.       TRACE("CF_DIB format is unavailablen");
  106.       return FALSE;
  107.     }
  108.     CClipSampDoc* pDoc = GetDocument();
  109.     // seems to be MOVEABLE memory, so we must use GlobalLock!
  110.     //  (hDib != lpDib) GetGlobalData copies the memory, so we can
  111.     //  hang onto it until we delete the CDib
  112.     HGLOBAL hDib = pDataObject->GetGlobalData(CF_DIB);
  113.     ASSERT(hDib != NULL);
  114.     LPVOID lpDib = ::GlobalLock(hDib);
  115.     ASSERT(lpDib != NULL);
  116.     pDoc->m_dib.AttachMemory(lpDib, TRUE, hDib);
  117.     GetDocument()->SetModifiedFlag();
  118.     pDoc->UpdateAllViews(NULL);
  119.     return TRUE;
  120. }
  121. COleDataSource* CClipSampView::SaveDib()
  122. {
  123.     CDib& dib = GetDocument()->m_dib;
  124.     if (dib.GetSizeImage() > 0) {
  125.       COleDataSource* pSource = new COleDataSource();
  126.       int nHeaderSize =  dib.GetSizeHeader();
  127.       int nImageSize = dib.GetSizeImage();
  128.       HGLOBAL hHeader = ::GlobalAlloc(GMEM_SHARE,
  129.           nHeaderSize + nImageSize);
  130.       LPVOID pHeader = ::GlobalLock(hHeader);
  131.       ASSERT(pHeader != NULL);
  132.       LPVOID pImage = (LPBYTE) pHeader + nHeaderSize;
  133.       memcpy(pHeader, dib.m_lpBMIH, nHeaderSize); 
  134.       memcpy(pImage, dib.m_lpImage, nImageSize);
  135.       // receiver is supposed to free the global memory 
  136.       ::GlobalUnlock(hHeader);
  137.       pSource->CacheGlobalData(CF_DIB, hHeader);
  138.       return pSource;
  139.     }
  140.     return NULL;
  141. }
  142. void CClipSampView::MoveTrackRect(CPoint point)
  143. {
  144.     CClientDC dc(this);
  145.     OnPrepareDC(&dc);
  146.     dc.DrawFocusRect(m_rectTracker);
  147.     dc.LPtoDP(m_rectTracker);
  148.     CSize sizeTrack = m_rectTracker.Size();
  149.     CPoint newTopleft = point - m_dragOffset;  // still device
  150.     m_rectTracker = CRect(newTopleft, sizeTrack);
  151.     m_tracker.m_rect = m_rectTracker;
  152.     dc.DPtoLP(m_rectTracker);
  153.     dc.DrawFocusRect(m_rectTracker);
  154. }
  155. //////////////////////////////////////////////////////////////////////
  156. // drag-and-drop functions
  157. DROPEFFECT CClipSampView::OnDragEnter(COleDataObject* pDataObject,
  158.         DWORD dwKeyState, CPoint point)
  159. {
  160.     TRACE("Entering CClipSampView::OnDragEnter, point = (%d, %d)n",
  161.         point.x, point.y);
  162.     m_rectTrackerEnter = m_rectTracker; // Save original coordinates
  163.                                         //  for cursor leaving
  164.                                         //  rectangle
  165.     CClientDC dc(this);
  166.     OnPrepareDC(&dc);
  167.     dc.DrawFocusRect(m_rectTracker); // will be erased in OnDragOver
  168.     return OnDragOver(pDataObject, dwKeyState, point);
  169. }
  170. DROPEFFECT CClipSampView::OnDragOver(COleDataObject* pDataObject,
  171.         DWORD dwKeyState, CPoint point)
  172. {
  173.     if (!pDataObject->IsDataAvailable(CF_DIB)) {
  174.         return DROPEFFECT_NONE;
  175.     }
  176.     MoveTrackRect(point);
  177.     if((dwKeyState & MK_CONTROL) == MK_CONTROL) {
  178.         return DROPEFFECT_COPY;
  179.     }
  180.     // Check for force move
  181.     if ((dwKeyState & MK_ALT) == MK_ALT) {
  182.         return DROPEFFECT_MOVE;
  183.     }
  184.     // default -- recommended action is move
  185.     return DROPEFFECT_MOVE;
  186. }
  187. void CClipSampView::OnDragLeave()
  188. {
  189.     TRACE("Entering CClipSampView::OnDragLeaven");
  190.     CClientDC dc(this);
  191.     OnPrepareDC(&dc);
  192.     dc.DrawFocusRect(m_rectTracker);
  193.     m_rectTracker = m_rectTrackerEnter; // Forget it ever happened
  194. }
  195. BOOL CClipSampView::OnDrop(COleDataObject* pDataObject, 
  196.     DROPEFFECT dropEffect, CPoint point)
  197. {
  198.     TRACE("Entering CClipSampView::OnDrop -- dropEffect = %dn", dropEffect);
  199.     BOOL bRet;
  200.     CClipSampDoc* pDoc = GetDocument();
  201.     MoveTrackRect(point);
  202.     if(pDoc->m_bDragHere) {
  203.         pDoc->m_bDragHere = FALSE;
  204.         bRet = TRUE;
  205.     }
  206.     else {
  207.         bRet = DoPasteDib(pDataObject);
  208.     }
  209.     return bRet;
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. // CClipSampView message handlers
  213. void CClipSampView::OnEditCopy() 
  214. {
  215.     COleDataSource* pSource = SaveDib();
  216.     if(pSource) {
  217.         pSource->SetClipboard(); // OLE deletes data source 
  218.     }
  219. }
  220. void CClipSampView::OnUpdateEditCopy(CCmdUI* pCmdUI) 
  221. {
  222.     // serves Copy, Cut, and Copy To
  223.     CDib& dib = GetDocument()->m_dib;
  224.     pCmdUI->Enable(dib.GetSizeImage() > 0L);
  225. }
  226. void CClipSampView::OnEditCut() 
  227. {
  228.     OnEditCopy();
  229.     GetDocument()->OnEditClearAll();
  230. }
  231. void CClipSampView::OnEditPaste() 
  232. {
  233.     CClipSampDoc* pDoc = GetDocument();
  234.     COleDataObject dataObject;
  235.     VERIFY(dataObject.AttachClipboard());
  236.     DoPasteDib(&dataObject);
  237.     pDoc->SetModifiedFlag();
  238.     pDoc->UpdateAllViews(NULL);
  239. }
  240. void CClipSampView::OnUpdateEditPaste(CCmdUI* pCmdUI) 
  241. {
  242.     COleDataObject dataObject;
  243.     BOOL bAvail = dataObject.AttachClipboard() && dataObject.IsDataAvailable(CF_DIB);
  244.     pCmdUI->Enable(bAvail);
  245. }
  246. void CClipSampView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
  247. {
  248.     // custom MM_LOENGLISH with positive y down
  249.     if(pDC->IsPrinting()) {
  250.         int nHsize = pDC->GetDeviceCaps(HORZSIZE) * 1000 / 254;
  251.         int nVsize = pDC->GetDeviceCaps(VERTSIZE) * 1000 / 254;
  252.         pDC->SetMapMode(MM_ANISOTROPIC);
  253.         pDC->SetWindowExt(nHsize, nVsize);
  254.         pDC->SetViewportExt(pDC->GetDeviceCaps(HORZRES),
  255.                             pDC->GetDeviceCaps(VERTRES));
  256.     }
  257.     else {
  258.         CScrollView::OnPrepareDC(pDC, pInfo);
  259.     }
  260. }
  261. void CClipSampView::OnInitialUpdate() 
  262. {
  263.     m_dropTarget.Register(this); // IMPORTANT
  264.     SetScrollSizes(MM_TEXT, m_sizeTotal);
  265.     m_tracker.m_nStyle = CRectTracker::solidLine | CRectTracker::resizeOutside;
  266.     CScrollView::OnInitialUpdate();
  267. }
  268. void CClipSampView::OnLButtonDown(UINT nFlags, CPoint point) 
  269. {
  270.     CClipSampDoc* pDoc = GetDocument();
  271.     if(m_tracker.HitTest(point) == CRectTracker::hitMiddle) {
  272.         COleDataSource* pSource = SaveDib();
  273.         if(pSource) {
  274.             // DoDragDrop returns only after drop is complete
  275.             CClientDC dc(this);
  276.             OnPrepareDC(&dc);
  277.             CPoint topleft = m_rectTracker.TopLeft();
  278.             dc.LPtoDP(&topleft);
  279.             // 'point' here is not the same as the point parameter in 
  280.             //  OnDragEnter, so we use this one to compute the offset
  281.             m_dragOffset = point - topleft;  // device coordinates
  282.             pDoc->m_bDragHere = TRUE;
  283.             DROPEFFECT dropEffect = pSource->DoDragDrop(
  284.                 DROPEFFECT_MOVE|DROPEFFECT_COPY, CRect(0, 0, 0, 0));
  285.             TRACE("after DoDragDrop -- dropEffect = %ldn", dropEffect);
  286.             if (dropEffect == DROPEFFECT_MOVE && pDoc->m_bDragHere) {
  287.                 pDoc->OnEditClearAll();
  288.             }
  289.             pDoc->m_bDragHere = FALSE;
  290.             delete pSource;
  291.         }
  292.     }
  293.     else {
  294.         if(m_tracker.Track(this, point, FALSE, NULL)) {
  295.             CClientDC dc(this);
  296.             OnPrepareDC(&dc);
  297.             // should have some way to prevent it going out of bounds
  298.             m_rectTracker = m_tracker.m_rect;
  299.             dc.DPtoLP(m_rectTracker); // Update logical coords
  300.         }
  301.     }
  302.     Invalidate();
  303. }
  304. BOOL CClipSampView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  305. {
  306.     if(m_tracker.SetCursor(pWnd, nHitTest)) {
  307.         return TRUE;
  308.     }
  309.     else {
  310.         return CScrollView::OnSetCursor(pWnd, nHitTest, message);
  311.     }
  312. }