www.gusucode.com > 类似画笔的绘图控件源代码C++源码程序 > 类似画笔的绘图控件源代码/WinPainter21/WinPainter/Demo1View.cpp

    // Demo1View.cpp : implementation of the CDemo1View class
//

#include "stdafx.h"
#include "resource.h"

#include "Demo1Doc.h"
#include "Demo1View.h"

#include "Draw.h"
#include "bitmap.h"
#include <windowsx.h>
#include "structure.h"
#include "TextDlg.h"

#define WIDTH_THIN  1
#define WIDTH_NORMAL  3
#define WIDTH_WIDE  5

#define UD_WHITE  0
#define UD_BLACK  0xffffff
#define UD_YELLOW  0x00ffff
#define UD_PINK  0xff80ff
#define UD_CYAN 0xffff00
#define UD_GRAY 0x4080

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDemo1View

IMPLEMENT_DYNCREATE(CDemo1View, CView)

BEGIN_MESSAGE_MAP(CDemo1View, CView)
	//{{AFX_MSG_MAP(CDemo1View)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_UPDATE_COMMAND_UI(IDT_SELECT, OnUpdateArrow)
	ON_UPDATE_COMMAND_UI(IDT_LINE, OnUpdateLine)
	ON_UPDATE_COMMAND_UI(IDT_RECTANGLE, OnUpdateRectangle)
	ON_UPDATE_COMMAND_UI(IDT_ELLIPSE, OnUpdateEllipse)
	ON_UPDATE_COMMAND_UI(IDT_CIRCLE, OnUpdateCircle)
	ON_UPDATE_COMMAND_UI(IDT_POLY, OnUpdatePline)
	ON_UPDATE_COMMAND_UI(IDT_FONT, OnUpdateFont)
	ON_COMMAND(IDT_LINE, OnLine)
	ON_COMMAND(IDT_RECTANGLE, OnRectangle)
	ON_COMMAND(IDT_ELLIPSE, OnEllipse)
	ON_COMMAND(IDT_CIRCLE, OnCircle)
	ON_COMMAND(IDT_FONT, OnFont)
	ON_COMMAND(ID_FILE_NEW, OnFileNew)
	ON_COMMAND(IDT_SELECT, OnSelect)
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
	ON_COMMAND(ID_EDIT_CUT, OnEditCut)
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_COLOR_BLACK, OnColorBlack)
	ON_COMMAND(ID_COLOR_CYAN, OnColorCyan)
	ON_COMMAND(ID_COLOR_GRAY, OnColorGray)
	ON_COMMAND(ID_COLOR_GREEN, OnColorGreen)
	ON_COMMAND(ID_COLOR_PINK, OnColorPink)
	ON_COMMAND(ID_COLOR_RED, OnColorRed)
	ON_COMMAND(ID_COLOR_WHITE, OnColorWhite)
	ON_COMMAND(ID_COLOR_YELLOW, OnColorYellow)
	ON_COMMAND(ID_COLOR_BLUE, OnColorBlue)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
	ON_UPDATE_COMMAND_UI(IDT_SELECT, OnUpdateSelect)
	ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
	ON_WM_PAINT()
	ON_COMMAND(IDT_CURVE, OnCurve)
	ON_COMMAND(IDT_POLY, OnPoly)
	ON_WM_LBUTTONDBLCLK()
	ON_COMMAND(ID_WIDTH_NORMAL, OnWidthNormal)
	ON_COMMAND(ID_WIDTH_THIN, OnWidthThin)
	ON_COMMAND(ID_WIDTH_WIDE, OnWidthWide)
	ON_COMMAND(ID_FILL_FALSE, OnFillFalse)
	ON_COMMAND(ID_FILL_TRUE, OnFillTrue)
	ON_UPDATE_COMMAND_UI(ID_FILL_TRUE, OnUpdateFillTrue)
	ON_UPDATE_COMMAND_UI(ID_FILL_FALSE, OnUpdateFillFalse)
	ON_UPDATE_COMMAND_UI(ID_WIDTH_NORMAL, OnUpdateWidthNormal)
	ON_UPDATE_COMMAND_UI(ID_WIDTH_THIN, OnUpdateWidthThin)
	ON_UPDATE_COMMAND_UI(ID_WIDTH_WIDE, OnUpdateWidthWide)
	ON_UPDATE_COMMAND_UI(IDT_CURVE, OnUpdateCurve)
	ON_UPDATE_COMMAND_UI(ID_COLOR_BLACK, OnUpdateColorBlack)
	ON_UPDATE_COMMAND_UI(ID_COLOR_BLUE, OnUpdateColorBlue)
	ON_UPDATE_COMMAND_UI(ID_COLOR_CYAN, OnUpdateColorCyan)
	ON_UPDATE_COMMAND_UI(ID_COLOR_GRAY, OnUpdateColorGray)
	ON_UPDATE_COMMAND_UI(ID_COLOR_GREEN, OnUpdateColorGreen)
	ON_UPDATE_COMMAND_UI(ID_COLOR_PINK, OnUpdateColorPink)
	ON_UPDATE_COMMAND_UI(ID_COLOR_RED, OnUpdateColorRed)
	ON_UPDATE_COMMAND_UI(ID_COLOR_WHITE, OnUpdateColorWhite)
	ON_UPDATE_COMMAND_UI(ID_COLOR_YELLOW, OnUpdateColorYellow)
	//}}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()

