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

📄 imageeditorview.cpp

📁 在mfc环境下实现的绘图板程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		m_bCurrentObjectIsActive = FALSE;
}
//根据逻辑坐标绘制橡皮线
void CImageEditorView::MyDrawFocusRect(const CPoint& pt1, const CPoint& pt2)
{
	CRect rect(pt1,pt2);
	rect.NormalizeRect();
	this->DocToClient(rect);
	CClientDC dc(this);
	dc.DrawFocusRect(rect);	
	
}

//------------------撤销重做
void CImageEditorView::InitHistory(HBITMAP hBmp)
{
	m_pHistoryStack->Clear();
	m_pHistoryStack->Add(hBmp);
}
//将当前的图像记录到历史堆栈中 并删除当前对象
void CImageEditorView::RecordHistory()
{
	HBITMAP hBmp = CanvasToBmp();
	if (hBmp!=NULL)
	{
		m_pHistoryStack->Add(hBmp);
		delete m_pCurObj;
		m_pCurObj = NULL;
	}
}

void CImageEditorView::OnEditUndo()
{
	if (m_pHistoryStack->CanUndo())
	{
		SetInitState();
		ResetCurrentObj(NULL);
		m_pHistoryStack->Undo();
		this->Invalidate();
	}
}

void CImageEditorView::OnEditRedo()
{
	if (m_pHistoryStack->CanRedo())
	{
		SetInitState();
		ResetCurrentObj(NULL);		
		m_pHistoryStack->Redo();
		this->Invalidate();

	}

}
void CImageEditorView::OnUpdateEditUndo(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_pHistoryStack->CanUndo());
}

void CImageEditorView::OnUpdateEditRedo(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_pHistoryStack->CanRedo());
}

//改变工具样式
void CImageEditorView::OnToolStyleChange(NMHDR *pNMHDR, LRESULT *pResult)
{
	CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	int index = pNMListView->iItem;
	switch (m_nCurToolIndex)
	{
		case ID_EDIT_ZOOM:
		{			
			switch (index)
			{
			case 0:
				SetZoomScale(1);
				break;
			case 1:
				SetZoomScale(1.5);
				break;
			case 2:
				SetZoomScale(2);
				break;
			case 3:
				SetZoomScale(4);
				break;
			default:
				break;
			}
			pMainFrame->m_indexZoom = index;
			break;
		}
		//画刷头样式
	case ID_EDIT_BRUSH:
	case ID_EDIT_ERASER:
		{
			switch (index)
			{
			case 0:
				m_emBrushStyle = CDrawObject::MyPenStyle::psDot2;
				break;
			case 1:
				m_emBrushStyle = CDrawObject::MyPenStyle::psDot3;
				break;
			case 2:
				m_emBrushStyle = CDrawObject::MyPenStyle::psRect1;
				break;
			case 3:
				m_emBrushStyle = CDrawObject::MyPenStyle::psRect2;
				break;
			case 4:
				m_emBrushStyle = CDrawObject::MyPenStyle::psRect3;
				break;
			default:
				m_emBrushStyle = CDrawObject::MyPenStyle::psRect1;
				break;
			}
			pMainFrame->m_indexPenStyle = index;
			break;
		}
		//线宽度
	case ID_EDIT_LINE:
		{
			switch (index)
			{
			case 0:
				m_emLineWidth = 1;
				break;
			case 1:
				m_emLineWidth = 50;
				break;
			case 2:
				m_emLineWidth = 100;
				break;
			case 3:
				m_emLineWidth = 200;
				break;
			case 4:
				m_emLineWidth = 300;
				break;
			default:
				break;
			}
			pMainFrame->m_indexLineStyle = index;
			break;
		}
	case ID_EDIT_RECTANGLE:
	case ID_EDIT_POLYGON:
	case ID_EDIT_ELLIPSE:
	case ID_EDIT_ROUND_RECT:
		{
			switch (index)
			{
			case 0:
				m_emShapeStyle = CDrawObject::ShapeStyle::styleFrameOnly;
				break;
			case 1:
				m_emShapeStyle = CDrawObject::ShapeStyle::styleFillAndFrame;
				break;
			case 2:
				m_emShapeStyle = CDrawObject::ShapeStyle::styleFillOnly;
				break;
			default:
				break;
			}
			pMainFrame->m_indexShapeStyle = index;
			break;
		}
	default:
		break;
	}

}

