📄 imageeditorview.cpp
字号:
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 + -