/////////////////////////////////////////////////////////////////////////////
// CDemo1View construction/destruction

CDemo1View::CDemo1View()
{
	// TODO: add construction code here
	m_bDrawing=false;
	m_nMouseMode = IDT_LINE;
	m_usrCurrentObject = NULL;
	m_nCurrentColor = UD_RED;
	m_iPenWidth = WIDTH_THIN;
	m_bFill = false;
	m_pSelect = NULL;              //没有选中区域
	m_bClip = false;               //剪贴扳为空 
	virtualline=false;
	m_pStack =new Stack(3);        //栈的大小
	m_bFirstSave = true;           //可以保存空白屏幕
	m_bShowGrid = false;
}

CDemo1View::~CDemo1View()
{
	if(m_pSelect)
	{
		delete m_pSelect;
		m_pSelect = NULL;
	}
	if(m_pStack)
	{
		delete m_pStack;
		m_pStack = NULL;
	}
	if(m_usrCurrentObject)
	{
		delete m_usrCurrentObject;
		m_usrCurrentObject = NULL;
	}
}

BOOL CDemo1View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	//加载自定义光标资源
	m_hcurCross = (HCURSOR)::LoadImage(cs.hInstance,
		MAKEINTRESOURCE(IDC_USERDRAW), IMAGE_CURSOR,
		32, 32, LR_DEFAULTCOLOR);

	//加载光标的类方法(与上述方法功能类似)
	CWinApp* pApp = ::AfxGetApp();//获得当前CWinApp对象指针

	m_hcurMoving = pApp->LoadCursor(IDC_USERMOVING);
	m_hcurArrow = pApp->LoadCursor(IDC_USERARROW);

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDemo1View drawing

void CDemo1View::OnDraw(CDC* pDC)
{
	CDemo1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CDemo1View printing

BOOL CDemo1View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CDemo1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CDemo1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CDemo1View diagnostics

#ifdef _DEBUG
void CDemo1View::AssertValid() const
{
	CView::AssertValid();
}

void CDemo1View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDemo1Doc* CDemo1View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDemo1Doc)));
	return (CDemo1Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDemo1View message handlers

void CDemo1View::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CDC* pDC = GetDC();//获得DC
	OnPrepareDC(pDC);//设置DC的滚动属性,与ScollView的滚动有关
	pDC->DPtoLP(&point);//转换当前点为逻辑位置坐标
	CDemo1Doc* pDoc = GetDocument();

	CRect client;
	GetClientRect(&client);//获得客户区范围
	ClientToScreen(&client);//转化为屏幕坐标
	::ClipCursor(&client);//锁定鼠标移动范围

	switch(m_nMouseMode)
	{
	case IDT_SELECT:
		if(!m_pSelect)//如果没选中
		{
			m_bDrawing = true;
			m_pSelect = new CDrawSelect(m_nCurrentColor);
			m_pSelect->NewPoint(point.x, point.y);
			break;
		}
		else//如果选中
		{
			CDC * pDC = GetDC();
			m_pSelect->Clear(pDC);
			m_bDrawing = false;

			if (m_pSelect->isin(point))//如果鼠标进入
			{ 
				m_pSelect->maponmouse=true;	
				m_pSelect->p_maponmouse.x=point.x;
				m_pSelect->p_maponmouse.y=point.y;
				if (!(m_pSelect->copied))//如果没有存储两个图	
				{
					m_pSelect->maponmouse=true;
					m_pSelect->copied=true;
					Selected_Copy();
					Back_CutCopy();
					ReleaseDC(pDC);
				}
				break;
			}
			else//如果落在选中的矩形外边
			{
				virtualline=false;
				delete m_pSelect;
				m_pSelect = NULL;
				break;
			}			
		}
	case IDT_LINE:
		m_bDrawing = true;
		m_usrCurrentObject = new CDrawLine(m_nCurrentColor, m_iPenWidth);
		m_usrCurrentObject->NewPoint(point.x, point.y);
		break;
	case IDT_CURVE:
		m_bDrawing = true;
		m_usrCurrentObject = new CDrawCurve(m_nCurrentColor, m_iPenWidth);
		m_usrCurrentObject->NewPoint(point.x, point.y);
		break;
	case IDT_RECTANGLE:
		m_bDrawing = true;
		m_usrCurrentObject = new CDrawRect(m_nCurrentColor, m_iPenWidth, m_bFill);
		m_usrCurrentObject->NewPoint(point.x, point.y);
		break;
	case IDT_ELLIPSE:
		m_bDrawing = true;
		m_usrCurrentObject = new CDrawEllipse(m_nCurrentColor, m_iPenWidth, m_bFill);
		m_usrCurrentObject->NewPoint(point.x, point.y);
		break;
	case IDT_CIRCLE:
		m_bDrawing = true;
		m_usrCurrentObject = new CDrawCircle(m_nCurrentColor, m_iPenWidth, m_bFill);
		m_usrCurrentObject->NewPoint(point.x, point.y);
		break;
	case IDT_POLY:
		if(m_usrCurrentObject)
		{
			m_usrCurrentObject->AddPoint(point.x, point.y);
//			if(!m_nMoveMode)
//			{//输入端点超过20个
//				OnRButtonDown(nFlags, point);
//			}
		}
		else
		{
			m_bDrawing = true;
			m_usrCurrentObject = new CDrawPoly(m_nCurrentColor, m_iPenWidth);
			m_usrCurrentObject->NewPoint(point.x, point.y);
		}
		break;
	}
	ReleaseDC(pDC);//释放DC资源
	CView::OnLButtonDown(nFlags, point);
}

