VC绘图Word文档下载推荐.docx
《VC绘图Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《VC绘图Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。
rect);
pDC->
FillSolidRect(&
rect,RGB(255,255,255));
6.在控件上绘图
可以在对话框资源中放置图片控件,并对其类型属性选Frame。
可在对话框的绘图消息响应函数OnPaint或其他函数中,用CWnd类的函数GetDlgItem:
CWnd*GetDlgItem(intnID)const;
来获得图片控件的窗口对象,再用函数GetDC:
CDC*GetDC();
由窗口对象得到DC,然后就可以用该DC在控件中画图。
如(在ID为IDC_HUESAT的图片控件上画调色板)
voidCColorDlg:
OnPaint()
{
if(IsIconic()){
......
}
else{
CDialog:
OnPaint();
inti,j;
BYTEr,g,b;
//getcontrolwindowandDCofHue&
Saturation
CWnd*pWin=GetDlgItem(IDC_HUESAT);
CDC*pDC=pWin->
GetDC();
//drawhue-saturationpalette
for(i=0;
i<
360;
i++)
for(j=0;
j<
=255;
j++){
HSLtoRGB(i,255-j,128,r,g,b);
//自定义函数,见网络硬盘的
//res目录中的ColTrans.cpp文件
SetPixel(i,j,RGB(r,g,b));
在非Frame类静态控件上绘图,必须先按顺序依次调用CWnd类的Invalidate和UpdateWindow函数后,再开始用DC画图。
如在一个ID为IDC_COLOR的按钮上绘图:
voidCComDlgDlg:
DrawColor()
CWnd*pWnd=GetDlgItem(IDC_COLOR);
CDC*pDC=pWnd->
CRectrect;
pWnd->
GetClientRect(&
Invalidate();
UpdateWindow();
FillRect(&
rect,newCBrush(m_crCol));
若干说明:
<
!
--[if!
supportLists]-->
l
<
--[endif]-->
除了基于对话框的程序外,其他对话框类都需要自己添加(重写型)消息响应函数OnInitDialog,来做一些必要的初始化对话框的工作。
添加方法是:
先在项目区选中“类视图”页,再选中对应的对话框类,然后在属性窗口的“重写”页中添加该函数;
为了使在运行时能够不断及时更新控件的显示(主要是自己加的显式代码),可以将自己绘制控件的所有代码都全部加入对话框类的消息响应函数OnPaint中。
在需要时(例如在绘图参数修改后),自己调用CWnd的Invalidate和UpdateWindow函数,请求系统刷新对话框和控件的显示。
因为控件也是窗口,控件类都是CWnd的派生类。
所以在对话框和控件中,可以像在视图类中一样,调用各种CWnd的成员函数。
一般的对话框类,缺省时都没有明写出OnPaint函数。
可以自己在对话框类中添加WM_PAINT消息的响应函数OnPaint来进行一些绘图工作。
为了在鼠标指向按钮时,让按钮上自己绘制的图形不被消去,可以设置按钮控件的“OwnerDraw”属性为“True”。
如果希望非按钮控件(如图片控件和静态文本等),也可以响应鼠标消息(如单击、双击等),需要设置控件的“Notify”属性为“True”。
使用OnPaint函数在对话框客户区的空白处(无控件的地方)绘制自己的图形,必须屏蔽掉其中缺省的对对话框基类的OnPaint函数的调用:
//CDialog:
对话框的背景色,可以用CWnd类的成员函数:
DWORDGetSysColor(intnIndex);
得到,其中的nIndex取为COLOR_BTNFACE。
例如:
dc.SetBkColor(GetSysColor(COLOR_BTNFACE));
下面是部分例子代码:
(其中FillColor和ShowImg为自定义的成员函数)
voidCSetDlg:
OnBnClickedPenColor()
//TODO:
在此添加控件通知处理程序代码
CColorDialogcolDlg(m_crLineColor);
if(colDlg.DoModal()==IDOK){
m_crLineColor=colDlg.GetColor();
Invalidate();
UpdateWindow();
//……
OnPaint()
CPaintDCdc(this);
//devicecontextforpainting
在此处添加消息处理程序代码
//不为绘图消息调用CDialog:
FillColor(IDC_PEN_COLOR,m_crLineColor);
FillColor(IDC_BRUSH_COLOR,m_crBrushColor);
if(m_pBitmap0!
=NULL)ShowImg(IDC_BRUSH_IMG,m_hBmp0);
elseif(m_pBitmap!
=NULL)ShowImg(IDC_BRUSH_IMG,m_hBmp);
FillColor(UINTid,COLORREFcol)
CWnd*pWnd=GetDlgItem(id);
SelectObject(newCPen(PS_SOLID,1,RGB(0,0,0)));
SelectObject(newCBrush(col));
RoundRect(&
rect,CPoint(8,8));
ShowImg(UINTID,HBITMAPhBmp)
CWnd*pWnd=GetDlgItem(ID);
BITMAPbs;
GetObject(hBmp,sizeof(bs),&
bs);
CDCdc;
if(dc.CreateCompatibleDC(pDC)){
intx0,y0,w,h;
floatrx=(float)bs.bmWidth/rect.right,
ry=(float)bs.bmHeight/rect.bottom;
if(rx>
=ry){
x0=0;
w=rect.right;
h=(int)(bs.bmHeight/rx+0.5);
y0=(rect.bottom-h)/2;
y0=0;
h=rect.bottom;
w=(int)(bs.bmWidth/ry+0.5);
x0=(rect.right-w)/2;
:
SelectObject(dc.GetSafeHdc(),hBmp);
SetStretchBltMode(HALFTONE);
StretchBlt(x0,y0,w,h,&
dc,0,0,bs.bmWidth,bs.bmHeight,SRCCOPY);
SetDlgItemInt(IDC_W,bs.bmWidth);
SetDlgItemInt(IDC_H,bs.bmHeight);
//……
5设置绘图属性
除了映射模式外,还有许多绘图属性可以设置,如背景、绘图方式、多边形填充方式、画弧方向、刷原点等。
1.背景
1)背景色
当背景模式为不透明时,背景色决定线状图的空隙颜色(如虚线中的空隙、条纹刷的空隙和文字的空隙),可以使用CDC类的成员函数GetBkColor和SetBkColor来获得和设置当前的背景颜色:
COLORREFGetBkColor()const;
//返回当前的背景色
virtualCOLORREFSetBkColor(COLORREFcrColor);
//返回先前的背景色
//若出错返回0x80000000
2)背景模式
背景模式影响有空隙的线状图的空隙(如虚线中的空隙、条纹刷的空隙和文字的空隙)用什么办法填充。
可以使用CDC类的成员函数GetBkMode和SetBkMode来获得和设置当前的背景模式:
intGetBkMode()const;
//返回当前背景模式
intSetBkMode(intnBkMode);
//返回先前背景模式
背景模式的取值
nBkMode值名称作用
OPAQUE不透明的(缺省值)空隙用背景色填充
TRANSPARENT透明的空隙处保持原背景图不变
2.绘图模式
绘图模式(drawingmode)指前景色的混合方式,它决定新画图的笔和刷的颜色(pbCol)如何与原有图的颜色(scCol)相结合而得到结果像素色(pixel)。
1)设置绘图模式
可使用CDC类的成员函数SetROP2(ROP=RasterOPeration光栅操作)来设置绘图模式:
intSetROP2(intnDrawMode);
其中,nDrawMode可取值:
绘图模式nDrawMode的取值
符号常量作用运算结果
R2_BLACK黑色pixel=black
R2_WHITE白色pixel=white
R2_NOP不变pixel=scCol
R2_NOT反色pixel=~scCol
R2_COPYPEN覆盖pixel=pbCol
R2_NOTCOPYPEN反色覆盖pixel=~pbCol
R2_MERGEPENNOT反色或pixel=~scCol|pbCol
R2_MERGENOTPEN或反色pixel=scCol|~pbCol
R2_MASKNOTPEN与反色pixel=scCol&
~pbCol
R2_MERGEPEN或pixel=scCol|pbCol
R2_NOTMERGEPEN或非pixel=~(scCol|pbCol)
R2_MASKPEN与pixel=scCol&
pbCol
R2_NOTMASKPEN与非pixel=~(scCol&
pbCol)
R2_XORPEN异或pixel=scCol^pbCol
R2_NOTXORPEN异或非pixel=~(scCol^pbCol)
其中,R2_COPYPEN(覆盖)为缺省绘图模式,R2_XORPEN(异或)较常用。
2)画移动图形
为了能画移动的位置标识(如十字、一字)和随鼠标移动画动态图形(如直线、矩形、椭圆),必须在不破坏原有背景图形的基础上移动这些图形。
移动图形采用的是异或画图方法,移动图形的过程为:
异或画图、在原位置再异或化图(擦除)、在新位置异或画图、……。
如
pGrayPen=newCPen(PS_DOT,0,RGB(128,128,128));
pDC->
SetBkMode(TRANSPARENT);
pOldPen=pDC->
SelectObject(pGrayPen);
SelectStockObject(NULL_BRUSH);
SetROP2(R2_XORPEN);
if(m_bErase)pDC->
Ellipse(rect0);
Ellipse(rect);
SetROP2(R2_COPYPEN);
SelectObject(pOldPen);
rect0=rect;
较完整的拖放动态画图的例子,可参照下面的“3.拖放画动态直线”部分。
3)其他属性
多边形填充方式:
可使用CDC类的成员函数GetPolyFillMode和SetPolyFillMode来确定多边形的填充方式:
intGetPolyFillMode()const;
intSetPolyFillMode(intnPolyFillMode);
其中nPolyFillMode可取值ALTERNATE(交替——填充奇数边和偶数边之间的区域,缺省值)或WINDING(缠绕——根据多边形边的走向来确定是否填充一区域)
画弧方向:
可使用CDC类的成员函数GetArcDirection和SetArcDirection来确定Arc、Chord、Pie等函数的画弧方向:
intGetArcDirection()const;
intSetArcDirection(intnArcDirection);
其中,nArcDirection可取值AD_COUNTERCLOCKWISE(逆时针方向,缺省值)和AD_CLOCKWISE(顺时针方向)
刷原点:
可使用CDC类的成员函数GetBrushOrg和SetBrushOrg来确定可填充绘图函数的条纹或图案刷的起点:
(缺省值为客户区左上角的坐标原点(0,0))
CPointGetBrushOrg()const;
CPointSetBrushOrg(intx,inty);
CPointSetBrushOrg(POINTpoint);
3.拖放画动态直线
下面是一个较完整的拖放动态画直线的例子:
//类变量
classCDrawView:
publicCView{
//……
protected:
BOOLm_bLButtonDown,m_bErase;
//判断是否按下左鼠标键
//和是否需要擦除图形的类变量
CPointp0,pm;
//记录直线起点和动态终点的类变量
CPen*pGrayPen,*pLinePen;
//定义灰色和直线笔
//构造函数
CDrawView(){
m_bLButtonDown=FALSE;
//设左鼠标键按下为假
m_bErase=FALSE;
//设需要擦除为假
pGrayPen=newCPen(PS_SOLID,0,RGB(128,128,128));
//创建灰色笔
pLinePen=newCPen(PS_SOLID,0,RGB(255,0,0));
//创建红色的直线笔
//鼠标消息响应函数
voidCDrawView:
OnLButtonDown(UINTnFlags,CPointpoint){
m_bLButtonDown=TRUE;
//设左鼠标键按下为真
SetCapture();
//设置鼠标捕获
//SetCursor(LoadCursor(NULL,IDC_CROSS));
//设置鼠标为十字
p0=point;
//保存矩形左上角
pm=p0;
//让矩形右下角等于左上角
CView:
OnLButtonDown(nFlags,point);
OnMouseMove(UINTnFlags,CPointpoint){
SetCursor(LoadCursor(NULL,IDC_CROSS));
if(m_bLButtonDown){//左鼠标键按下为真
CDC*pDC=GetDC();
//获取设备上下文
//选取灰色笔
//设置为异或绘图方式
if(m_bErase){//需要擦除为真
MoveTo(p0);
LineTo(pm);
//擦除原直线
else//需要擦除为假
m_bErase=TRUE;
//设需要擦除为真
LineTo(point);
//绘制新直线
pm=point;
//记录老终点
ReleaseDC(pDC);
//释放设备上下文
OnMouseMove(nFlags,point);
OnLButtonUp(UINTnF