void CImageEditorView::DrawCanvasTracker(CDC* pDC)
{
	int nHandleCount = 8;
	for (int nHandle = 1; nHandle <= nHandleCount; nHandle += 1)
	{
		CPoint handle = GetCanvasHandle(nHandle);
		pDC->PatBlt(handle.x - 80, handle.y - 80, 160, 160, DSTINVERT);
	}
}
int CImageEditorView::HitCanvasTest(CPoint point)
{
	if (this)
	{
		int nHandleCount = 8;
		for (int nHandle = 1; nHandle <= nHandleCount; nHandle += 1)
		{
			CRect rc = GetCanvasHandleRect(nHandle);
			if (rc.PtInRect(point))
				return nHandle;
		}
	}
	return 0;
}
// 获取拖拽点区域
const int HandleSize = 80;
CRect CImageEditorView::GetCanvasHandleRect(int nHandleID)
{
	CPoint point = GetCanvasHandle(nHandleID);
	CRect rect(point.x-HandleSize, point.y-HandleSize, point.x+HandleSize, point.y+HandleSize);
	rect.NormalizeRect();
	return rect;
}
CPoint CImageEditorView::GetCanvasHandle(int nHandle)
{
	int x, y, xCenter, yCenter;

	CRect runtimeRect(0,0,m_sizeCanvas.cx, m_sizeCanvas.cy);

	// this gets the center regardless of left/right and top/bottom ordering
	xCenter = runtimeRect.left + runtimeRect.Width() / 2;
	yCenter = runtimeRect.top + runtimeRect.Height() / 2;

	switch (nHandle)
	{
	default:
		ASSERT(FALSE);

	case 1:	// left-top
		x = runtimeRect.left;
		y = runtimeRect.top;
		break;

	case 2:	// top-middle
		x = xCenter;
		y = runtimeRect.top;
		break;

	case 3:	// right-top
		x = runtimeRect.right;
		y = runtimeRect.top;
		break;

	case 4:	// right-middle
		x = runtimeRect.right;
		y = yCenter;
		break;

	case 5:	// right-bottom
		x = runtimeRect.right;
		y = runtimeRect.bottom;
		break;

	case 6:	// bottom-middle
		x = xCenter;
		y = runtimeRect.bottom;
		break;

	case 7:	// left-bottom
		x = runtimeRect.left;
		y = runtimeRect.bottom;
		break;

	case 8:	// left-middle
		x = runtimeRect.left;
		y = yCenter;
		break;
	}

	return CPoint(x, y);
}



//
BOOL CImageEditorView::LoadFromString( CString& strSrc)
{
	m_imgCurent.Destroy();
	if (LoadImageFromBase64String(strSrc,&m_imgCurent))
	{
		m_sizeCanvas.SetSize(m_imgCurent.GetWidth(),m_imgCurent.GetHeight());
		this->ClientToDoc(m_sizeCanvas);
		InitHistory(m_imgCurent.Detach());
		UpdateViewSize();
		this->Invalidate();
		return TRUE;
	}
	else
	{
		this->MessageBox(_T("ImageEditor 加载图片失败!"));
		return FALSE;
	}
}
CString CImageEditorView::SaveToString()
{
	CString strSrc = _T("");
	if(!SaveImageToBase64String(strSrc,&m_imgCurent))
		this->MessageBox(_T("ImageEditor 保存图片失败!"));
	return strSrc;
		
}
//把图片进行base64编码 然后保存到字符串中
BOOL CImageEditorView::SaveImageToBase64String(CString& strResult,const CImage* pImg)
{
	ASSERT(pImg!=NULL);
	//把图像到byte数组中
	HGLOBAL m_hMem = GlobalAlloc(GMEM_MOVEABLE, 0);
	IStream *pstm=NULL;
	CreateStreamOnHGlobal(m_hMem, TRUE, &pstm);
	pImg->Save(pstm,Gdiplus::ImageFormatJPEG);
	if (pstm==NULL)
		return FALSE;
	DWORD wByteLen=GlobalSize(m_hMem);
	LPBYTE lpByteData = (LPBYTE)GlobalLock(m_hMem);

	//进行base64编码		
	int iRstLen=Base64EncodeGetRequiredLength(wByteLen);
	char* pResult= new char[iRstLen+1];
	::ZeroMemory(pResult,iRstLen+1);
	if (!Base64Encode(lpByteData,wByteLen,pResult,&iRstLen)) return FALSE;		
	strResult = CString(pResult);		
	delete []pResult;
	return TRUE;
}

//从字符串中加载图片
BOOL CImageEditorView::LoadImageFromBase64String(CString& strSrc,CImage* pImg)
{
	ASSERT(pImg!=NULL);
	int iRstLen=Base64DecodeGetRequiredLength(strSrc.GetLength()); 
	HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, iRstLen);
	if (m_hMem == NULL)
		return FALSE;
	IStream *pstm=NULL;
	CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
	if (pstm==NULL)
		return FALSE;

	BYTE* pByteMem= new BYTE[iRstLen+1];	
	CW2A pszA(strSrc );
    LPCSTR pszTemp = (LPCSTR)pszA;
	if (!Base64Decode(pszTemp,strSrc.GetLength(),pByteMem,&iRstLen)) return FALSE;
	DWORD wTemp= iRstLen;
	pstm->Write(pByteMem,iRstLen,&wTemp);
	pImg->Load(pstm);
	delete []pByteMem;
	return TRUE;
}


//----------------复制 粘贴 删除
void CImageEditorView::OnEditCut()
{

}
void CImageEditorView::OnEditCopy()
{	

}

void CImageEditorView::OnEditPaste()
{

}