void CDemo1View::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CDC* pDC = GetDC();
	OnPrepareDC(pDC);
	pDC->DPtoLP(&point);
	if(m_bDrawing && m_usrCurrentObject)
	{
		m_usrCurrentObject->MoveAt(pDC, point.x, point.y);	
	}
	if( m_pSelect && m_nMouseMode==IDT_SELECT)//如果是选中状态
		if(m_bDrawing )//如果在画虚框
			m_pSelect->MoveAt(pDC, point.x, point.y);
		else
			if (m_pSelect->maponmouse)	//如果拖动选中则移动选中的部分
			{
			CDC  dc;
			CClientDC pdc(this);
			if(!dc.CreateCompatibleDC(pDC))
				return;
			BITMAP  bm;
			m_pSelect->backmap.GetBitmap(&bm);
			CBitmap *pOldBitmap=dc.SelectObject(&m_pSelect->backmap);
			pdc.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
			m_pSelect->map_select.GetBitmap(&bm);
			pOldBitmap=dc.SelectObject(&m_pSelect->map_select);
			pdc.BitBlt(m_pSelect->GetX()+point.x-m_pSelect->p_maponmouse.x
				, m_pSelect->GetY()+point.y-m_pSelect->p_maponmouse.y,
				bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
			dc.SelectObject(&pOldBitmap);		
			}
	ReleaseDC(pDC);//释放DC资源
	
	CView::OnMouseMove(nFlags, point);
}

void CDemo1View::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CDC* pDC = GetDC();//获得DC
	OnPrepareDC(pDC);//设置DC的滚动属性,与ScollView的滚动有关
	pDC->DPtoLP(&point);//转换当前点为逻辑位置坐标
	CDemo1Doc* pDoc = GetDocument();

	switch(m_nMouseMode)
	{
	case IDT_LINE:
	case IDT_RECTANGLE:
	case IDT_ELLIPSE:
	case IDT_CIRCLE:
	case IDT_CURVE:
		m_usrCurrentObject->Draw(pDC);
		SaveInStack();
		::ClipCursor(NULL);//释放鼠标锁定
		m_bDrawing = false;
		delete m_usrCurrentObject;
		m_usrCurrentObject = NULL;
		break;
	case IDT_SELECT:
		::ClipCursor(NULL);//释放鼠标锁定
		if (m_pSelect)
			if (m_bDrawing)
			{
				m_bDrawing=false;
				virtualline=true;
			}
			else//不在画虚框则释放鼠标
			{			
				if  (m_pSelect->maponmouse==true)
				{
					SaveInStack();
					m_pSelect->maponmouse=false;
					long w=m_pSelect->GetWidth();
					long h=m_pSelect->GetHeight();
					long x=m_pSelect->GetX()+point.x-m_pSelect->p_maponmouse.x;
					long y=m_pSelect->GetY()+point.y-m_pSelect->p_maponmouse.y;
					m_pSelect->Set(pDC,x,y,w,h);
					m_bDrawing=false;
					virtualline=true;
				}
			}						
			break;
	}
	ReleaseDC(pDC);//释放DC资源

	CView::OnLButtonUp(nFlags, point);
}

