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

📄 imagepaintarea.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 CPP
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This source code is a part of BCGControlBar library.
// You may use, compile or redistribute it as part of your application 
// for free. You cannot redistribute it as a part of a software development 
// library without the agreement of the author. If the sources are 
// distributed along with the application, you should leave the original 
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
// 
// Stas Levin <stas@iet.co.il>
//*******************************************************************************

// ImagePaintArea.cpp : implementation file
//

#include "stdafx.h"
#include "bcgbarres.h"
#include "ImagePaintArea.h"
#include "BCGToolBarImages.h"
#include "ImageEditDlg.h"
#include "bcgbarres.h"
#include "bcglocalres.h"

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

/////////////////////////////////////////////////////////////////////////////
// CImagePaintArea

CImagePaintArea::CImagePaintArea(CImageEditDlg* pParentDlg)
{
	ASSERT (pParentDlg != NULL);

	m_pParentDlg = pParentDlg;

	m_sizeImage.cx = 0;
	m_sizeImage.cy = 0;

	m_pBitmap = NULL;
	m_rgbColor = RGB (0, 0, 0);	// Black

	m_rectParentPreviewArea.SetRectEmpty ();
	m_memDC.CreateCompatibleDC (NULL);

	m_Mode = IMAGE_EDIT_MODE_PEN;
	m_rectDraw.SetRectEmpty ();
}

CImagePaintArea::~CImagePaintArea()
{
	::DestroyCursor (m_hcurPen);
	::DestroyCursor (m_hcurFill);
	::DestroyCursor (m_hcurLine);
	::DestroyCursor (m_hcurRect);
	::DestroyCursor (m_hcurEllipse);
	::DestroyCursor (m_hcurColor);
}

BEGIN_MESSAGE_MAP(CImagePaintArea, CButton)
	//{{AFX_MSG_MAP(CImagePaintArea)
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_CANCELMODE()
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImagePaintArea message handlers

