资源描述
附录表
一、 具体步骤:
1、选择菜单栏的“新建”,选择MFC项目名为DrawGraphics,并设置为基于对话框的项目,如图-1、图-2所示;
图-1
图-2
2、 按下键盘上的Ctrl+W键,调出类向导,选择“Add Class”,并点击“New”添加一个颜色按钮类CColorButton,继承自CButton类,如图-3所示:
图-3
3、在CColorButton中添加如下成员变量:
COLORREF color; //按钮颜色
CPoint arrays[4]; //按钮顶点坐标
BOOL IsShow; //是否显示按钮
BOOL IsPressed; //按钮是否被按下
4、右击CColorButton类,选择Add Virtul function ,重写其DraItem函数,如图-4,图-5所示:
图-4
图-5
5、 为其Drawitem函数中添加如下代码:
CRect rect;
GetClientRect(rect);
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
arrays[0]=CPoint(rect.left,rect.top);
arrays[1]=CPoint(rect.right,rect.top);
arrays[2]=CPoint(rect.right,rect.bottom);
arrays[3]=CPoint(rect.left,rect.bottom);
//设置背景透明
dc.SetBkMode(TRANSPARENT);
if (IsShow)
{
//创建一个位图画刷
CBrush brush(color);
dc.SelectObject(&brush);
CPen pen(PS_NULL,1,color);
dc.SelectObject(&pen);
dc.Rectangle(rect);
if(IsPressed)
{
CPen pen(PS_DASHDOTDOT,3,RGB(0,0,0));
dc.SelectObject(&pen);
dc.MoveTo(arrays[0]);
for(int i=1;i<4;i++)
{
dc.LineTo(arrays[i]);
}
dc.LineTo(arrays[0]);
}
else
{
CPen pen(PS_DASHDOTDOT,2,color);
dc.SelectObject(&pen);
dc.MoveTo(arrays[0]);
for(int i=1;i<4;i++)
{
dc.LineTo(arrays[i]);
}
dc.LineTo(arrays[0]);
}
//绘制按钮文本
CString str;
GetWindowText(str);
dc.SetTextColor(RGB(255-GetRValue(color),255-GetGValue(color),255-GetBValue(color)));
dc.DrawText(str,CRect(0,0,rect.right,rect.bottom),DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
6、 为CColorButton添加属性设置函数:
void CColorButton::SetDrawColor(COLORREF m_color,BOOL IsShow)
{
this->color = m_color;
this->IsShow=IsShow;
}
7、 为CColorButton添加WM_LBUTTONDOWN和WM_LBUTTONUP消息,其消息处理函数如下:
void CColorButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
IsPressed = true;
CButton::OnLButtonDown(nFlags, point);
}
void CColorButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
IsPressed = false;
CButton::OnLButtonUp(nFlags, point);
}
8、 为DrawGraphics项目的中的对话框资源拖拽如下控件,如图-6所示,并按表-1设置其相关ID;
图-6
ID
作用及类别
IDC_RADIO_RECT
矩形单选按钮
IDC_RADIO_ROUND
圆形单选按钮
IDC_RADIO_LINE
直线单选按钮
IDC_RADIO_SELF
涂鸦单选按钮
IDC_RADIO_SLOIDLINE
实线单选按钮
IDC_RADIO_DOTTEDLINE
虚线单选按钮
IDC_COMBO_LINEVALUE
线条粗细下拉列表
IDC_STATIC_LINEEXAMPLE
显示线条粗细的Picture控件
IDC_CHECK_BORDER
是否有边界复选框
IDC_RADIO_SOLID
填充单选按钮
IDC_RADIO_GRADIENT
渐变单选按钮
IDC_RADIO_NULL
无填充单选按钮
IDC_BUTTON_FORECOLOR
前景色按钮
IDC_BUTTON_BKCOLOR
背景色按钮
IDC_RADIO_PEN
画笔单选按钮
IDC_RADIO_CLEAR
清空画板单选按钮
IDC_STATIC_GRAPHICS
画板区(Picture控件)
表-1
9、 打开类向导,按图-7所示,为相关控件添加关联成员:
10、在CDrawGraphicsDlg类的OninitDialog函数中添加初始化代码:
BOOL CDrawGraphicsDlg:OnInitDialog()
{
/*.........省略无关代码..........
.....................................................*/
// TODO: Add extra initialization here
CButton *cb; //设置相关按钮的默认选中状态
cb=(CButton *)GetDlgItem(IDC_RADIO_RECT);
cb->SetCheck(1);
cb=(CButton *)GetDlgItem(IDC_RADIO_SLOIDLINE);
cb->SetCheck(1);
cb=(CButton *)GetDlgItem(IDC_CHECK_BORDER);
cb->SetCheck(1);
cb=(CButton *)GetDlgItem(IDC_RADIO_SOLID);
cb->SetCheck(1);
cb=(CButton *)GetDlgItem(IDC_RADIO_PEN);
cb->SetCheck(1);
m_ComboLineValue.SetCurSel(3);
m_ForeColor=RGB(255,0,0);
m_BkColor=RGB(0,0,255);
m_ForeCButton.SetDrawColor(m_ForeColor,TRUE); //设置前背景色按钮的颜色
m_BkCButton.SetDrawColor(m_BkColor,TRUE);
m_IsPressed=FALSE;
m_nWidth=4;
m_nPenStyle=PS_SOLID;
return TRUE; // return TRUE unless you set the focus to a control
}
10、 为CDrawGraphicsDlg添加WM_LBUTTONDOWN和WM_LBUTTONUP,WM_MOUSEMOVE消息,其消息处理函数如下:
void CDrawGraphicsDlg:OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_IsPressed=TRUE;
SetCursor(m_Hcursor);
if (IsDlgButtonChecked(IDC_RADIO_SELF))
{
m_pOld=point;
}
else if (IsDlgButtonChecked(IDC_RADIO_LINE))
{
m_pOld=point;
m_PointOrigin=point;
}else if (IsDlgButtonChecked(IDC_RADIO_RECT))
{
m_pOld=point;
m_PointOrigin=point;
}else if (IsDlgButtonChecked(IDC_RADIO_ROUND))
{
m_pOld=point;
m_PointOrigin=point;
}
CDialog::OnLButtonDown(nFlags, point);
}
void CDrawGraphicsDlg:OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_IsPressed=FALSE;
ClipCursor(NULL); //解除鼠标的限定
CClientDC dc(this);
CPen pen(m_nPenStyle,m_nWidth,m_ForeColor);
dc.SelectObject(&pen);
if (IsDlgButtonChecked(IDC_RADIO_LINE)) //选择的为画直线
{
dc.SetROP2(R2_NOT); //逆转当前屏幕颜色来画线的绘图方式
dc.MoveTo(m_PointOrigin);
dc.LineTo(m_pOld);//擦去上一次的临时线
dc.SetROP2(R2_COPYPEN);//缺省绘图模式,像素为画笔颜色
dc.MoveTo(m_PointOrigin);
dc.LineTo(point);//绘制固定线
}
else if (IsDlgButtonChecked(IDC_RADIO_RECT)) //选择的为画矩形
{
dc.SelectObject(GetStockObject(NULL_BRUSH));//选择空话刷
dc.SetROP2(R2_NOT);
CRect Oldrect(m_PointOrigin,m_pOld);
dc.Rectangle(&Oldrect); //清除之前的矩形绘图
dc.SetROP2(R2_COPYPEN);
CBrush brush(m_BkColor);
dc.SelectObject(&brush); //画这次的矩形
if (IsDlgButtonChecked(IDC_RADIO_NULL)) //如果选择无填充的话,使用空画刷
dc.SelectObject(GetStockObject(NULL_BRUSH));
CRect Nowrect(m_PointOrigin,point);
dc.Rectangle(&Nowrect);
if (IsDlgButtonChecked(IDC_RADIO_GRADIENT))//如果选择渐变的话,调用渐变函数
DrawGradient(dc.GetSafeHdc(),Nowrect,m_ForeColor,m_BkColor,1);
}else if(IsDlgButtonChecked(IDC_RADIO_ROUND))//如果选择绘制椭圆
{
dc.SelectObject(GetStockObject(NULL_BRUSH));
dc.SetROP2(R2_NOT);
CRect Oldrect(m_PointOrigin,m_pOld);
dc.Ellipse(&Oldrect);
dc.SetROP2(R2_COPYPEN);
CBrush brush(m_BkColor);
dc.SelectObject(&brush);
if (IsDlgButtonChecked(IDC_RADIO_NULL))
dc.SelectObject(GetStockObject(NULL_BRUSH));
CRect Nowrect(m_PointOrigin,point);
if (IsDlgButtonChecked(IDC_RADIO_GRADIENT))//如果选择渐变的话,调用渐变函数
DrawGradient(dc.GetSafeHdc(),Nowrect,m_ForeColor,m_BkColor,1);
dc.Ellipse(&Nowrect);
}
InvalidateMyRect();//刷新工具区
CDialog::OnLButtonUp(nFlags, point);
}
void CDrawGraphicsDlg:OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_IsPressed&&point.x>205)//如果鼠标移动位置到达画板区
{
CRect rect;
m_Graphics.GetClientRect(&rect);
m_Graphics.ClientToScreen(&rect);
ClipCursor(rect);//限定光标在指定矩形
}
CClientDC dc(this);
if (m_IsPressed&&IsDlgButtonChecked(IDC_RADIO_SELF))//如果选择了涂鸦
{
CPen pen(m_nPenStyle,m_nWidth,m_ForeColor); //创建画笔
dc.SelectObject(&pen); //选入画笔
dc.MoveTo(m_pOld);
dc.LineTo(point);//绘制轨迹
m_pOld=point;//将当前点设置为旧点
}
else if(m_IsPressed&&IsDlgButtonChecked(IDC_RADIO_LINE))//如果选择了直线
{
dc.SetROP2(R2_NOT);//逆转当前屏幕颜色来画线的绘图方式
dc.MoveTo(m_PointOrigin);
dc.LineTo(m_pOld); //擦去上一次的线
dc.MoveTo(m_PointOrigin);
dc.LineTo(point);//绘制这一次的临时线
m_pOld=point;
}
else if(m_IsPressed&&IsDlgButtonChecked(IDC_RADIO_RECT))//如果选择了矩形
{
dc.SetROP2(R2_NOT);
CPen pen(PS_DOT,1,m_ForeColor);
dc.SelectObject(&pen);
dc.SelectObject(GetStockObject(HOLLOW_BRUSH));
CRect Oldrect(m_PointOrigin,m_pOld);
dc.Rectangle(&Oldrect);
CRect Nowrect(m_PointOrigin,point);
dc.Rectangle(&Nowrect);
m_pOld=point;
pen.DeleteObject();
}else if (m_IsPressed&&IsDlgButtonChecked(IDC_RADIO_ROUND))//如果选择了圆
{
CClientDC dc(this);
dc.SetROP2(R2_NOT);
CPen pen(PS_DOT,1,m_ForeColor);
dc.SelectObject(&pen);
dc.SelectObject(GetStockObject(HOLLOW_BRUSH));
CRect Oldrect(m_PointOrigin,m_pOld);
dc.Ellipse(&Oldrect);
CRect Nowrect(m_PointOrigin,point);
dc.Ellipse(&Nowrect);
m_pOld=point;
pen.DeleteObject();
}
CDialog::OnMouseMove(nFlags, point);
}
11、 为背景色、前景色、无填充、实线、虚线、边框、清空画板按钮添加按钮单击消息,响应函数如下:
void CDrawGraphicsDlg:OnButtonBkcolor()
{
// TODO: Add your control notification handler code here
CColorDialog cdg;
if (cdg.DoModal()==IDOK) //调用颜色对话框
{
m_BkColor=cdg.GetColor(); //更改背景色
m_BkCButton.SetDrawColor(m_BkColor,TRUE);//更改背景色按钮颜色
InvalidateMyRect(); //刷新工具区
}
}
void CDrawGraphicsDlg:OnButtonForecolor()
{
// TODO: Add your control notification handler code here
CColorDialog cdg;
if (cdg.DoModal()==IDOK)
{
m_ForeColor=cdg.GetColor();
m_ForeCButton.SetDrawColor(m_ForeColor,TRUE);
InvalidateMyRect();
}
}
void CDrawGraphicsDlg:OnRadioNull()
{
// TODO: Add your control notification handler code here
if (!IsDlgButtonChecked(IDC_CHECK_BORDER)) //无填充时不能也无边框
{
CButton *cb=(CButton *)GetDlgItem(IDC_CHECK_BORDER);
cb->SetCheck(1);
}
}
void CDrawGraphicsDlg:OnRadioSloidline()
{
// TODO: Add your control notification handler code here
CString str[9]={"1px","2px","3px","4px","5px","6px","8px","10px","12px"};
m_ComboLineValue.ResetContent();
for (int i=0;i<9;i++)
m_ComboLineValue.AddString(str[i]);
m_ComboLineValue.SetCurSel(3);
m_nWidth=4;
m_nPenStyle=PS_SOLID;
InvalidateMyRect();
}
void CDrawGraphicsDlg:OnRadioDottedline()
{
// TODO: Add your control notification handler code here
for (int i=11;i>0;i--)
m_ComboLineValue.DeleteString(i);
m_ComboLineValue.SetCurSel(0);
m_nWidth=1;
m_nPenStyle=PS_DOT;
InvalidateMyRect();
}
void CDrawGraphicsDlg:OnCheckBorder()
{
// TODO: Add your control notification handler code here
if (IsDlgButtonChecked(IDC_CHECK_BORDER))
m_nPenStyle=PS_SOLID;
else
{
m_nPenStyle=PS_NULL;
if (IsDlgButtonChecked(IDC_RADIO_NULL)) //既不能无边框也不能无填充
{
CButton *cb=(CButton *)GetDlgItem(IDC_CHECK_BORDER);
cb->SetCheck(1);
}
}
}
void CDrawGraphicsDlg:OnRadioClear()
{
// TODO: Add your control notification handler code here
Invalidate(TRUE);
}
12、 为选择画笔宽度的下拉列表添加CBN_SELCHAGE消息,消息处理函数如下:
void CDrawGraphicsDlg:OnRadioSloidline()
{
// TODO: Add your control notification handler code here
CString str[9]={"1px","2px","3px","4px","5px","6px","8px","10px","12px"};
m_ComboLineValue.ResetContent();
for (int i=0;i<9;i++)
m_ComboLineValue.AddString(str[i]);
m_ComboLineValue.SetCurSel(3);
m_nWidth=4;
m_nPenStyle=PS_SOLID;
InvalidateMyRect();
}
13、 为CDrawGraphicsDlg类添加如下的两个自定义函数InvalidateMyRect以及DrawGradient,分别用来刷新工具区和绘制渐变:
void CDrawGraphicsDlg:InvalidateMyRect() //将工具区部分刷新
{
CRect invaRect;
invaRect.top=0;
invaRect.bottom=500;
invaRect.left=0;
invaRect.right=205;
InvalidateRect(invaRect,TRUE);
}
void CDrawGraphicsDlg:DrawGradient(HDC pDc, const RECT &rect, COLORREF begin, COLORREF end, const int &width)
{
RECT rcstep; //设置每次填充的矩形
HBRUSH br; //创建画刷句柄
int n,m;
float step=0.0;
int nred=0,ngreen=0,nblue=0;
float red=0.0,green=0.0,blue=0.0;
nred=(GetRValue(begin)-GetRValue(end));
ngreen=(GetGValue(begin)-GetGValue(end));
nblue=(GetBValue(begin)-GetBValue(end));
step=(float)abs(rect.top-rect.bottom)/(float)width;
red=nred/(float)step;
green=ngreen/(float)step;
blue=nblue/(float)step;
for (int start=0;start<=step;start++) //一块快绘制矩形
{
n=min((int)(rect.top+start*width),rect.bottom);
m=min((int)(rect.top+(start+1)*width),rect.bottom);
::SetRect(&rcstep,rect.left,n,rect.right+1,m);
br=CreateSolidBrush(RGB(nred-red*start,ngreen-green*start,nblue-blue*start)); //选择笔刷颜色
HBRUSH oldbr=(HBRUSH)::SelectObject(pDc,br);
FillRect(pDc,&rcstep,br);//用新颜色填充矩形区
::SelectObject(pDc,oldbr);
DeleteObject(br);
}
}
二、运行结果:
1、 绘图效果:
2、 选择颜色对话框以及清空画图板功能:
15
展开阅读全文