void CDemo1View::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	
	// TODO: Add your specialized code here and/or call the base class
	CSize size(2000, 2000);//设置绘图区范围为:1280*1024
}

void CDemo1View::OnUpdateArrow(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_SELECT);
}

void CDemo1View::OnUpdateLine(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_LINE);
}

void CDemo1View::OnUpdateRectangle(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_RECTANGLE);
}

void CDemo1View::OnUpdateEllipse(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_ELLIPSE);
}

void CDemo1View::OnUpdateCircle(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_CIRCLE);
}

void CDemo1View::OnUpdatePline(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_POLY);
}

void CDemo1View::OnUpdateFont(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_FONT);
}

void CDemo1View::OnLine() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_LINE;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurCross);//修改缺省光标
}

void CDemo1View::OnRectangle() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_RECTANGLE;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurCross);//修改缺省光标
}

void CDemo1View::OnEllipse() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_ELLIPSE;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurCross);//修改缺省光标
}

void CDemo1View::OnCircle() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_CIRCLE;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurCross);//修改缺省光标
}

void CDemo1View::OnFont() 
{
	// TODO: Add your command handler code here
	CDC*  pDC = GetDC();
	LOGFONT  m_lFont;
	COLORREF  m_cTextColor;
	CFont  myFont;
	CFont* pOldFont;

	CFontDialog  FontDlg;
	FontDlg.m_cf.lpLogFont = &m_lFont;
	FontDlg.m_cf.rgbColors = m_cTextColor;
	FontDlg.m_cf.Flags != CF_INITTOLOGFONTSTRUCT;

	if( FontDlg.DoModal() == IDOK )
	{
		FontDlg.GetCurrentFont(&m_lFont);
		m_cTextColor = FontDlg.GetColor();
	}

	CString str;
	CTextDlg   TextDlg;
//	CRect rect(TextDlg.m_ctrEdit.GetClientRect());

	if( TextDlg.DoModal() == IDOK )
	{
		CRect rect(TextDlg.m_iPosX, TextDlg.m_iPosY,
			TextDlg.m_iPosX + 100, TextDlg.m_iPosY + 100);
		str = TextDlg.m_sText;
		myFont.CreateFontIndirect(&m_lFont);
		pOldFont = pDC->SelectObject(&myFont);
		pDC->SetTextColor(m_cTextColor);
		pDC->DrawText(str, rect, 0);
		pDC->SelectObject(pOldFont);
		SaveInStack();
	}
}

void CDemo1View::OnFileNew(CString name) 
{
	// TODO: Add your command handler code here
	m_strName = name;
	m_usrCurrentObject = NULL;
	m_bDrawing=false;
	m_nMouseMode = IDT_LINE;
	m_usrCurrentObject = NULL;
	m_nCurrentColor = UD_RED;
	m_iPenWidth = WIDTH_THIN;
	m_bFill = false;
	m_pSelect = NULL;              //没有选中区域
	m_bClip = false;               //剪贴扳为空 
	virtualline=false;
	delete m_pStack;
	m_pStack =new Stack(3);        //栈的大小
	m_bFirstSave = true;           //可以保存空白屏幕
	m_bShowGrid = false;

	CDC* pDC = GetDC();
	CRect rect;
	GetClientRect(&rect);
	pDC->BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, WHITENESS);
	OnPaint();
}

void CDemo1View::OnSelect() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_SELECT;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurArrow);//修改缺省光标
}

void CDemo1View::OnEditCopy() 
{
	// TODO: Add your command handler code here
	if (m_bShowGrid) 
		Grid();
	if( !m_pSelect )
		return;
	m_bClip = true;
	CBitmap 	bitmap;
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	long  width = m_pSelect->GetWidth();
	long  height = m_pSelect->GetHeight();
	long x = m_pSelect->GetX();
	long y = m_pSelect->GetY();

	memDC.CreateCompatibleDC(&dc);
	dc.OffsetViewportOrg(x+1, y+1);
	bitmap.CreateCompatibleBitmap(&dc, width-1, height-1);
	
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, width, height, &dc, 0, 0, SRCCOPY);

	OpenClipboard();
	EmptyClipboard();
	SetClipboardData(CF_BITMAP, bitmap.GetSafeHandle());
	CloseClipboard();

	memDC.SelectObject(pOldBitmap);
	bitmap.Detach();
	virtualline=true;
	if (m_bShowGrid) Grid();
}