void CImageEditorView::OnDelete()
{
	if (m_bCurrentObjectIsActive)
	{
		CDrawArea* pAreaObj = dynamic_cast<CDrawArea*>(m_pCurObj);
		if(pAreaObj)
		{
			pAreaObj->DestroyImage();
			m_bCurrentObjectIsActive = FALSE;
			this->InvalidateObj(pAreaObj);
			RecordHistory();
			m_curMode = smNone;
		}
	}
}
int CImageEditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CADMMScrollView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	//注册快捷键
	//RegisterHotKey(this->m_hWnd,ID_COPY_AREA,MOD_CONTROL,'C');
	//RegisterHotKey(this->m_hWnd,ID_PASTE_AREA,MOD_CONTROL,'V');
	//RegisterHotKey(this->m_hWnd,ID_CUT_AREA,MOD_CONTROL,'X');
	RegisterHotKey(this->m_hWnd,ID_EDIT_UNDO,MOD_CONTROL,'Z');
	RegisterHotKey(this->m_hWnd,ID_DELETE_AREA,NULL,VK_DELETE);
	return 0;
}

void CImageEditorView::OnDestroy()
{
	CADMMScrollView::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
	//UnregisterHotKey(this->m_hWnd,ID_COPY_AREA);
	//UnregisterHotKey(this->m_hWnd,ID_PASTE_AREA);
	//UnregisterHotKey(this->m_hWnd,ID_CUT_AREA);
	RegisterHotKey(this->m_hWnd,ID_EDIT_UNDO,MOD_CONTROL,'Z');
	UnregisterHotKey(this->m_hWnd,ID_DELETE_AREA);
}

LRESULT CImageEditorView::OnHotKey(WPARAM wParam,LPARAM lParam)
{	
	switch(wParam)
	{
	case ID_COPY_AREA:
			OnEditCopy();
			break;
	case ID_PASTE_AREA:
			OnEditPaste();
			break;
	case ID_CUT_AREA:
			OnEditCut();
			break;
	case ID_DELETE_AREA:
			OnDelete();
			break;
	case ID_EDIT_UNDO:
			OnEditUndo();
			break;
	default:
		break;
	}
	return 0;
}
BOOL CImageEditorView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	if (nHitTest!=HTCLIENT)
	{
		return CADMMScrollView::OnSetCursor(pWnd, nHitTest, message);
	}
	switch (m_nCurToolIndex)
	{
		case ID_EDIT_PEN:
			SetCursor(AfxGetApp()->LoadCursor(IDC_MY_PEN));
			break;
		case ID_EDIT_ERASER:
			{			
			switch (m_emBrushStyle)
			{
				case CDrawObject::MyPenStyle::psDot2:
					SetCursor(AfxGetApp()->LoadCursor(IDC_ERASER1));
					break;
				case CDrawObject::MyPenStyle::psDot3:
					SetCursor(AfxGetApp()->LoadCursor(IDC_ERASER2));
					break;
				case CDrawObject::MyPenStyle::psRect1:
					SetCursor(AfxGetApp()->LoadCursor(IDC_ERASER3));
					break;
				case CDrawObject::MyPenStyle::psRect2:
					SetCursor(AfxGetApp()->LoadCursor(IDC_ERASER4));
					break;
				case CDrawObject::MyPenStyle::psRect3:
					SetCursor(AfxGetApp()->LoadCursor(IDC_ERASER5));
					break;
				default:
					SetCursor(AfxGetApp()->LoadCursor(IDC_ERASER3));
					break;
			}
			break;
			}
		case ID_EDIT_BRUSH:
			{			
			switch (m_emBrushStyle)
			{
				case CDrawObject::MyPenStyle::psDot2:
					SetCursor(AfxGetApp()->LoadCursor(IDC_BRUSH1));
					break;
				case CDrawObject::MyPenStyle::psDot3:
					SetCursor(AfxGetApp()->LoadCursor(IDC_BRUSH2));
					break;
				case CDrawObject::MyPenStyle::psRect1:
					SetCursor(AfxGetApp()->LoadCursor(IDC_BRUSH3));
					break;
				case CDrawObject::MyPenStyle::psRect2:
					SetCursor(AfxGetApp()->LoadCursor(IDC_BRUSH4));
					break;
				case CDrawObject::MyPenStyle::psRect3:
					SetCursor(AfxGetApp()->LoadCursor(IDC_BRUSH5));
					break;
				default:
					SetCursor(AfxGetApp()->LoadCursor(IDC_BRUSH3));
					break;
			}
			break;
			}
		case ID_EDIT_SELECT:
		case ID_EDIT_TEXT:
		case ID_EDIT_LINE:
		case ID_EDIT_CURVE:
		case ID_EDIT_RECTANGLE:
		case ID_EDIT_POLYGON:
		case ID_EDIT_ELLIPSE:
		case ID_EDIT_ROUND_RECT:
			SetCursor(AfxGetApp()->LoadCursor(IDC_MY_CROSS));
			break;
		default:
			SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
			break;
	}

	return TRUE;	
}

⌨️ 快捷键说明

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