⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex23avw.cpp

📁 visual c++技术内幕范例的源代码
💻 CPP
字号:
// ex23avw.cpp : implementation of the CEx23aView class
//

#include "stdafx.h"
#include "ex23a.h"

#include "cdib.h"
#include "ex23adoc.h"
#include "ex23avw.h"
#include "bitsdlg.h"

/************************************************************************/
#define DRAW_ALT 3 //1=StretchBlt, 2=BitBlt, 3=Stretch DIB, 4=Display DIB
/************************************************************************/

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CEx23aView

IMPLEMENT_DYNCREATE(CEx23aView, CScrollView)

BEGIN_MESSAGE_MAP(CEx23aView, CScrollView)
    //{{AFX_MSG_MAP(CEx23aView)
    ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
    ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
    ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
    ON_COMMAND(ID_EDIT_PASTE_FROM, OnEditPasteFrom)
    ON_COMMAND(ID_EDIT_COPY_TO, OnEditCopyTo)
    ON_UPDATE_COMMAND_UI(ID_EDIT_COPY_TO, OnUpdateEditCopy)
    ON_COMMAND(ID_EDIT_CUT, OnEditCut)
    ON_COMMAND(ID_VIEW_SHRINK, OnViewShrink)
    ON_UPDATE_COMMAND_UI(ID_VIEW_SHRINK, OnUpdateViewShrink)
    ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
    ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCopy)
    ON_WM_CREATE()
    //}}AFX_MSG_MAP
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEx23aView construction/destruction

CEx23aView::CEx23aView() : m_totalSize(800, 1050) // 8" x 10.5" when printed
{
    m_pDisplayMemDC = new CDC;  // DC lasts for the life of the view
    m_bShrinkToFit = FALSE;
}

CEx23aView::~CEx23aView()
{
    // deletes bitmap currently selected and restores original bitmap
    delete m_pDisplayMemDC->SelectObject
           (CBitmap::FromHandle(m_hOldDisplayBitmap));
    delete m_pDisplayMemDC;
}

/////////////////////////////////////////////////////////////////////////////
void CEx23aView::OnDraw(CDC* pDC)
{
    CRect clientRect;
    
    GetClientRect(clientRect); // device coords
    pDC->DPtoLP(clientRect);   // logical
    
#if DRAW_ALT == 1
    TRACE("Drawing alternative 1 - StretchBlt from bitmap\n");
    if (GetDocument()->m_pDib->GetMonoColors(dwFore, dwBack)) {
        pDC->SetBkColor(dwBack);
        pDC->SetTextColor(dwFore);
    }
    if (m_bShrinkToFit | pDC->IsPrinting()) {
        pDC->StretchBlt(0, 0, m_totalSize.cx, m_totalSize.cy,
                        m_pDisplayMemDC, 0, 0, m_bmSize.cx,
                        m_bmSize.cy, SRCCOPY);
    }
    else {
        // The previous StretchBlt call works fine, but this one's faster.
        // It draws only the portion of the bitmap that's in the window.
        // not so good for Print Preview, however.
        pDC->StretchBlt(clientRect.left, clientRect.top,
                        clientRect.Width(), clientRect.Height(),
                        m_pDisplayMemDC,
                        (int) ((long) m_bmSize.cx * (long) clientRect.left /
                               (long) m_totalSize.cx),
                        (int) ((long) m_bmSize.cy * (long) clientRect.top /
                               (long) m_totalSize.cy),
                        (int) ((long) m_bmSize.cx * (long) clientRect.Width() /
                               (long) m_totalSize.cx),
                        (int) ((long) m_bmSize.cy * (long) clientRect.Height() /
                               (long) m_totalSize.cy), SRCCOPY);
    }
#endif

#if DRAW_ALT == 2
    TRACE("Drawing alternative 2 - BitBlt from bitmap\n");
    if (GetDocument()->m_pDib->GetMonoColors(dwFore, dwBack)) {
        pDC->SetBkColor(dwBack);
        pDC->SetTextColor(dwFore);
    }
    pDC->BitBlt(0, 0, m_bmSize.cx, m_bmSize.cy,
                m_pDisplayMemDC, 0, 0, SRCCOPY);  
#endif

#if DRAW_ALT == 3
    // CPoint origin: +y = down
    TRACE("Drawing alternative 3 - Stretch DIB\n");
    GetDocument()->m_pDib->Stretch(pDC, CPoint(0, 0), m_bmSize);
#endif

#if DRAW_ALT == 4
    // CPoint origin: +y = down
    TRACE("Drawing alternative 4 - Display DIB\n");
    GetDocument()->m_pDib->Display(pDC, CPoint(0, 0));
#endif

#if (DRAW_ALT == 2) || (DRAW_ALT == 4)
    // print the filename at the bottom of the screen/paper
    CFont titleFont;
    titleFont.CreateFont(50, 0, 0, 0, 400, FALSE, FALSE, 0,
                         ANSI_CHARSET, OUT_DEFAULT_PRECIS,
                         CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
                         DEFAULT_PITCH | FF_SWISS, "Arial");
    pDC->SelectObject(&titleFont);
    pDC->TextOut(0, 1000, GetDocument()->GetTitle());
    pDC->SelectStockObject(SYSTEM_FONT);
#endif 
    // shows bits-per-pixel in status bar (subject to overwrite by menu code)
    char text[40];
    int nBits = GetDocument()->m_pDib->GetColorBits();
    wsprintf(text, "Bits per pixel = %d", nBits);
    CStatusBar* pStatus = (CStatusBar*)
        AfxGetApp()->m_pMainWnd->GetDlgItem(AFX_IDW_STATUS_BAR);
    if (pStatus && nBits) {
        pStatus->SetPaneText(0, text);
    }
}