void CDemo1View::OnEditCut()
{
	if (m_bShowGrid) Grid();
	if( !m_pSelect )
		return;
	CDC *pdc = GetDC();
	m_bClip = true;
	CBitmap 	bitmap;
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	GetWindowRect(rect);

	m_pSelect->Clear(pdc);
	long  width = m_pSelect->GetWidth();
	long  height = m_pSelect->GetHeight();
	long x = m_pSelect->GetX();
	long y = m_pSelect->GetY();
	
	memDC.CreateCompatibleDC(&dc); 
	dc.OffsetViewportOrg(x, y);
	bitmap.CreateCompatibleBitmap(&dc, width, height);
		
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, width, height, &dc, 0, 0, SRCCOPY);

	OpenClipboard();
	EmptyClipboard();
	SetClipboardData (CF_BITMAP, bitmap.GetSafeHandle() );
	CloseClipboard();

    dc.OffsetViewportOrg(-x, -y);
	
	if (!(m_pSelect->copied))//如果剪切的还没复制过就变白
	{
		pdc->BitBlt(x, y, width+1, height+1, &dc, 0, 0, WHITENESS);

		Back_Copy();
		memDC.SelectObject(pOldBitmap);
		bitmap.Detach();	
	}
	else	//如果剪切的已经复制,不变白
	{		
		CDC* pDC = GetDC();
		CDC  dc;
		CClientDC pdc(this);
		if(!dc.CreateCompatibleDC(pDC))
			return;
		BITMAP  bm;	
		m_pSelect->backmap.GetBitmap(&bm);
		CBitmap *pOldBitmap=dc.SelectObject(&m_pSelect->backmap);
		pdc.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
		dc.SelectObject(&pOldBitmap);
	}
	m_pSelect->Set(pdc,-width,-height,width,height);
	if (m_bShowGrid) 
		Grid();
	virtualline=false;
	SaveInStack();
}

void CDemo1View::OnEditDelete()
{
	if( !m_pSelect )
		return;
	CDC *pdc = GetDC();
	m_bClip = true;
	CBitmap 	bitmap;
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	GetWindowRect(rect);

	m_pSelect->Clear(pdc);
	long  width = m_pSelect->GetWidth();
	long  height = m_pSelect->GetHeight();
	long x = m_pSelect->GetX();
	long y = m_pSelect->GetY();
	
	memDC.CreateCompatibleDC(&dc); 
	dc.OffsetViewportOrg(x, y);
	bitmap.CreateCompatibleBitmap(&dc, width, height);
		
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, width, height, &dc, 0, 0, SRCCOPY);

	OpenClipboard();
	EmptyClipboard();
	SetClipboardData (CF_BITMAP, bitmap.GetSafeHandle() );
	CloseClipboard();

    dc.OffsetViewportOrg(-x, -y);
	
	if (!(m_pSelect->copied))//如果剪切的还没复制过就变白
	{
		pdc->BitBlt(x, y, width+1, height+1, &dc, 0, 0, WHITENESS);

		Back_Copy();
		memDC.SelectObject(pOldBitmap);
		bitmap.Detach();
		//bit1=bitmap;
	
	}
	else	//如果剪切的已经复制,不变白
	{		
		CDC* pDC = GetDC();
		CDC  dc;
		CClientDC pdc(this);
		if(!dc.CreateCompatibleDC(pDC))
			return;
		BITMAP  bm;	
		m_pSelect->backmap.GetBitmap(&bm);
		CBitmap *pOldBitmap=dc.SelectObject(&m_pSelect->backmap);
		pdc.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
		dc.SelectObject(&pOldBitmap);
	}
	virtualline=false;

	SaveInStack();
}

void CDemo1View::OnEditPaste() 
{
	// TODO: Add your command handler code here
	if( !GetPasteState() )
		return;
	CDC  dc;
	CDC * pDC = GetDC();

	if (virtualline && m_pSelect)
		m_pSelect->Clear(pDC);

	m_pSelect = new CDrawSelect(m_nCurrentColor);
	
	Back_Copy();//保存背景图

	if(!dc.CreateCompatibleDC(pDC))
		return;
	BITMAP  bm;
	HBITMAP  hBitmap;

	OpenClipboard();
	hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

    m_pSelect->map_select.Detach();
	m_pSelect->map_select.Attach(hBitmap);
	m_pSelect->map_select.GetBitmap(&bm);
	dc.SelectObject(&m_pSelect->map_select);
	pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
	CloseClipboard();

	m_pSelect->Set(pDC,0,0,bm.bmWidth,bm.bmHeight);
	m_bDrawing=false;
	m_pSelect->copied=true;	
	virtualline=true;
}