void CImagePaintArea::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
	CDC* pDC = CDC::FromHandle (lpDIS->hDC);
	ASSERT_VALID (pDC);

	CRect rectClient = lpDIS->rcItem;
	rectClient.InflateRect (-1, -1);

	CRect rectDraw = rectClient;

	rectDraw.right = rectDraw.left + m_sizeCell.cx * m_sizeImage.cx;
	rectDraw.bottom = rectDraw.top + m_sizeCell.cy * m_sizeImage.cy;

	rectClient = rectDraw;
	rectClient.InflateRect (1, 1);

	pDC->Draw3dRect (rectDraw,
					::GetSysColor (COLOR_3DDKSHADOW),
					::GetSysColor (COLOR_3DHILIGHT));

	//-----------
	// Draw grid:
	//-----------
	CPen penGrid (PS_SOLID, 1, ::GetSysColor (COLOR_3DSHADOW));
	CPen* pOldPen = (CPen*) pDC->SelectObject (&penGrid);

	for (int x = rectDraw.left + m_sizeCell.cx; 
		x <= rectDraw.right - m_sizeCell.cx; x += m_sizeCell.cx)
	{
		pDC->MoveTo (x, rectDraw.top + 1);
		pDC->LineTo (x, rectDraw.bottom - 1);
	}

	for (int y = rectDraw.top + m_sizeCell.cy; 
		y <= rectDraw.bottom - m_sizeCell.cy; y += m_sizeCell.cy)
	{
		pDC->MoveTo (rectDraw.left + 1, y);
		pDC->LineTo (rectDraw.right - 1, y);
	}

	pDC->SelectObject (pOldPen);

	//-------------
	// Draw bitmap:
	//-------------
	if (m_pBitmap == NULL)
	{
		return;
	}

	CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);

	for (x = 0; x < m_sizeImage.cx; x ++)
	{
		for (y = 0; y < m_sizeImage.cy; y ++)
		{
			COLORREF rgbPixel = 
				CBCGToolBarImages::MapFromSysColor (m_memDC.GetPixel (x, y), FALSE);
			if (rgbPixel != (COLORREF) -1)
			{
				CRect rect (
					CPoint (rectDraw.left + x * m_sizeCell.cx, 
							rectDraw.top + y * m_sizeCell.cy),
					m_sizeCell);
				rect.InflateRect (-1, -1);

				pDC->FillSolidRect (rect, rgbPixel);
			}
		}
	}

	m_memDC.SelectObject (pOldBitmap);
}
//********************************************************************************
BOOL CImagePaintArea::OnEraseBkgnd(CDC* pDC) 
{
	CRect rectClient;	// Client area rectangle
	GetClientRect (&rectClient);

	pDC->FillSolidRect (&rectClient, ::GetSysColor (COLOR_3DFACE));
	return TRUE;
}
//********************************************************************************
void CImagePaintArea::OnMouseMove(UINT nFlags, CPoint point) 
{
	if ((nFlags & MK_LBUTTON) == 0)
	{
		return;
	}

	CRect rectClient;	// Client area rectangle
	GetClientRect (&rectClient);

	point.x = min (max (point.x, rectClient.left), rectClient.right);
	point.y = min (max (point.y, rectClient.top), rectClient.bottom);

	if (m_Mode == IMAGE_EDIT_MODE_PEN)
	{
		DrawPixel (point);
		return;
	}

	if (m_Mode != IMAGE_EDIT_MODE_LINE &&
		m_Mode != IMAGE_EDIT_MODE_RECT &&
		m_Mode != IMAGE_EDIT_MODE_ELLIPSE)
	{
		return;
	}

	CRect rectDraw = rectClient;

	rectDraw.right = rectDraw.left + m_sizeCell.cx * m_sizeImage.cx;
	rectDraw.bottom = rectDraw.top + m_sizeCell.cy * m_sizeImage.cy;

	rectDraw.DeflateRect (1, 1);

	if (m_rectDraw == rectDraw)
	{
		return;
	}

	CRgn rgnClip;
	rgnClip.CreateRectRgnIndirect (&rectDraw);

	CClientDC dc (this);
	dc.SelectObject (&rgnClip);

	CPen* pOldPen = (CPen*) dc.SelectObject (&m_penStretch);
	CBrush* pOldBrush = (CBrush*) dc.SelectStockObject (NULL_BRUSH);
	int nOldROP = dc.SetROP2 (R2_NOT);

	switch (m_Mode)
	{
	case IMAGE_EDIT_MODE_LINE:
		{		
			//-----------
			// Erase old:
			//-----------
			CRect rectScreen = m_rectDraw;
			BitmapToClient (rectScreen);

			if (m_rectDraw.Width () != 0 ||
				m_rectDraw.Height () != 0)
			{
				dc.MoveTo (rectScreen.left, rectScreen.top);
				dc.LineTo (rectScreen.right, rectScreen.bottom);
			}

			ScreenToBitmap (point);
			m_rectDraw.right = point.x;
			m_rectDraw.bottom = point.y;

			//----------
			// Draw new:
			//----------
			rectScreen = m_rectDraw;
			BitmapToClient (rectScreen);

			if (m_rectDraw.Width () != 0 ||
				m_rectDraw.Height () != 0)
			{
				dc.MoveTo (rectScreen.left, rectScreen.top);
				dc.LineTo (rectScreen.right, rectScreen.bottom);
			}
		}
		break;

	case IMAGE_EDIT_MODE_RECT:
		{		
			//-----------
			// Erase old:
			//-----------
			CRect rectScreen = m_rectDraw;
			BitmapToClient (rectScreen);

			if (m_rectDraw.Width () != 0 ||
				m_rectDraw.Height () != 0)
			{
				dc.Rectangle (rectScreen);
			}

			ScreenToBitmap (point);
			m_rectDraw.right = point.x;
			m_rectDraw.bottom = point.y;

			//----------
			// Draw new:
			//----------
			rectScreen = m_rectDraw;
			BitmapToClient (rectScreen);

			if (m_rectDraw.Width () != 0 ||
				m_rectDraw.Height () != 0)
			{
				dc.Rectangle (rectScreen);
			}
		}
		break;

	case IMAGE_EDIT_MODE_ELLIPSE:
		{		
			//-----------
			// Erase old:
			//-----------
			CRect rectScreen = m_rectDraw;
			BitmapToClient (rectScreen);

			if (m_rectDraw.Width () != 0 ||
				m_rectDraw.Height () != 0)
			{
				dc.Ellipse (rectScreen);
			}

			ScreenToBitmap (point);
			m_rectDraw.right = point.x;
			m_rectDraw.bottom = point.y;

			//----------
			// Draw new:
			//----------
			rectScreen = m_rectDraw;
			BitmapToClient (rectScreen);

			if (m_rectDraw.Width () != 0 ||
				m_rectDraw.Height () != 0)
			{
				dc.Ellipse (rectScreen);
			}
		}
		break;
	}

	dc.SetROP2 (nOldROP);
	dc.SelectObject (pOldBrush);
	dc.SelectObject (pOldPen);
	dc.SelectClipRgn (NULL);
}
//********************************************************************************
void CImagePaintArea::OnLButtonDown(UINT /*nFlags*/, CPoint point) 
{
	if (m_pBitmap == NULL)
	{
		return;
	}

	switch (m_Mode)
	{
	case IMAGE_EDIT_MODE_PEN:
		DrawPixel (point);
		break;

	case IMAGE_EDIT_MODE_LINE:
	case IMAGE_EDIT_MODE_RECT:
	case IMAGE_EDIT_MODE_ELLIPSE:
		{
			ScreenToBitmap (point);
			m_rectDraw = CRect (point, CSize (0, 0));
		}
		break;
	}

	SetCapture ();
}
//********************************************************************************
void CImagePaintArea::OnLButtonUp(UINT /*nFlags*/, CPoint point) 
{
	CRect rectClient;	// Client area rectangle
	GetClientRect (&rectClient);

	if (GetCapture () == this)
	{
		ReleaseCapture ();
	}

	switch (m_Mode)
	{
	case IMAGE_EDIT_MODE_PEN:
		DrawPixel (point);
		break;

	case IMAGE_EDIT_MODE_LINE:
		{
			CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);
			CPen* pOldPen = (CPen*) m_memDC.SelectObject (&m_penDraw);

			m_memDC.MoveTo (m_rectDraw.left, m_rectDraw.top);
			m_memDC.LineTo (m_rectDraw.right, m_rectDraw.bottom);

			m_memDC.SelectObject (pOldBitmap);
			m_memDC.SelectObject (pOldPen);

			Invalidate ();
			UpdateWindow ();

			GetParent()->InvalidateRect (m_rectParentPreviewArea);
		}
		break;

	case IMAGE_EDIT_MODE_RECT:
		{
			CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);
			CPen* pOldPen = (CPen*) m_memDC.SelectObject (&m_penDraw);
			CBrush* pOldBrush = (CBrush*) m_memDC.SelectStockObject (NULL_BRUSH);

			m_memDC.Rectangle (m_rectDraw);

			m_memDC.SelectObject (pOldBitmap);
			m_memDC.SelectObject (pOldPen);
			m_memDC.SelectObject (pOldBrush);

			Invalidate ();
			UpdateWindow ();

			GetParent()->InvalidateRect (m_rectParentPreviewArea);
		}
		break;

	case IMAGE_EDIT_MODE_ELLIPSE:
		{
			CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);
			CPen* pOldPen = (CPen*) m_memDC.SelectObject (&m_penDraw);
			CBrush* pOldBrush = (CBrush*) m_memDC.SelectStockObject (NULL_BRUSH);

			m_memDC.Ellipse (m_rectDraw);

			m_memDC.SelectObject (pOldBitmap);
			m_memDC.SelectObject (pOldPen);
			m_memDC.SelectObject (pOldBrush);

			Invalidate ();
			UpdateWindow ();

			GetParent()->InvalidateRect (m_rectParentPreviewArea);
		}
		break;

	case IMAGE_EDIT_MODE_FILL:
		ScreenToBitmap (point);
		FloodFil (point);
		break;

	case IMAGE_EDIT_MODE_COLOR:
		{
			ScreenToBitmap (point);

			CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);
			COLORREF color = m_memDC.GetPixel (point);
			m_memDC.SelectObject (pOldBitmap);

			m_pParentDlg->OnPickColor (color);
		}
		break;
	}

	m_rectDraw.SetRectEmpty ();
}
//********************************************************************************
void CImagePaintArea::OnCancelMode() 
{
	if (GetCapture () == this)
	{
		ReleaseCapture ();
	}
}
//********************************************************************************DrawPixel (point);
void CImagePaintArea::DrawPixel (POINT point)
{
	CRect rectClient;	// Client area rectangle
	GetClientRect (&rectClient);

	rectClient.InflateRect (-1, -1);

	CPoint ptBmp = point;
	ScreenToBitmap (ptBmp);

	CRect rect (
		CPoint (rectClient.left + ptBmp.x * m_sizeCell.cx, 
				rectClient.top + ptBmp.y * m_sizeCell.cy),
		m_sizeCell);
	rect.InflateRect (-1, -1);

	CClientDC dc (this);
	dc.FillSolidRect (rect, m_rgbColor);

	//---------------
	// Update bitmap:
	//---------------
	CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);
	m_memDC.SetPixel (ptBmp.x, ptBmp.y, CBCGToolBarImages::MapToSysColor (m_rgbColor));
	m_memDC.SelectObject (pOldBitmap);

	GetParent()->InvalidateRect (m_rectParentPreviewArea);
}
//********************************************************************************
void CImagePaintArea::SetBitmap (CBitmap* pBitmap)
{
	m_pBitmap = pBitmap;
	m_sizeCell = CSize (0, 0);

	if (m_pBitmap == NULL)
	{
		m_sizeImage.cx = 0;
		m_sizeImage.cy = 0;
		return;
	}

	BITMAP bmp;
	m_pBitmap->GetBitmap (&bmp);

	m_sizeImage.cx = bmp.bmWidth;
	m_sizeImage.cy = bmp.bmHeight;

	CRect rectClient;
	GetClientRect (rectClient);
	rectClient.DeflateRect (1, 1);

	m_sizeCell = CSize (
		rectClient.Width () / m_sizeImage.cx,
		rectClient.Height () / m_sizeImage.cy);

	if (m_penStretch.GetSafeHandle () != NULL)
	{
		m_penStretch.DeleteObject ();
	}

	m_penStretch.CreatePen (PS_SOLID, min (m_sizeCell.cx, m_sizeCell.cy),
							::GetSysColor (COLOR_BTNTEXT));
}
//********************************************************************************
BOOL CImagePaintArea::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	switch (m_Mode)
	{
	case IMAGE_EDIT_MODE_PEN:
		::SetCursor (m_hcurPen);
		return TRUE;

	case IMAGE_EDIT_MODE_FILL:
		::SetCursor (m_hcurFill);
		return TRUE;

	case IMAGE_EDIT_MODE_LINE:
		::SetCursor (m_hcurLine);
		return TRUE;

	case IMAGE_EDIT_MODE_RECT:
		::SetCursor (m_hcurRect);
		return TRUE;

	case IMAGE_EDIT_MODE_ELLIPSE:
		::SetCursor (m_hcurEllipse);
		return TRUE;

	case IMAGE_EDIT_MODE_COLOR:
		::SetCursor (m_hcurColor);
		return TRUE;
	}
	
	return CButton::OnSetCursor(pWnd, nHitTest, message);
}
//********************************************************************
void CImagePaintArea::PreSubclassWindow() 
{
	CBCGLocalResource locaRes;
	
	m_hcurPen = AfxGetApp()->LoadCursor (IDC_BCGBARRES_PEN);
	m_hcurFill = AfxGetApp()->LoadCursor (IDC_BCGBARRES_FILL);
	m_hcurLine = AfxGetApp()->LoadCursor (IDC_BCGBARRES_LINE);
	m_hcurRect = AfxGetApp()->LoadCursor (IDC_BCGBARRES_RECT);
	m_hcurEllipse = AfxGetApp()->LoadCursor (IDC_BCGBARRES_ELLIPSE);
	m_hcurColor = AfxGetApp()->LoadCursor (IDC_BCGBARRES_COLOR);

	CButton::PreSubclassWindow();
}
//********************************************************************
void CImagePaintArea::ScreenToBitmap (CPoint& point)
{
	int x = (point.x - 1) / m_sizeCell.cx;
	int y = (point.y - 1) / m_sizeCell.cy;

	point.x = max (min (x, m_sizeImage.cx - 1), 0);
	point.y = max (min (y, m_sizeImage.cy - 1), 0);
}
//********************************************************************
void CImagePaintArea::BitmapToClient (CRect& rect)
{
	rect.left = rect.left * m_sizeCell.cx + 1;
	rect.top = rect.top * m_sizeCell.cy + 1;
	rect.right = rect.right * m_sizeCell.cx + 1;
	rect.bottom = rect.bottom * m_sizeCell.cy + 1;

	rect.OffsetRect (m_sizeCell.cx / 2, m_sizeCell.cy / 2);
}
//*********************************************************************
void CImagePaintArea::FloodFil (const CPoint& point)
{
	ASSERT (m_pBitmap != NULL);

	CBitmap* pOldBitmap = m_memDC.SelectObject (m_pBitmap);

	CBrush br (m_rgbColor);
	CBrush* pBrOld = (CBrush*) m_memDC.SelectObject (&br);

	m_memDC.ExtFloodFill (point.x, point.y, 
		m_memDC.GetPixel (point), FLOODFILLSURFACE);

	m_memDC.SelectObject (pOldBitmap);
	m_memDC.SelectObject (pBrOld);

	Invalidate ();
	UpdateWindow ();

	GetParent()->InvalidateRect (m_rectParentPreviewArea);
}
//********************************************************************
void CImagePaintArea::SetColor (COLORREF color)
{
	m_rgbColor = color;

	if (m_penDraw.GetSafeHandle () != NULL)
	{
		m_penDraw.DeleteObject ();
	}

	m_penDraw.CreatePen (PS_SOLID, 1, m_rgbColor);
}

⌨️ 快捷键说明

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