📄 imagepaintarea.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 + -