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); }