bool CDemo1View::OnFileSave(CString name) 
{
	// TODO: Add your command handler code here
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	GetClientRect(rect);
	memDC.CreateCompatibleDC(&dc);
	CBitmap bm;
	int Width = rect.Width();
	int Height = rect.Height();
	bm.CreateCompatibleBitmap(&dc, Width, Height);
	CBitmap*  pOld = memDC.SelectObject(&bm);
	memDC.BitBlt(0, 0, Width, Height, &dc, 0, 0, SRCCOPY);
	memDC.SelectObject(pOld);
	BITMAP  btm;
	bm.GetBitmap(&btm);
	DWORD  size = btm.bmWidthBytes * btm.bmHeight;
	LPSTR lpData = (LPSTR)GlobalAllocPtr(GPTR, size);
	BITMAPFILEHEADER   bfh;
	/////////////////////////////////////////////
	BITMAPINFOHEADER  bih;
	bih.biBitCount = btm.bmBitsPixel;
	bih.biClrImportant = 0;
	bih.biClrUsed = 0;
	bih.biCompression = 0;
	bih.biHeight = btm.bmHeight;
	bih.biPlanes = 1;
	bih.biSize = sizeof(BITMAPINFOHEADER);
	bih.biSizeImage = size;
	bih.biWidth = btm.bmWidth;
	bih.biXPelsPerMeter = 0;
	bih.biYPelsPerMeter = 0;
	GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
	//bm.GetBitmapBits(size,lpData);//此函数在处理5-5-5模式的16位色下会出现颜色混乱
	bfh.bfReserved1 = bfh.bfReserved2 = 0;
	bfh.bfType = ((WORD)('M'<< 8)|'B');
	bfh.bfSize = 54 + size;
	bfh.bfOffBits = 54;
/*
	CFileDialog dlg(false,_T("BMP"),_T("*.bmp"),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("*.bmp|*.bmp|*.*|*.*|"));
	if (dlg.DoModal()!=IDOK)
		return;

*/	
	CString s;
	if(name == "")
		s = m_strName;
	else
		s = name;

	CFile  bf;
	if(bf.Open( (LPCTSTR)s, CFile::modeCreate | CFile::modeWrite))
	{
		bf.WriteHuge(&bfh, sizeof(BITMAPFILEHEADER));
		bf.WriteHuge(&bih, sizeof(BITMAPINFOHEADER));
		bf.WriteHuge(lpData, size);
		bf.Close();
	}
	else
		return false;
	GlobalFreePtr(lpData);
	AfxMessageBox("保存成功");
	return true;
}

bool CDemo1View::OnFileOpen(CString name)
{
	// TODO: Add your command handler code here
//	m_strFileName = name;
	CDC  dc;
	CDC * pDC = GetDC();
	if(!dc.CreateCompatibleDC(pDC))
		return  false;
	CBitmap b;
	BITMAP  bm;

	CString  path;
//	CFileDialog dlg(true,_T("BMP"),_T("*.bmp"),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("*.bmp|*.bmp|*.*|*.*|"));
//	if (dlg.DoModal()==IDOK)
//	{
//		path =dlg.GetPathName();
//	}
//	else 
//		return;
	HBITMAP  hbmp = (HBITMAP)LoadImage(NULL, name, IMAGE_BITMAP,
		0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
	b.Attach(hbmp);

	b.GetBitmap(&bm);
	dc.SelectObject(&b);
	pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
	return true;
}

void CDemo1View::OnColorBlack() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_BLACK;
}

void CDemo1View::OnColorBlue() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_BLUE;
}

void CDemo1View::OnColorCyan() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_CYAN;	
}

void CDemo1View::OnColorGray() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_GRAY;
}

void CDemo1View::OnColorGreen() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_GREEN;
}

void CDemo1View::OnColorPink() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_PINK;
}

void CDemo1View::OnColorRed() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_RED;
}

void CDemo1View::OnColorWhite() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_WHITE;	
}

void CDemo1View::OnColorYellow() 
{
	// TODO: Add your command handler code here
	m_nCurrentColor = UD_YELLOW;
}

void CDemo1View::OnUpdateEditCut(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(virtualline);
}

void CDemo1View::OnUpdateEditPaste(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bClip);
}

void CDemo1View::OnUpdateEditCopy(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(virtualline);
}

