📄 canvas.cpp
字号:
// Canvas.cpp : implementation file
//
#include "stdafx.h"
#include "Canvas.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TIMER_ID 1
/////////////////////////////////////////////////////////////////////////////
// CCanvas
CCanvas::CCanvas()
: m_width(0), m_height(0), m_bitmap(NULL), m_buffer(NULL),
m_double_buffered(true), m_auto_focus(true), m_draw_background(true),
m_mouse_in(false), m_draw_border(false), m_border_style(FLAT)
{
// Set the background color
m_back_color = ::GetSysColor(COLOR_3DFACE);
// Set the cursor to the arrow by default
m_cursor = ::LoadCursor(NULL, IDC_ARROW );
}
CCanvas::~CCanvas()
{
// Delete the buffer
Clean();
}
void CCanvas::Clean()
{
// Delete the buffer
if (m_buffer != NULL) delete(m_buffer);
if (m_bitmap != NULL) delete(m_bitmap);
}
BEGIN_MESSAGE_MAP(CCanvas, CStatic)
//{{AFX_MSG_MAP(CCanvas)
ON_WM_NCHITTEST()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCanvas message handlers
// Enable mouse messages
UINT CCanvas::OnNcHitTest(CPoint point)
{
return HTCLIENT;
}
// Set a Windows cursor
void CCanvas::SetWinCursor(LPCTSTR cursor)
{
m_cursor = ::LoadCursor(NULL, cursor );
}
// Set an application cursor
void CCanvas::SetAppCursor(UINT nIDResource)
{
m_cursor = AfxGetApp()->LoadCursor(nIDResource);
}
// Repaint
void CCanvas::Repaint()
{
// If double buffered, call PaintBuffer
if( m_double_buffered )
{
// Get the client dc
CClientDC dc(this);
CRect rect;
GetClientRect(rect);
// Clean the background
if( m_draw_background )
{
CBrush brush(GetBackgroundColor());
m_buffer->FillRect(rect,&brush);
}
// Paint
Paint(m_buffer);
// Draw a border
if( m_draw_border )
{
DrawBorder(m_buffer);
}
// Copy the double buffer to the front
dc.BitBlt(0,0,rect.Width(),rect.Height(),m_buffer,0,0,SRCCOPY);
}
else
{
Invalidate();
}
}
// OnPaint()
void CCanvas::OnPaint()
{
CPaintDC dc(this);
// Get the Client rectangle
CRect rect;
GetClientRect(rect);
// Check is double buffered
if( m_double_buffered )
{
// Copy back image to dc
dc.BitBlt(0,0,rect.Width(),rect.Height(),m_buffer,0,0,SRCCOPY);
}
else
{
// Set the clipping region
CRgn rgn;
rgn.CreateRectRgnIndirect(rect);
dc.SelectClipRgn(&rgn);
// Draw the background
if( m_draw_background )
{
CBrush brush(m_back_color);
dc.FillRect(rect,&brush);
}
// Call the paint method directly for non double buffered
Paint(&dc);
// Draw a border
if( m_draw_border )
{
DrawBorder(&dc);
}
}
}
// Draw a border
void CCanvas::DrawBorder(CDC* dc)
{
CRect rect;
GetClientRect(rect);
switch(m_border_style)
{
case SUNKEN:
dc->Draw3dRect(rect, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DLIGHT));
break;
case HIGH:
dc->Draw3dRect(rect, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect, GetSysColor(COLOR_3DLIGHT), GetSysColor(COLOR_3DSHADOW));
break;
case FLAT:
DrawRect(dc, rect, GetSysColor(COLOR_3DDKSHADOW));
rect.DeflateRect(1,1,1,1);
DrawRect(dc, rect, GetSysColor(COLOR_3DDKSHADOW));
break;
case LOW:
dc->Draw3dRect(rect, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
break;
case UP:
dc->Draw3dRect(rect, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
break;
case SIMPLE:
DrawRect(dc, rect, GetSysColor(COLOR_3DDKSHADOW));;
break;
case FRAME:
dc->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
rect.DeflateRect(1,1,1,1);
DrawRect(dc, rect, GetSysColor(COLOR_3DFACE));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DHILIGHT));
break;
case THIN_FRAME:
dc->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DHILIGHT));
break;
case LIGHT_FRAME:
dc->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
rect.DeflateRect(1,1,1,1);
DrawRect(dc, rect, GetSysColor(COLOR_3DFACE));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
break;
case THIN_LIGHT_FRAME:
dc->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
break;
case ETCHED:
dc->Draw3dRect(rect, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
break;
case ETCHED2:
dc->Draw3dRect(rect, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
rect.DeflateRect(1,1,1,1);
DrawRect(dc, rect, GetSysColor(COLOR_3DDKSHADOW));
rect.DeflateRect(1,1,1,1);
dc->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
break;
default:
break;
}
}
void CCanvas::OnMouseMove(UINT nFlags, CPoint point)
{
// Set the focus to allow mouse wheel
if( m_auto_focus )
SetFocus();
// Handle mouse exit
if( !m_mouse_in )
{
m_mouse_in = true;
SetTimer(TIMER_ID,50,NULL);
}
}
BOOL CCanvas::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// If we are in the client area change the cursor
if( nHitTest == HTCLIENT )
{
::SetCursor(m_cursor);
return TRUE;
}
return CStatic::OnSetCursor(pWnd, nHitTest, message);
}
void CCanvas::OnTimer(UINT nIDEvent)
{
if( nIDEvent == TIMER_ID)
{
// Get the client rectangle
CRect rect;
GetClientRect(rect);
// Get the mouse position
CPoint point;
GetCursorPos(&point);
ScreenToClient(&point);
// Check if the point is in the client
if( !rect.PtInRect(point) && GetCapture()!=this )
{
KillTimer(TIMER_ID);
m_mouse_in = false;
OnMouseExit();
}
}
else
CStatic::OnTimer(nIDEvent);
}
BOOL CCanvas::OnEraseBkgnd(CDC* /*pDC*/)
{
// We are managing the background
return TRUE;
}
// Called after the CCanvas is created, before it is visible
void CCanvas::PreSubclassWindow()
{
CStatic::PreSubclassWindow();
// Init double buffer
Init();
}
// Initialize the double buffer
void CCanvas::Init()
{
// Get the Client rectangle
CRect rect;
GetClientRect(rect);
// Set the width and height
m_width = rect.Width();
m_height = rect.Height();
CClientDC dc(this);
// Create the bitmap
if(m_bitmap == NULL)
{
m_bitmap = new CBitmap();
m_bitmap->CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
}
// Create the double buffer
if(m_buffer == NULL)
{
m_buffer = new CDC();
m_buffer->CreateCompatibleDC(&dc);
m_buffer->SelectObject(m_bitmap);
}
// Init the buffer
Repaint();
}
// Draw a rectangle
void CCanvas::DrawRect(CDC *dc, RECT rect)
{
dc->MoveTo(rect.left,rect.top);
dc->LineTo(rect.right-1,rect.top);
dc->LineTo(rect.right-1,rect.bottom-1);
dc->LineTo(rect.left,rect.bottom-1);
dc->LineTo(rect.left,rect.top);
}
void CCanvas::DrawRect(CDC *dc, RECT rect, COLORREF color)
{
CPen pen(PS_SOLID,1,color);
CPen* oldPen = dc->SelectObject(&pen);
DrawRect(dc, rect);
dc->SelectObject(oldPen);
}
void CCanvas::DrawRect(CDC *dc, int x, int y, int w, int h)
{
dc->MoveTo(x,y);
dc->LineTo(x+w,y);
dc->LineTo(x+w,y+h);
dc->LineTo(x,y+h);
dc->LineTo(x,y);
}
void CCanvas::DrawRect(CDC *dc, int x, int y, int w, int h, COLORREF color)
{
CPen pen(PS_SOLID,1,color);
CPen* oldPen = dc->SelectObject(&pen);
DrawRect(dc, x, y, w, h);
}
// Draw a circle
void CCanvas::DrawCircle(CDC *dc, int x, int y, int radius)
{
dc->Arc(x-radius,y-radius,x+radius,y+radius,x,y-radius,x,y-radius);
}
void CCanvas::DrawCircle(CDC *dc, int x, int y, int radius, COLORREF color)
{
CPen pen(PS_SOLID,1,color);
CPen* oldPen = dc->SelectObject(&pen);
DrawCircle(dc, x, y, radius);
dc->SelectObject(oldPen);
}
// Draw a line
void CCanvas::DrawLine(CDC *dc, CPoint& start, CPoint& end)
{
dc->MoveTo(start);
dc->LineTo(end);
}
void CCanvas::DrawLine(CDC *dc, CPoint& start, CPoint& end, COLORREF color)
{
CPen pen(PS_SOLID,1,color);
CPen* oldPen = dc->SelectObject(&pen);
DrawLine(dc, start, end);
dc->SelectObject(oldPen);
}
void CCanvas::DrawLine(CDC *dc, int xStart, int yStart, int xEnd, int yEnd)
{
dc->MoveTo(xStart, yStart);
dc->LineTo(xEnd, yEnd);
}
void CCanvas::DrawLine(CDC *dc, int xStart, int yStart, int xEnd, int yEnd, COLORREF color)
{
CPen pen(PS_SOLID,1,color);
CPen* oldPen = dc->SelectObject(&pen);
DrawLine(dc, xStart, yStart, xEnd, yEnd);
dc->SelectObject(oldPen);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -