Programming with Microsoft Visual C++.NET 6ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming with Microsoft Visual C++.NET 6ed [Electronic resources] - نسخه متنی

George Shepherd, David Kruglinski

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید








The Ex24a Example: A Data Object Clipboard


This example uses the CDib class from Ex06d. Here, you can move and resize the device-independent bitmap (DIB) image with a tracker rectangle, and you can copy and paste the DIB to and from the Clipboard using a COM data object. The example also includes functions for reading DIBs from and writing DIBs to BMP files.

If you create such an example from scratch, use the MFC Application Wizard without any ActiveX or Automation options and then add the following line in your

StdAfx.h file:

#include <afxole.h>

Add the following call at the start of the application's InitInstance function:

AfxOleInit();

To prepare Ex24a, open the \vcppnet\Ex24a\

Ex24a.sln solution and then build the project. Run the application, and paste a bitmap into the rectangle by choosing Paste From from the Edit menu. You'll see an MDI application similar to the one shown in Figure 24-2.


Figure 24-2: The Ex24a program in operation.


The CMainFrame Class


This class contains the handlers OnQueryNewPalette and OnPaletteChanged for the WM_QUERYNEWPALETTE and WM_PALETTECHANGED messages, respectively. These handlers send a user-defined WM_VIEWPALETTECHANGED message to all the views, and then the handler calls CDib::UsePalette to realize the palette. The value of wParam tells the view whether it should realize the palette in background mode or in foreground mode.



The CEx24aDoc Class


This class is pretty straightforward. It contains an embedded CDib object, m_dib, plus a Clear All command handler. The overridden DeleteContents member function calls the CDib::Empty function.



The CEx24aView Class


This class contains the Clipboard function command handlers, the tracking code, the DIB drawing code, and the palette message handler. The header and implementation files are shown below with manually entered code in boldface:

Ex24aView.h






// Ex24aView.h : interface of the CEx24aView class
//
#pragma once
#define WM_VIEWPALETTECHANGED WM_USER + 5
class CEx24aView : public CScrollView
{
// for tracking
CRectTracker m_tracker;
CRect m_rectTracker; // logical coordinates
CSize m_sizeTotal; // document size
protected: // create from serialization only
CEx24aView();
DECLARE_DYNCREATE(CEx24aView)
// Attributes
public:
CEx24aDoc* GetDocument() const;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
// Implementation
public:
virtual ~CEx24aView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnEditCopy();
afx_msg void OnUpdateEditCopy(CCmdUI *pCmdUI);
afx_msg void OnEditCut();
afx_msg void OnEditPaste();
afx_msg void OnUpdateEditPaste(CCmdUI *pCmdUI);
afx_msg void OnEditCopyto();
afx_msg void OnEditPastefrom();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnSetFocus(CWnd* pOldWnd);
virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
virtual void OnInitialUpdate();
afx_msg LONG OnViewPaletteChanged(UINT wParam, LONG lParam);
BOOL DoPasteDib(COleDataObject* pDataObject);
COleDataSource* CEx24aView::SaveDib();
};
#ifndef _DEBUG // debug version in Ex24aView.cpp
inline CEx24aDoc* CEx24aView::GetDocument() const
{ return reinterpret_cast<CEx24aDoc*>(m_pDocument); }
#endif











Ex24aView.cpp






