gdidoc.cpp
来自「MFC编程实例」· C++ 代码 · 共 456 行
CPP
456 行
#include "stdafx.h"
#include "GDI.h"
#include "GDIView.h"
#include "GDIDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
COLORREF colorDef[COLOR_BUTTON_NUM]=
{
RGB(0x00, 0x00, 0x00),
RGB(0x80, 0x00, 0x00),
RGB(0x00, 0x80, 0x00),
RGB(0x80, 0x80, 0x00),
RGB(0x00, 0x00, 0x80),
RGB(0x80, 0x00, 0x80),
RGB(0x00, 0x80, 0x80),
RGB(0xC0, 0xC0, 0xC0),
RGB(0xC0, 0xFF, 0xC0),
RGB(0xA6, 0xCA, 0xF0),
RGB(0xFF, 0xF0, 0xF0),
RGB(0xA0, 0xA0, 0xA4),
RGB(0x80, 0x80, 0x80),
RGB(0xFF, 0x00, 0x00),
RGB(0x00, 0xFF, 0x00),
RGB(0xFF, 0xFF, 0x00),
RGB(0x00, 0x00, 0xFF),
RGB(0xFF, 0x00, 0xFF),
RGB(0x00, 0xFF, 0xFF),
RGB(0xFF, 0xFF, 0xFF)
};
IMPLEMENT_DYNCREATE(CGDIDoc, CDocument)
BEGIN_MESSAGE_MAP(CGDIDoc, CDocument)
//{{AFX_MSG_MAP(CGDIDoc)
ON_COMMAND(ID_ZOOM_IN, OnZoomIn)
ON_COMMAND(ID_ZOOM_OUT, OnZoomOut)
ON_UPDATE_COMMAND_UI(ID_ZOOM_IN, OnUpdateZoomIn)
ON_UPDATE_COMMAND_UI(ID_ZOOM_OUT, OnUpdateZoomOut)
ON_COMMAND(ID_GRID, OnGrid)
ON_UPDATE_COMMAND_UI(ID_GRID, OnUpdateGrid)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
//}}AFX_MSG_MAP
ON_COMMAND_RANGE(TOOL_HEAD_ID, TOOL_TAIL_ID, OnDrawTool)
ON_UPDATE_COMMAND_UI_RANGE(TOOL_HEAD_ID, TOOL_TAIL_ID, OnUpdateDrawTool)
END_MESSAGE_MAP()
CGDIDoc::CGDIDoc()
{
LPLOGPALETTE lpLogPal;
int i;
lpLogPal=(LPLOGPALETTE) new BYTE
[
sizeof(LOGPALETTE)+(PALETTE_SIZE-1)*sizeof(PALETTEENTRY)
];
lpLogPal->palVersion=0x300;
lpLogPal->palNumEntries=PALETTE_SIZE;
for(i=0; i<COLOR_BUTTON_NUM; i++)
{
lpLogPal->palPalEntry[i].peRed=GetRValue(colorDef[i]);
lpLogPal->palPalEntry[i].peGreen=GetGValue(colorDef[i]);
lpLogPal->palPalEntry[i].peBlue=GetBValue(colorDef[i]);;
lpLogPal->palPalEntry[i].peFlags=NULL;
}
VERIFY(m_palDraw.CreatePalette(lpLogPal));
delete [](BYTE *)lpLogPal;
m_hDIB=NULL;
m_nRatio=1;
m_bGridOn=FALSE;
m_nCurrentTool=TOOL_PEN;
}
CGDIDoc::~CGDIDoc()
{
}
BOOL CGDIDoc::OnNewDocument()
{
if(!CDocument::OnNewDocument())return FALSE;
return TRUE;
}
void CGDIDoc::Serialize(CArchive& ar)
{
if(ar.IsStoring())
{
HGLOBAL hDib;
BITMAPFILEHEADER bmf;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpBi;
DWORD dwSizeCT;
hDib=m_hDIB;
ASSERT(hDib);
bmf.bfType='MB';
bmf.bfSize=sizeof(bmf)+::GlobalSize(hDib);
bmf.bfReserved1=0;
bmf.bfReserved2=0;
lpBi=(LPBITMAPINFOHEADER)::GlobalLock(hDib);
bi=*lpBi;
if(bi.biSizeImage == 0)
{
bi.biSizeImage=WIDTHBYTES(bi.biBitCount*bi.biWidth)*bi.biHeight;
}
dwSizeCT=GetColorTableSize(bi.biBitCount);
bmf.bfOffBits=sizeof(bmf)+bi.biSize+dwSizeCT*sizeof(RGBQUAD);
ar.Write((char *)&bmf, sizeof(bmf));
ar.Write((LPSTR)lpBi, bi.biSize+dwSizeCT*sizeof(RGBQUAD)+bi.biSizeImage);
::GlobalUnlock(hDib);
}
else
{
BITMAPFILEHEADER bf;
DWORD dwSize;
LPSTR lpDIB;
if(m_hDIB != NULL)
{
::GlobalFree(m_hDIB);
m_hDIB=NULL;
}
if
(
ar.Read
(
(LPSTR)&bf,
sizeof(BITMAPFILEHEADER)
) != sizeof(BITMAPFILEHEADER)
)return;
if(bf.bfType != 'MB')return;
dwSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
m_hDIB=(HBITMAP)::GlobalAlloc(GHND, dwSize);
ASSERT(m_hDIB);
lpDIB=(LPSTR)::GlobalLock(m_hDIB);
ASSERT(lpDIB);
if(ar.Read(lpDIB, dwSize) != dwSize)
{
::GlobalUnlock(m_hDIB);
::GlobalFree(m_hDIB);
m_hDIB=NULL;
}
else ::GlobalUnlock(m_hDIB);
}
}
#ifdef _DEBUG
void CGDIDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CGDIDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif
DWORD CGDIDoc::GetColorTableSize(WORD wBitCount)
{
DWORD dwSizeCT;
switch(wBitCount)
{
case 1:
{
dwSizeCT=2;
break;
}
case 4:
{
dwSizeCT=16;
break;
}
case 8:
{
dwSizeCT=256;
break;
}
case 24:
{
dwSizeCT=0;
}
}
return dwSizeCT;
}
CGDIView *CGDIDoc::GetCGDIView()
{
POSITION pos;
CGDIView *ptrView;
pos=GetFirstViewPosition();
ptrView=(CGDIView *)GetNextView(pos);
ASSERT(ptrView->IsKindOf(RUNTIME_CLASS(CGDIView)));
return ptrView;
}
void CGDIDoc::OnZoomIn()
{
int nRatio;
if(m_nRatio < 16)
{
nRatio=m_nRatio*2;
GetCGDIView()->ChangeTrackerRectRatio(nRatio);
m_nRatio=nRatio;
UpdateAllViews(NULL);
GetCGDIView()->UpdateScrollSizes();
}
}
void CGDIDoc::OnZoomOut()
{
int nRatio;
if(m_nRatio > 1)
{
nRatio=m_nRatio/2;
GetCGDIView()->ChangeTrackerRectRatio(nRatio);
m_nRatio=nRatio;
UpdateAllViews(NULL);
GetCGDIView()->UpdateScrollSizes();
}
}
void CGDIDoc::OnUpdateZoomIn(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_nRatio < 16 && m_hDIB != NULL);
}
void CGDIDoc::OnUpdateZoomOut(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_nRatio > 1 && m_hDIB != NULL);
}
void CGDIDoc::OnGrid()
{
m_bGridOn=m_bGridOn ? FALSE:TRUE;
UpdateAllViews(NULL);
}
void CGDIDoc::OnUpdateGrid(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bGridOn == TRUE);
}
void CGDIDoc::OnDrawTool(UINT nID)
{
m_nCurrentTool=nID-TOOL_HEAD_ID;
if(m_nCurrentTool != TOOL_RECTSEL && m_nCurrentTool != TOOL_FREESEL)
{
GetCGDIView()->ResetTracker();
UpdateAllViews(NULL);
}
}
void CGDIDoc::OnUpdateDrawTool(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck((UINT)m_nCurrentTool+TOOL_HEAD_ID == pCmdUI->m_nID);
}
HGLOBAL CGDIDoc::CreateCopyCutDIB()
{
HGLOBAL hDIB;
LPBITMAPINFO lpBi;
LPSTR lpRowSrc;
LPSTR lpRowTgt;
BITMAPINFOHEADER bi;
CRect rect;
CRect rectSrc;
CSize sizeTgtOffset;
CSize sizeCopy;
int i;
int nPalSize;
DWORD dwDIBSize;
LPPALETTEENTRY lpPalEntry;
lpBi=(LPBITMAPINFO)::GlobalLock(m_hDIB);
ASSERT(lpBi != NULL);
bi=lpBi->bmiHeader;
if(bi.biBitCount != 8)
{
::GlobalUnlock(m_hDIB);
return NULL;
}
::GlobalUnlock(m_hDIB);
lpBi=NULL;
rect=GetCGDIView()->GetNormalizedTrackerRect();
dwDIBSize=
(
sizeof(BITMAPINFOHEADER)+
GetColorTableSize(bi.biBitCount)*sizeof(RGBQUAD)+
WIDTHBYTES(rect.Width()*bi.biBitCount)*rect.Height()
);
hDIB=::GlobalAlloc(GHND | GMEM_SHARE, dwDIBSize);
ASSERT(hDIB != NULL);
lpBi=(LPBITMAPINFO)::GlobalLock(hDIB);
ASSERT(lpBi != NULL);
lpBi->bmiHeader=bi;
lpBi->bmiHeader.biWidth=rect.Width();
lpBi->bmiHeader.biHeight=rect.Height();
lpBi->bmiHeader.biSizeImage=WIDTHBYTES
(
bi.biBitCount*rect.Width()
)*rect.Height();
nPalSize=GetColorTableSize(lpBi->bmiHeader.biBitCount);
lpPalEntry=(LPPALETTEENTRY)new BYTE[nPalSize*sizeof(PALETTEENTRY)];
m_palDraw.GetPaletteEntries(0, nPalSize, lpPalEntry);
for(i=0; i<nPalSize; i++)
{
lpBi->bmiColors[i].rgbRed=lpPalEntry[i].peRed;
lpBi->bmiColors[i].rgbGreen=lpPalEntry[i].peGreen;
lpBi->bmiColors[i].rgbBlue=lpPalEntry[i].peBlue;
lpBi->bmiColors[i].rgbReserved=NULL;
}
delete []lpPalEntry;
rectSrc=rect;
sizeTgtOffset.cx=0;
sizeTgtOffset.cy=0;
if(rect.left < 0)
{
rectSrc.left=0;
sizeTgtOffset.cx=-rect.left;
}
if(rect.top < 0)
{
rectSrc.top=0;
sizeTgtOffset.cy=-rect.top;
}
if(rect.right >= bi.biWidth)
{
rectSrc.right=bi.biWidth-1;
}
if(rect.bottom >= bi.biHeight)
{
rectSrc.bottom=bi.biHeight-1;
}
for(i=0; i<rectSrc.Height(); i++)
{
lpRowSrc=
(
(LPSTR)m_lpBits+
WIDTHBYTES
(
bi.biBitCount*bi.biWidth
)*(bi.biHeight-rectSrc.top-i-1)+
rectSrc.left
);
lpRowTgt=
(
(LPSTR)lpBi+
sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD)*nPalSize+
WIDTHBYTES
(
lpBi->bmiHeader.biBitCount*lpBi->bmiHeader.biWidth
)*(lpBi->bmiHeader.biHeight-sizeTgtOffset.cy-i-1)
);
memcpy
(
lpRowTgt,
lpRowSrc,
WIDTHBYTES(lpBi->bmiHeader.biBitCount*rectSrc.Width())
);
}
::GlobalUnlock(hDIB);
return hDIB;
}
void CGDIDoc::OnEditCopy()
{
if(GetCGDIView()->OpenClipboard() == TRUE)
{
HGLOBAL hDIB;
::EmptyClipboard();
hDIB=CreateCopyCutDIB();
ASSERT(hDIB != NULL);
::SetClipboardData(CF_DIB, hDIB);
::CloseClipboard();
}
}
void CGDIDoc::OnEditCut()
{
if(GetCGDIView()->OpenClipboard() == TRUE)
{
HGLOBAL hDIB;
::EmptyClipboard();
hDIB=CreateCopyCutDIB();
ASSERT(hDIB != NULL);
::SetClipboardData(CF_DIB, hDIB);
::CloseClipboard();
GetCGDIView()->FillSelectionWithBgdColor();
UpdateAllViews(NULL);
}
}
void CGDIDoc::OnEditPaste()
{
if(GetCGDIView()->OpenClipboard() == TRUE)
{
HGLOBAL hDIB;
LPBYTE lpByte;
HGLOBAL hDIBPaste;
LPBYTE lpBytePaste;
ASSERT(hDIB != NULL);
hDIB=::GetClipboardData(CF_DIB);
ASSERT(hDIB);
hDIBPaste=::GlobalAlloc(GHND, ::GlobalSize(hDIB));
ASSERT(hDIBPaste);
lpByte=(LPBYTE)::GlobalLock(hDIB);
ASSERT(lpByte);
lpBytePaste=(LPBYTE)::GlobalLock(hDIBPaste);
ASSERT(lpBytePaste);
memcpy(lpBytePaste, lpByte, ::GlobalSize(hDIB));
::GlobalUnlock(hDIB);
::GlobalUnlock(hDIBPaste);
::CloseClipboard();
GetCGDIView()->PasteDIB(hDIB);
::GlobalFree(hDIBPaste);
}
}
void CGDIDoc::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetCGDIView()->IsTrackerValid());
}
void CGDIDoc::OnUpdateEditCut(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetCGDIView()->IsTrackerValid());
}
void CGDIDoc::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
pCmdUI->Enable(::IsClipboardFormatAvailable(CF_DIB) && m_hDIB != NULL);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?