// MyPaintView.cpp : implementation of the CMyPaintView class
//
#include "stdafx.h"
#include "MyPaint.h"
#include "Mainfrm.h"
#include "MyPaintDoc.h"
#include "MyPaintView.h"
#include "MyImage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyPaintView
IMPLEMENT_DYNCREATE(CMyPaintView, CView)
BEGIN_MESSAGE_MAP(CMyPaintView, CView)
//{{AFX_MSG_MAP(CMyPaintView)
ON_UPDATE_COMMAND_UI(ID_BUTTON_IRREG_SEL, OnUpdateButtonIrregSel)
ON_UPDATE_COMMAND_UI(ID_BUTTON_RECT_SEL, OnUpdateButtonRectSel)
ON_UPDATE_COMMAND_UI(ID_BUTTON_ERASER, OnUpdateButtonEraser)
ON_UPDATE_COMMAND_UI(ID_BUTTON_FILL, OnUpdateButtonFill)
ON_UPDATE_COMMAND_UI(ID_BUTTON_MAGNIFY, OnUpdateButtonMagnify)
ON_UPDATE_COMMAND_UI(ID_BUTTON_PEN, OnUpdateButtonPen)
ON_UPDATE_COMMAND_UI(ID_BUTTON_BRUSH, OnUpdateButtonBrush)
ON_UPDATE_COMMAND_UI(ID_BUTTON_AIRBRUSH, OnUpdateButtonAirbrush)
ON_UPDATE_COMMAND_UI(ID_BUTTON_SELCOLOR, OnUpdateButtonSelcolor)
ON_UPDATE_COMMAND_UI(ID_BUTTON_TEXT, OnUpdateButtonText)
ON_COMMAND(ID_BUTTON_IRREG_SEL, OnButtonIrregSel)
ON_COMMAND(ID_BUTTON_RECT_SEL, OnButtonRectSel)
ON_COMMAND(ID_BUTTON_ERASER, OnButtonEraser)
ON_COMMAND(ID_BUTTON_MAGNIFY, OnButtonMagnify)
ON_COMMAND(ID_BUTTON_FILL, OnButtonFill)
ON_COMMAND(ID_BUTTON_BRUSH, OnButtonBrush)
ON_COMMAND(ID_BUTTON_PEN, OnButtonPen)
ON_COMMAND(ID_BUTTON_SELCOLOR, OnButtonSelcolor)
ON_COMMAND(ID_BUTTON_TEXT, OnButtonText)
ON_COMMAND(ID_BUTTON_AIRBRUSH, OnButtonAirbrush)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_BUTTON_CURVE, OnButtonCurve)
ON_UPDATE_COMMAND_UI(ID_BUTTON_CURVE, OnUpdateButtonCurve)
ON_COMMAND(ID_BUTTON_LINE, OnButtonLine)
ON_UPDATE_COMMAND_UI(ID_BUTTON_LINE, OnUpdateButtonLine)
ON_WM_SETCURSOR()
ON_UPDATE_COMMAND_UI(ID_BUTTON_RECT, OnUpdateButtonRect)
ON_COMMAND(ID_BUTTON_RECT, OnButtonRect)
ON_UPDATE_COMMAND_UI(ID_BUTTON_POLYGON, OnUpdateButtonPolygon)
ON_COMMAND(ID_BUTTON_POLYGON, OnButtonPolygon)
ON_UPDATE_COMMAND_UI(ID_BUTTON_ROUND_RECT, OnUpdateButtonRoundRect)
ON_COMMAND(ID_BUTTON_ROUND_RECT, OnButtonRoundRect)
ON_UPDATE_COMMAND_UI(ID_BUTTON_ELLIPSE, OnUpdateButtonEllipse)
ON_COMMAND(ID_BUTTON_ELLIPSE, OnButtonEllipse)
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyPaintView construction/destruction
CMyPaintView::CMyPaintView()
{
// TODO: add construction code here
m_emPaintType = IRREG_SEL;
m_pdcMem = new CDC;
m_pbmBackground = new CBitmap;
m_bDrawing = FALSE;
m_bFirstDraw = FALSE;
m_nEraserSize = 10;
m_pbyBitmapBuf = NULL;
}
CMyPaintView::~CMyPaintView()
{
delete m_pdcMem;
delete m_pbmBackground;
if ( m_pbyBitmapBuf ) delete[] m_pbyBitmapBuf;
}
BOOL CMyPaintView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMyPaintView drawing
void CMyPaintView::OnDraw(CDC* pDC)
{
CMyPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->BitBlt(0,0,m_nScreenW,m_nScreenH, m_pdcMem, 0, 0, SRCCOPY);
}
/////////////////////////////////////////////////////////////////////////////
// CMyPaintView printing
BOOL CMyPaintView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMyPaintView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMyPaintView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMyPaintView diagnostics
#ifdef _DEBUG
void CMyPaintView::AssertValid() const
{
CView::AssertValid();
}
void CMyPaintView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyPaintDoc* CMyPaintView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyPaintDoc)));
return (CMyPaintDoc*)m_pDocument;
}
#endif //_DEBUG
COLORREF CMyPaintView::GetCanvasColor() const
{
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
if ( pFrame )
return pFrame->m_clrCanvas;
else
return RGB(255,255,255);
}
COLORREF CMyPaintView::GetPaintColor() const
{
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
if ( pFrame )
return pFrame->m_clrPaint;
else
return RGB(0,0,0);
}
int CMyPaintView::GetPenWidth() const
{
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
if ( pFrame )
return pFrame->GetPenWidth();
else
return 1;
}
void CMyPaintView::SetSelBox(int type)
{
((CMainFrame*)AfxGetMainWnd())->m_wndToolBar.SetSelType((SELTYPE)type);
}
/////////////////////////////////////////////////////////////////////////////
// CMyPaintView message handlers
void CMyPaintView::OnUpdateButtonIrregSel(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==IRREG_SEL);
}
void CMyPaintView::OnUpdateButtonRectSel(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==RECT_SEL);
}
void CMyPaintView::OnUpdateButtonEraser(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==ERASER);
}
void CMyPaintView::OnUpdateButtonFill(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==FILL);
}
void CMyPaintView::OnUpdateButtonMagnify(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==MAGNIFY);
}
void CMyPaintView::OnUpdateButtonPen(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==PEN);
}
void CMyPaintView::OnUpdateButtonBrush(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==BRUSH);
}
void CMyPaintView::OnUpdateButtonAirbrush(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==AIRBRUSH);
}
void CMyPaintView::OnUpdateButtonSelcolor(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==SEL_COLOR);
}
void CMyPaintView::OnUpdateButtonText(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==TEXT);
}
void CMyPaintView::OnUpdateButtonCurve(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==CURVE);
}
void CMyPaintView::OnUpdateButtonLine(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==LINE);
}
void CMyPaintView::OnButtonIrregSel()
{
// TODO: Add your command handler code here
m_emPaintType = IRREG_SEL;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonRectSel()
{
// TODO: Add your command handler code here
m_emPaintType = RECT_SEL;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonEraser()
{
// TODO: Add your command handler code here
m_emPaintType = ERASER;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonMagnify()
{
// TODO: Add your command handler code here
m_emPaintType = MAGNIFY;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonFill()
{
// TODO: Add your command handler code here
m_emPaintType = FILL;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonBrush()
{
// TODO: Add your command handler code here
m_emPaintType = BRUSH;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonPen()
{
// TODO: Add your command handler code here
m_emPaintType = PEN;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonSelcolor()
{
// TODO: Add your command handler code here
m_emPaintType = SEL_COLOR;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonText()
{
// TODO: Add your command handler code here
m_emPaintType = TEXT;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonAirbrush()
{
// TODO: Add your command handler code here
m_emPaintType = AIRBRUSH;
SetSelBox(SEL_NONE);
}
void CMyPaintView::OnButtonCurve()
{
// TODO: Add your command handler code here
m_emPaintType = CURVE;
SetSelBox(SEL_PENWIDTH);
}
void CMyPaintView::OnButtonLine()
{
// TODO: Add your command handler code here
m_emPaintType = LINE;
SetSelBox(SEL_PENWIDTH);
}
int CMyPaintView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
m_nScreenW = ::GetSystemMetrics(SM_CXSCREEN);
m_nScreenH = ::GetSystemMetrics(SM_CYSCREEN);
CDC *pDC = GetDC();
m_pdcMem->CreateCompatibleDC(pDC);
m_pbmBackground->CreateCompatibleBitmap(pDC,m_nScreenW,m_nScreenH);
m_bmBackup.CreateCompatibleBitmap(pDC,m_nScreenW,m_nScreenH);
m_pdcMem->SelectObject(m_pbmBackground);
CBrush brush;
brush.CreateSolidBrush(GetCanvasColor());
CRect rect(0,0,m_nScreenW,m_nScreenH);
m_pdcMem->FillRect(rect,&brush);
ReleaseDC(pDC);
BITMAP bm;
m_pbmBackground->GetBitmap(&bm);
m_dwSizeBitmap = bm.bmWidthBytes * bm.bmHeight;
m_pbyBitmapBuf = new BYTE[m_dwSizeBitmap];
return 0;
}
void CMyPaintView::UpdateImage()
{
m_pdcMem->SelectObject(m_pbmBackground);
Invalidate();
}
void CMyPaintView::XorLine(CPoint pt1,CPoint pt2)
{
CDC *pDC = GetDC();
CPen pen;
pen.CreateStockObject(WHITE_PEN);
CPen* pOldPen = (CPen*)pDC->SelectObject(&pen);
pDC->SetROP2(R2_XORPEN);
pDC->MoveTo(pt1);
pDC->LineTo(pt2);
pDC->SelectObject(pOldPen);
ReleaseDC(pDC);
}
void CMyPaintView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
Backup();
CDC* pDC = GetDC();
switch(m_emPaintType)
{
case LINE:
case RECT:
m_ptStart = point;
m_bFirstDraw = TRUE;
break;
case PEN:
case BRUSH:
m_ptStart = point;
break;
case ERASER:
m_ptStart = point;
EraserBox(pDC, point);
EraserBox(m_pdcMem, point);
break;
case FILL:
Fill(pDC,point);
Fill(m_pdcMem,point);
break;
default:
break;
}
m_bDrawing = TRUE;
ReleaseDC(pDC);
CView::OnLButtonDown(nFlags, point);
}
void CMyPaintView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CString strCoord;
strCoord.Format(" %d, %d", point.x, point.y);
pFrame->m_wndStatusBar.SetPaneText(1, strCoord, TRUE);
if ( m_bDrawing )
{
CDC* pDC = GetDC();
switch(m_emPaintType)
{
case LINE:
if ( point != m_ptEnd )
{
if ( !m_bFirstDraw )
XorLine(m_ptStart,m_ptEnd);
else
m_bFirstDraw = FALSE;
XorLine(m_ptStart,point);
m_ptEnd = point;
}
break;
case PEN:
SetPixel(pDC, point);
SetPixel(m_pdcMem, point);
m_ptStart = point;
break;
case BRUSH:
SetPixel(pDC, point, GetPenWidth());
SetPixel(m_pdcMem, point, GetPenWidth());
m_ptStart = point;
break;
case ERASER:
EraserBox(pDC, point);
EraserBox(m_pdcMem, point);
m_ptStart = point;
break;
case RECT:
if ( !m_bFirstDraw )
Rectangle(pDC,m_ptStart,m_ptEnd);
else
m_bFirstDraw = FALSE;
Rectangle(pDC,m_ptStart,point);
m_ptEnd = point;
break;
default:
break;
}
ReleaseDC(pDC);
}
CView::OnMouseMove(nFlags, point);
}
void CMyPaintView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC* pDC = GetDC();
switch(m_emPaintType)
{
case LINE:
XorLine(m_ptStart,m_ptEnd);
Line(m_ptStart,m_ptEnd);
break;
case PEN:
break;
case RECT:
Rectangle(pDC,m_ptStart,m_ptEnd);
Rectangle(m_pdcMem,m_ptStart,m_ptEnd,TRUE);
break;
default:
break;
}
ReleaseDC(pDC);
m_bDrawing = FALSE;
Invalidate();
CView::OnLButtonUp(nFlags, point);
}
void CMyPaintView::Line(CPoint point1, CPoint point2)
{
CPen pen;
pen.CreatePen(PS_SOLID, GetPenWidth(), GetPaintColor());
CPen* pOldPen = (CPen*)m_pdcMem->SelectObject(&pen);
m_pdcMem->MoveTo(point1);
m_pdcMem->LineTo(point2);
m_pdcMem->SelectObject(pOldPen);
}
void CMyPaintView::SetPixel(CDC* pDC,CPoint point,int nPenWidth)
{
CPen pen;
pen.CreatePen(PS_SOLID, nPenWidth, GetPaintColor());
CPen* pOldPen = (CPen*)pDC->SelectObject(&pen);
pDC->MoveTo(m_ptStart);
pDC->LineTo(point);
pDC->SelectObject(pOldPen);
}
BOOL CMyPaintView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
HCURSOR hCursor = NULL;
switch(m_emPaintType)
{
case LINE:
hCursor = AfxGetApp()->LoadCursor(IDC_LINE);
break;
case PEN:
hCursor = AfxGetApp()->LoadCursor(IDC_PEN);
break;
case BRUSH:
hCursor = AfxGetApp()->LoadCursor(IDC_BRUSH);
break;
case ERASER:
hCursor = AfxGetApp()->LoadCursor(IDC_ERASER);
break;
case FILL:
hCursor = AfxGetApp()->LoadCursor(IDC_FILL);
break;
case RECT:
hCursor = AfxGetApp()->LoadCursor(IDC_LINE);
break;
default:
break;
}
if ( hCursor )
{
::SetCursor(hCursor);
return TRUE;
}
else
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CMyPaintView::Fill(CDC *pDC, CPoint point)
{
CBrush brush;
brush.CreateSolidBrush(GetPaintColor());
CBrush* pOldBrush = (CBrush*)pDC->SelectObject(&brush);
pDC->ExtFloodFill(point.x,point.y,pDC->GetPixel(point),FLOODFILLSURFACE);
pDC->SelectObject(pOldBrush);
}
void CMyPaintView::EraserBox(CDC* pDC, CPoint point)
{//|PS_INSIDEFRAME | PS_ENDCAP_ROUND
CPen pen( PS_SOLID , 9, GetCanvasColor());
CPen* pOldPen = (CPen*)pDC->SelectObject(&pen);
/*
CBrush brush;
brush.CreateSolidBrush(GetCanvasColor());
CBrush* pOldBrush = (CBrush*)pDC->SelectObject(&brush);
*/
// pDC->Rectangle(point.x-5,point.y-5,point.x+5,point.y+5);
pDC->MoveTo(m_ptStart);
pDC->LineTo(point);
// pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
void CMyPaintView::Rectangle(CDC *pDC, CPoint ptUpperLeft, CPoint ptLowerLeft, BOOL bXorROP)
{
CPen pen;
if ( !bXorROP )
pen.CreateStockObject(WHITE_PEN);
else
pen.CreatePen(PS_SOLID, GetPenWidth(), GetPaintColor());
CPen* pOldPen = (CPen*)pDC->SelectObject(&pen);
CBrush brush;
if ( bXorROP )
brush.CreateSolidBrush(GetCanvasColor());
else
{
brush.CreateStockObject(NULL_BRUSH);
pDC->SetROP2(R2_XORPEN);
}
CBrush* pOldBrush = (CBrush*)pDC->SelectObject(&brush);
pDC->Rectangle(ptUpperLeft.x,ptUpperLeft.y,ptLowerLeft.x,ptLowerLeft.y);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
void CMyPaintView::OnUpdateButtonRect(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==RECT);
}
void CMyPaintView::OnButtonRect()
{
// TODO: Add your command handler code here
m_emPaintType = RECT;
SetSelBox(SEL_RECTTYPE);
}
void CMyPaintView::OnUpdateButtonPolygon(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==POLYGON);
}
void CMyPaintView::OnButtonPolygon()
{
// TODO: Add your command handler code here
m_emPaintType = POLYGON;
SetSelBox(SEL_RECTTYPE);
}
void CMyPaintView::OnUpdateButtonRoundRect(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==ROUND_RECT);
}
void CMyPaintView::OnButtonRoundRect()
{
// TODO: Add your command handler code here
m_emPaintType = ROUND_RECT;
SetSelBox(SEL_RECTTYPE);
}
void CMyPaintView::OnUpdateButtonEllipse(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_emPaintType==ELLIPSE);
}
void CMyPaintView::OnButtonEllipse()
{
// TODO: Add your command handler code here
m_emPaintType = ELLIPSE;
SetSelBox(SEL_RECTTYPE);
}
void CMyPaintView::OnEditUndo()
{
// TODO: Add your command handler code here
Restore();
}
void CMyPaintView::OnEditRedo()
{
// TODO: Add your command handler code here
}
void CMyPaintView::Backup()
{
ASSERT(m_pbyBitmapBuf);
m_pbmBackground->GetBitmapBits(m_dwSizeBitmap,m_pbyBitmapBuf);
m_bmBackup.DeleteObject();
m_bmBackup.CreateBitmap(m_nScreenW,m_nScreenH,
1, 32, m_pbyBitmapBuf);
}
void CMyPaintView::Restore()
{
m_bmBackup.GetBitmapBits(m_dwSizeBitmap,m_pbyBitmapBuf);
m_pbmBackground->DeleteObject();
m_pbmBackground->CreateBitmap(m_nScreenW,m_nScreenH,
1, 32, m_pbyBitmapBuf);
UpdateImage();
}