void CDemo1View::Selected_Copy()
{
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	GetWindowRect(rect);
	long  width = m_pSelect->GetWidth();
	long  height = m_pSelect->GetHeight();
	long x = m_pSelect->GetX();
	long y = m_pSelect->GetY();
	memDC.CreateCompatibleDC(&dc);
  	dc.OffsetViewportOrg(x, y);
	m_pSelect->map_select.CreateCompatibleBitmap(&dc, width, height);
	CBitmap* pOldBitmap = memDC.SelectObject(&m_pSelect->map_select);
	memDC.BitBlt(0, 0, width, height, &dc, 0, 0, SRCCOPY);
	memDC.SelectObject(pOldBitmap);
}

void CDemo1View::Back_Copy()
{
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	GetWindowRect(rect);
	CBitmap *pOldBitmap;
	memDC.CreateCompatibleDC(&dc);
	m_pSelect->backmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height());
	pOldBitmap = memDC.SelectObject(&m_pSelect->backmap);
	memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
	memDC.SelectObject(pOldBitmap);
}

void CDemo1View::Back_CutCopy()
{
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	GetWindowRect(rect);
	CBitmap *pOldBitmap;

	long  width = m_pSelect->GetWidth();
	long  height = m_pSelect->GetHeight();
	long x = m_pSelect->GetX();
	long y = m_pSelect->GetY();

 	memDC.CreateCompatibleDC(&dc);
	m_pSelect->backmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height());
	pOldBitmap = memDC.SelectObject(&m_pSelect->backmap);
	memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
 	memDC.BitBlt(x, y, width, height, &dc, 0, 0, WHITENESS);
	memDC.SelectObject(pOldBitmap);
}

void CDemo1View::OnUpdateSelect(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(m_nMouseMode==IDT_SELECT);// TODO: Add your command update UI handler code here
	
}

void CDemo1View::SaveInStack()
{
	CClientDC	dc(this);
	CDC 		memDC;
	CRect		rect;
	CBitmap     bitmap,b1;
	HBITMAP      bm;
	GetWindowRect(rect);
	CBitmap *pOldBitmap;
	memDC.CreateCompatibleDC(&dc);
	bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height());
	pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);

	bm=(HBITMAP)bitmap.GetSafeHandle();
	m_pStack->Add(bm);
	memDC.SelectObject(pOldBitmap);
	bitmap.Detach();
}

void CDemo1View::OnEditRedo() 
{
	if( !CanRedo() )
		return;
	//释放选中的对象,销去虚线框
	if(m_pSelect)
	{
		if (virtualline)
			m_pSelect->Clear(GetDC());
		delete m_pSelect;
		m_pSelect=NULL;
	}
	virtualline=false;
//////////////////////////	
	if (m_bShowGrid)
		Grid();

	CDC  dc;
	CDC * pDC = GetDC();
	if(!dc.CreateCompatibleDC(pDC))
		return;
	BITMAP  bm;
	CBitmap cb1;
	cb1.Attach(m_pStack->Redo());
	cb1.GetBitmap(&bm);
	dc.SelectObject(&cb1);
	pDC->BitBlt(0,0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
	cb1.Detach();
}

void CDemo1View::OnEditUndo() 
{
	if( !CanUndo() )
		return;
	//释放选中的对象,销去虚线框
	if(m_pSelect)
	{
		if (virtualline)
			m_pSelect->Clear(GetDC());
		delete m_pSelect;
		m_pSelect=NULL;
	}
	virtualline=false;
///////////////////////////////////

	if (m_bShowGrid)
		Grid();
	CDC  dc;
	CDC * pDC = GetDC();
	if(!dc.CreateCompatibleDC(pDC))
		return;
	BITMAP  bm;
	CBitmap cb1;
	cb1.Attach(m_pStack->Undo());
	cb1.GetBitmap(&bm);
	dc.SelectObject(&cb1);
	pDC->BitBlt(0,0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
	cb1.Detach();
}

void CDemo1View::OnUpdateEditUndo(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_pStack->CanUndo());
}

void CDemo1View::OnUpdateEditRedo(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_pStack->CanRedo());
}

void CDemo1View::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	// Do not call CView::OnPaint() for painting messages
	if(m_bFirstSave)
	{
		SaveInStack();

		m_bFirstSave = false;
	}
	
	CDC*  pDC = GetDC();
	if( m_pStack->CanUndo() )
	{
		CDC  dc;
		if(!dc.CreateCompatibleDC(pDC))
			return;
		BITMAP  bm;
		CBitmap cb;
		cb.Attach(m_pStack->Pop());
		cb.GetBitmap(&bm);
		dc.SelectObject(&cb);
		pDC->BitBlt(0,0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
		cb.Detach();
	}
//如果以前选中并有虚线,则再现窗口时出现虚线
	if (m_pSelect&&virtualline)
		m_pSelect->Clear(pDC);
/////////////////////////////////////////
	if(m_bShowGrid) Grid();
}