// Ex24aView.cpp : implementation of the CEx24aView class
//
#include "stdafx.h"
#include "Ex24a.h"
#include "Ex24aDoc.h"
#include "Ex24aView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CEx24aView
IMPLEMENT_DYNCREATE(CEx24aView, CScrollView)
BEGIN_MESSAGE_MAP(CEx24aView, CScrollView)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
ON_COMMAND(ID_EDIT_COPYTO, OnEditCopyto)
ON_COMMAND(ID_EDIT_PASTEFROM, OnEditPastefrom)
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_SETFOCUS()
ON_WM_PALETTECHANGED()
END_MESSAGE_MAP()
// CEx24aView construction/destruction
CEx24aView::CEx24aView() : m_sizeTotal(800, 1050), // 8-by-10.5 inches
// when printed
m_rectTracker(50, 50, 250, 250)
{
}
CEx24aView::~CEx24aView()
{
}
BOOL CEx24aView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
// CEx24aView drawing
void CEx24aView::OnDraw(CDC* pDC)
{
CDib& dib = GetDocument()->m_dib;
m_tracker.m_rect = m_rectTracker;
pDC->LPtoDP(m_tracker.m_rect); // tracker wants device coordinates
m_tracker.Draw(pDC);
dib.Draw(pDC, m_rectTracker.TopLeft(), m_rectTracker.Size());
}
// CEx24aView printing
BOOL CEx24aView::OnPreparePrinting(CPrintInfo* pInfo)
{
pInfo->SetMaxPage(1);
return DoPreparePrinting(pInfo);
}
void CEx24aView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CEx24aView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
// CEx24aView diagnostics
#ifdef _DEBUG
void CEx24aView::AssertValid() const
{
CScrollView::AssertValid();
}
void CEx24aView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CEx24aDoc* CEx24aView::GetDocument() const // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEx24aDoc)));
return (CEx24aDoc*)m_pDocument;
}
#endif //_DEBUG
// helper functions used for clipboard and drag-drop
BOOL CEx24aView::DoPasteDib(COleDataObject* pDataObject)
{
// update command user interface should keep us out of
// here if not CF_DIB
if (!pDataObject->IsDataAvailable(CF_DIB)) {
TRACE("CF_DIB format is unavailable\n");
return FALSE;
}
CEx24aDoc* pDoc = GetDocument();
// Seems to be MOVEABLE memory, so we must use GlobalLock!
// (hDib != lpDib) GetGlobalData copies the memory, so we can
// hang onto it until we delete the CDib.
HGLOBAL hDib = pDataObject->GetGlobalData(CF_DIB);
ASSERT(hDib != NULL);
LPVOID lpDib = ::GlobalLock(hDib);
ASSERT(lpDib != NULL);
pDoc->m_dib.AttachMemory(lpDib, TRUE, hDib);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews(NULL);
return TRUE;
}
COleDataSource* CEx24aView::SaveDib()
{
CDib& dib = GetDocument()->m_dib;
if (dib.GetSizeImage() > 0) {
COleDataSource* pSource = new COleDataSource();
int nHeaderSize = dib.GetSizeHeader();
int nImageSize = dib.GetSizeImage();
HGLOBAL hHeader = ::GlobalAlloc(GMEM_SHARE,
nHeaderSize + nImageSize);
LPVOID pHeader = ::GlobalLock(hHeader);
ASSERT(pHeader != NULL);
LPVOID pImage = (LPBYTE) pHeader + nHeaderSize;
memcpy(pHeader, dib.m_lpBMIH, nHeaderSize);
memcpy(pImage, dib.m_lpImage, nImageSize);
// Receiver is supposed to free the global memory
::GlobalUnlock(hHeader);
pSource->CacheGlobalData(CF_DIB, hHeader);
return pSource;
}
return NULL;
}
// CEx24aView message handlers
void CEx24aView::OnEditCopy()
{
COleDataSource* pSource = SaveDib();
if (pSource) {
pSource->SetClipboard(); // OLE deletes data source
}
}
void CEx24aView::OnUpdateEditCopy(CCmdUI *pCmdUI)
{
// serves Copy, Cut, and Copy To
CDib& dib = GetDocument()->m_dib;
pCmdUI->Enable(dib.GetSizeImage() > 0L);
}
void CEx24aView::OnEditCut()
{
OnEditCopy();
GetDocument()->OnEditClearall();
}
void CEx24aView::OnEditPaste()
{
CEx24aDoc* pDoc = GetDocument();
COleDataObject dataObject;
VERIFY(dataObject.AttachClipboard());
DoPasteDib(&dataObject);
CClientDC dc(this);
pDoc->m_dib.UsePalette(&dc);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews(NULL);
}
void CEx24aView::OnUpdateEditPaste(CCmdUI *pCmdUI)
{
COleDataObject dataObject;
BOOL bAvail = dataObject.AttachClipboard() &&
dataObject.IsDataAvailable(CF_DIB);
pCmdUI->Enable(bAvail);
}
void CEx24aView::OnEditCopyto()
{
CDib& dib = GetDocument()->m_dib;
CFileDialog dlg(FALSE, "bmp", "*.bmp");
if (dlg.DoModal() != IDOK) return;
BeginWaitCursor();
dib.CopyToMapFile(dlg.GetPathName());
EndWaitCursor();
}
void CEx24aView::OnEditPastefrom()
{
CEx24aDoc* pDoc = GetDocument();
CFileDialog dlg(TRUE, "bmp", "*.bmp");
if (dlg.DoModal() != IDOK) return;
if (pDoc->m_dib.AttachMapFile(dlg.GetPathName(), TRUE)) { // share
CClientDC dc(this);
pDoc->m_dib.SetSystemPalette(&dc);
pDoc->m_dib.UsePalette(&dc);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews(NULL);
}
}
void CEx24aView::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_tracker.Track(this, point, FALSE, NULL)) {
CClientDC dc(this);
OnPrepareDC(&dc);
m_rectTracker = m_tracker.m_rect;
dc.DPtoLP(m_rectTracker); // Update logical coordinates
Invalidate();
}
}
BOOL CEx24aView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_tracker.SetCursor(pWnd, nHitTest)) {
return TRUE;
}
else {
return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}
}
void CEx24aView::OnSetFocus(CWnd* pOldWnd)
{
CScrollView::OnSetFocus(pOldWnd);
AfxGetApp()->m_pMainWnd->SendMessage(WM_PALETTECHANGED,
(UINT) GetSafeHwnd());
}
void CEx24aView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
// custom MM_LOENGLISH; positive y is down
if (pDC->IsPrinting()) {
int nHsize = pDC->GetDeviceCaps(HORZSIZE) * 1000 / 254;
int nVsize = pDC->GetDeviceCaps(VERTSIZE) * 1000 / 254;
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(nHsize, nVsize);
pDC->SetViewportExt(pDC->GetDeviceCaps(HORZRES),
pDC->GetDeviceCaps(VERTRES));
}
else {
CScrollView::OnPrepareDC(pDC, pInfo);
}
}
void CEx24aView::OnInitialUpdate()
{
SetScrollSizes(MM_TEXT, m_sizeTotal);
m_tracker.m_nStyle = CRectTracker::solidLine |
CRectTracker::resizeOutside;
CScrollView::OnInitialUpdate();
}
LONG CEx24aView::OnViewPaletteChanged(UINT wParam, LONG lParam)
{
TRACE("CEx24aView::OnViewPaletteChanged, HWND = %x, code = %d\n",
GetSafeHwnd(), wParam);
CClientDC dc(this);
GetDocument()->m_dib.UsePalette(&dc, wParam);
Invalidate();
return 0;
}











Several interesting things happen in the view class. In the DoPasteDib helper, we can call GetGlobalData because we can attach the returned HGLOBAL variable to the document's CDib object. If we were to call GetData, we'd have to copy the memory block ourselves. The Paste From and Copy To command handlers rely on the memory-mapped file support in the CDib class. The OnPrepareDC function creates a special printer-mapping mode that is just like MM_LOENGLISH except that positive y is down. One pixel on the display corresponds to 0.01 inch on the printer.



/ 319