/////////////////////////////////////////////////////////////////////////////
void CEx23aView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
    // custom MM_LOENGLISH with positive y down
    int nHsize = (int) (pDC->GetDeviceCaps(HORZSIZE) * 1000L / 254L);
    int nVsize = (int) (pDC->GetDeviceCaps(VERTSIZE) * 1000L / 254L);
    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetWindowExt(nHsize, nVsize);
    pDC->SetViewportExt(pDC->GetDeviceCaps(HORZRES),
                        pDC->GetDeviceCaps(VERTRES));
    OnDraw(pDC);
}

///////////////////////////////////////////////////////////////////
void CEx23aView::OnInitialUpdate()
{
    TRACE("CEx23aView::OnInitialUpdate\n");
    if (m_bShrinkToFit) {
        SetScaleToFitSize(m_totalSize);
    }
    else {
        SetScrollSizes(MM_TEXT, m_totalSize);
    }
    CScrollView::OnInitialUpdate();
}
 
void CEx23aView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
    delete GetDocument()->m_pDib->MakeBitmap(m_pDisplayMemDC, m_bmSize);
    if (!m_bShrinkToFit) {
        ScrollToPosition(CPoint(0, 0));
    }
    Invalidate();
}

/////////////////////////////////////////////////////////////////////////////
BOOL CEx23aView::OnPreparePrinting(CPrintInfo* pInfo)
{
    pInfo->SetMaxPage(1);
    return DoPreparePrinting(pInfo);
}