void CDemo1View::OnCurve() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_CURVE;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurArrow);//修改缺省光标
}

void CDemo1View::OnPoly() 
{
	// TODO: Add your command handler code here
	m_nMouseMode = IDT_POLY;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurCross);//修改缺省光标
}


void CDemo1View::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CDemo1Doc* pDoc = GetDocument();
	CDC* pDC = GetDC();//获得DC

	if(m_nMouseMode == IDT_POLY && m_usrCurrentObject)
	{
		m_usrCurrentObject->EndPoint(pDC);
		SaveInStack();
		::ClipCursor(NULL);//释放鼠标锁定
		delete m_usrCurrentObject;
		m_bDrawing = false;
		m_usrCurrentObject = NULL;
	}
	ReleaseDC(pDC);//释放DC资源
	
	CView::OnLButtonDblClk(nFlags, point);
}

void CDemo1View::OnWidthNormal() 
{
	// TODO: Add your command handler code here
	m_iPenWidth = WIDTH_NORMAL;
}

void CDemo1View::OnWidthThin()
{
	// TODO: Add your command handler code here
	m_iPenWidth = WIDTH_THIN;
}

void CDemo1View::OnWidthWide() 
{
	// TODO: Add your command handler code here
	m_iPenWidth = WIDTH_WIDE;
}

void CDemo1View::OnFillFalse() 
{
	// TODO: Add your command handler code here
	m_bFill = false;
}

void CDemo1View::OnFillTrue() 
{
	// TODO: Add your command handler code here
	m_bFill = true;
}

void CDemo1View::OnUpdateWidthNormal(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_iPenWidth == WIDTH_NORMAL);	
}

void CDemo1View::OnUpdateWidthThin(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_iPenWidth == WIDTH_THIN);	
}

void CDemo1View::OnUpdateWidthWide(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_iPenWidth == WIDTH_WIDE);
}

void CDemo1View::OnUpdateFillFalse(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_bFill == false);	
}

void CDemo1View::OnUpdateFillTrue(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_bFill == true);
}

BOOL CDemo1View::CanUndo()
{
	return(m_pStack->CanUndo());
}

BOOL CDemo1View::CanRedo()
{
	return(m_pStack->CanRedo());
}

BOOL CDemo1View::GetSelectState()
{
	return (m_pSelect!=NULL);
}

BOOL CDemo1View::GetPasteState()
{
	return (m_bClip);
}

void CDemo1View::Grid()
{
	CDC *pdc = GetDC();
	CRect		rect;
	GetWindowRect(rect);
	int w = rect.Width();
	int h = rect.Height();

	COLORREF XorColor = pdc->GetBkColor()^RGB(128,128,128) ;
	CPen pen(PS_SOLID, 1, XorColor), *oldpen;
	int oldmode = pdc->GetROP2();
	oldpen = pdc->SelectObject(&pen);
	pdc->SetROP2(R2_XORPEN);

	for(int i = 0; i < 12; i ++)
	{
		pdc->MoveTo(0, (i*w)/12);
		pdc->LineTo(w, i*w/12);
    	pdc->MoveTo(w*i/12, 0);
		pdc->LineTo(w*i/12, h);

	}

	//以下恢复DC
	pdc->SetROP2(oldmode);
	pdc->SelectObject(oldpen);
	pen.DeleteObject();//释放笔资源
}

void CDemo1View::Ongrid() 
{
	// TODO: Add your command handler code here
	Grid();
	m_bShowGrid != m_bShowGrid;
}

void CDemo1View::SetColor(COLORREF color)
{
	m_nCurrentColor = color;
}

void CDemo1View::OnUpdateCurve(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_CURVE);	
}

void CDemo1View::OnUpdateColorBlack(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_BLACK);
}

void CDemo1View::OnUpdateColorBlue(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_BLUE);
}

void CDemo1View::OnUpdateColorCyan(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_CYAN);
}

void CDemo1View::OnUpdateColorGray(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_GRAY);
}

void CDemo1View::OnUpdateColorGreen(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_GREEN);
}

void CDemo1View::OnUpdateColorPink(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_PINK);
}

void CDemo1View::OnUpdateColorRed(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_RED);
}

void CDemo1View::OnUpdateColorWhite(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_WHITE);
}

void CDemo1View::OnUpdateColorYellow(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nCurrentColor == UD_YELLOW);
}