/////////////////////////////////////////////////////////////////////////////
// CEx23aView message handlers
int CEx23aView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CScrollView::OnCreate(lpCreateStruct)) {
        return -1;
    }

    // 'prime the pump' with an empty bitmap
    CClientDC dc(this);
    m_pDisplayMemDC->CreateCompatibleDC(&dc);
    CBitmap* pEmptyBitmap = new CBitmap;
    pEmptyBitmap->CreateCompatibleBitmap(&dc, 0, 0);
    CBitmap* pOldBitmap =
         (CBitmap*) m_pDisplayMemDC->SelectObject(pEmptyBitmap);
    // so we'll have an old bitmap to switch to at the end
    m_hOldDisplayBitmap = (HBITMAP) pOldBitmap->GetSafeHandle();
    return 0;
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnEditCopy()
{
    CBitmap* pBitmap = 
        GetDocument()->m_pDib->MakeBitmap(m_pDisplayMemDC, m_bmSize);
    if (pBitmap) {
        VERIFY(OpenClipboard());
        VERIFY(::EmptyClipboard());
        VERIFY(::SetClipboardData(CF_BITMAP, pBitmap->Detach()));
        VERIFY(::CloseClipboard());
        delete pBitmap;
    }
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnEditCut()
{
    OnEditCopy();
    GetDocument()->OnEditClearAll();
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnEditCopyTo()
{
    // copy DIB to a .BMP file
    CFileDialog dlg(FALSE, "bmp");
    if (dlg.DoModal() != IDOK) {
        return;
    }
    CFile file;
    if (!file.Open(dlg.GetPathName(), CFile::modeCreate |
        CFile::modeWrite)) {
        AfxMessageBox("Edit Copy To: Can't open file");
        return;
    }
    GetDocument()->m_pDib->Write(&file);  // get the DIB out of
                                          //  the document
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnEditPaste()
{
    VERIFY(OpenClipboard());
    // list the available clipboard formats
    UINT uFormat = 0;
    do {
        TRACE(" format = %lx\n", (long) uFormat); // first time always 0
    }
    while(uFormat = ::EnumClipboardFormats(uFormat));
    //
    // update command UI should keep us out of here if not CF_BITMAP
    if (::IsClipboardFormatAvailable(CF_BITMAP)) {
        // select the clipboard bitmap into the mem device context
        // then delete the old DIB and create the new DIB in the document
        // finally, make a new bitmap from the DIB
        // the internal bitmap can be displayed in OnDraw
        BITMAP bm;

        HBITMAP hBitmap = (HBITMAP) ::GetClipboardData(CF_BITMAP);
        ASSERT(hBitmap);
        CBitmap* pSourceBitmap = CBitmap::FromHandle(hBitmap); // temporary object
        pSourceBitmap->GetObject(sizeof(bm), &bm);
        
        int nBits = bm.bmPlanes * bm.bmBitsPixel; // bits per pixel
        TRACE("bits = %d\n", nBits);
        ASSERT((nBits == 1) || (nBits == 4) || (nBits == 8) || (nBits == 24));
        // allow user to change the # of bits per pixel
        CBitsDialog bdlg;  // system modal dialog
        if (nBits == 1) {
            bdlg.m_nBits = 0;
        }
        else 
            if (nBits == 4) {
                bdlg.m_nBits = 1;
            }
        else 
            if (nBits == 8) {
                bdlg.m_nBits = 2;
            }
        else {
            bdlg.m_nBits = 3;
        }
        if (bdlg.DoModal() == IDOK) {
            int nBitArray[4] = { 1, 4, 8, 24 };
            nBits = nBitArray[bdlg.m_nBits];
            delete m_pDisplayMemDC->SelectObject(pSourceBitmap);
            CEx23aDoc* pDoc = GetDocument();
            delete pDoc->m_pDib;
            pDoc->m_pDib = new CDib(m_pDisplayMemDC, nBits,
                                    bdlg.m_bCompression); 
            pDoc->m_pDib->MakeBitmap(m_pDisplayMemDC, m_bmSize);
            pDoc->SetModifiedFlag();

            Invalidate();
        }
    }
    VERIFY(::CloseClipboard());
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnEditPasteFrom()
{
    // paste from a .BMP file
    // we convert DIB to GDI bitmap, then select into m_pDisplayMemDC
    // no need for BitBlt here--only in OnDraw
    CFileDialog dlg(TRUE, "bmp", "*.bmp");
    if (dlg.DoModal() != IDOK) {
        return;
    }
    CFile file;
    if (!file.Open(dlg.GetPathName(), CFile::modeRead)) {
        AfxMessageBox("Edit Paste From: Can't open file");
        return;
    }
    CEx23aDoc* pDoc = GetDocument();
    delete pDoc->m_pDib;
    pDoc->m_pDib = new CDib; // replace the document's DIB
    if (!pDoc->m_pDib->Read(&file)) {
        AfxMessageBox("Edit Paste From: Can't read file");
        return;
    }
    delete pDoc->m_pDib->MakeBitmap(m_pDisplayMemDC, m_bmSize);
    pDoc->SetModifiedFlag();
    Invalidate();
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
    // show menu choice & toolbar button only if bitmap exists on clipboard
    VERIFY(OpenClipboard());
    pCmdUI->Enable(IsClipboardFormatAvailable(CF_BITMAP));
    VERIFY(::CloseClipboard());
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
    // serves Copy, Cut, and Copy To
    pCmdUI->Enable(GetDocument()->m_pDib->GetLength() > 0L);
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnViewShrink()
{
    // toggles 'shrink-to-fit' mode
    m_bShrinkToFit ^= 1;
    if (m_bShrinkToFit) {
        SetScaleToFitSize(m_totalSize);
    }
    else {
        SetScrollSizes(MM_TEXT, m_totalSize);
    }
}

///////////////////////////////////////////////////////////////////////////
void CEx23aView::OnUpdateViewShrink(CCmdUI* pCmdUI)
{
    pCmdUI->SetCheck(m_bShrinkToFit);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -