第07讲--利用CDC实现绘图程序
MFC基本的图形绘制 CDC类
MFC图形绘制1 、Windows应用程序概述1、设备环境类CDC设备环境是由Windows保存的一个数据结构,该结构包含应用程序向设备输出时所需要的信息,例如:图形是在屏幕上显示还是通过打印机输出。
为了能让用户使用一些特殊的设备环境,基类CDC还派生了以下各类:(1)CPaintDC类,此类比较特殊,它的构造函数和析构函数都是针对OnPaint进行的。
用户一旦获得相关的CDC指针,就可以将它当做任何设备环境(包括屏幕、打印机)指针来使用,CPaintDC类的构造函数会自动调用BeginPaint,而它的析构函数则会自动调用EndPaint。
(2)CClientDCCClientDC只能在窗口的客户区(不包括边框、标题栏、选单栏以及状态栏)进行绘图,点(0,0)通常指的是客户区的左上角。
其构造函数调用GetDC,析构函数调用ReleaseDC 函数用法是:CClientDC dc(this);;//this一般指向本窗口或当前活动视图dc.TextOut(10,10,str,str.GetLength());(3)CWindowDC•允许在窗口的任意位置中进行绘图,点(0,0)指整个窗口的左上角。
其构造函数调用GetWindowDC,析构函数调用ReleaseDC函数。
•Windows为设备环境提供了各种各样的绘图工具,例如:画笔、画刷、字体等。
MFC封装了这些工具,并提供相应的类来作为应用程序的图形设备接口(GDI,Graphics Device Interface),这些类有一个共同的抽象基类CGdiObject,如下所示:类名说明:•CBitmap“位图”是一种位矩阵,每一个显示像素都对应于其中的一个或多个位,用户可以利用位图来表示图象,也可以利用它来创建画刷。
•CBrush“画刷”定义了一种位图形式的像素,利用它可对区域内部填充颜色或样式。
•CFont“字体”是一种具有某种风格和尺寸的所有字符的完整集合,它常常被当做资源存于磁盘中,其中有一些还依赖于某种设备。
CDC绘图
图形设备接口一、GDI、DC的概念1.GDI:(Graphics Device Interfase)图形设备接口,是一个应用程序与输出设备之间的中介。
一方面,GDI向应用程序提供一个与设备无关的编程环境,另一方面,它又以设备相关的格式和具体的设备打交道。
user32.dll2.DC:(Device Context)设备描述表,是一种Windows数据结构。
包括了与一个设备的绘制属性相关的信息。
所有的绘制操作通过一个设备描述表进行,绘制线条、形状和文本的Windows API 函数都与DC有关。
二、在Windows Application程序中画线1.定义两个全局变量用于记录鼠标按下的(x,y)坐标。
int nOrginX;int nOrginY;2.响应鼠标按下和鼠标抬起的消息:在Swich中加入case WM_LBUTTONDOWN:case WM_LBUTTONUP:3.在鼠标按下时记录鼠标按下的(x,y)坐标,查MSDN得知WM_LBUTTONDOWN lParam的低字存放x坐标,高字存放y坐标,将其取出存入nOrginX,nOrginY。
case WM_LBUTTONDOWN:nOrginX=lParam & 0x0000ffff;nOrginY=lParam >> 16 & 0x0000ffff;break;4.在鼠标抬起时画线:case WM_LBUTTONUP:HDC hdc;hdc=GetDC(hwnd);PAINTSTRUCT ps;::MoveToEx(hdc,nOrginX,nOrginY,NULL);::LineTo(hdc,LOWORD(lParam),HIWORD(lParam) );::ReleaseDC(hwnd,hdc);三、在MFC程序中画线:1.在CxxxView(其中xxx是你的工程名字)中响应鼠标按下和鼠标抬起的消息(因为只有CxxxView中才能接收到鼠标消息):使用ClassWizard加入WM_LBUTTONDOWN,WM_LBUTTONUP的消息响应函数OnLButtonDown, OnLButtonUp。
VC使用CDC绘图的程序摘录
值得注意的是
在OnDraw(CDC* pDC)传入的DC指针,最后不能DeleteDC()掉
下面是一个直读BMP文件的例子
// TODO: Add your control notification handler code here
CFile cf;//文件变量,用来对文件操作
oldpBitmap=(CBitmap*)pMem->SelectObject(pBitmap);
pMem->SetTextColor(RGB(255,0,0));
于是在每次绘图时
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(0,255,255));
CPen *oldpen=(CPen*)pMem->SelectObject(&pen);
BITMAPFILEHEADER bmfh;//BMP文件头变量
BITMAPINFOHEADER bmih;//BMP文件信息变量
RGBTRIPLE *rgb;//24位真彩色数据格式
char szFilename[80];//文件名变量
CFileException e;//出错处理
strcpy(szFilename,"d:\\bk.bmp");
oldpBitmap=(CBitmap*)pMem->SelectObject(pBitmap);
//pMem->SetTextColor(RGB(255,0,0));
//在屏幕上打点显示图像
for (int i=0; i<bmih.biHeight;i++)
今天在学习用内存DC画图,终于有...
今天在学习用内存DC画图,终于有...DC 即Device Context,是GDI内部的一个资料结构,一个DC 会和某个特定的显示设备(如打印机、屏幕等)产生关联。
我们如果能取得该DC的handle 那我们便可以在这显示设备上写字、画图。
在Form 或Picturebox中都有一个hdc的属性,指的便是这东西,但是,怎么又会有一个Memory DC呢?这是一个存在记忆体内的 dc ,它除了不像form picturebox能将图形、文字显示出来之外,其他的几乎都相同,它也可以用在所有的 GDI API 呼叫之上,其实我们在VB中早就有使用上这 Memory DC 了,只是没有自觉。
当我们设 form picturebox的AutoRedraw = True时, hdc所指的便是Momoory DC,这时我们在其上作绘图动作,都没有显示在form上,这便是先前说的,它只是在记忆体中,不会真的画出图。
而我们下 refresh指令时,便是将这MemoryDC上的图,copy 到 form/PictureBox上。
另外我们也可以使用CreateCompatibleDC() API 它传入一个 hDc ,代表产生的 Memory DC和 hdc相容,若传0则是与屏幕相容的 Memory DC hMemDC = CreateCompatibleDC(0) 这时候,该hMemDC所指的绘图区有多大呢?其实只有一个单色Pixel,直到我们使用SelectObject( hMemDC, hBitmap)那hMemDC显示区就会有和hBitmap一样的宽度、高度、颜色选择等。
而且我们在hMemDC上的任何绘图,也都会反映在 hBitMap上,也就是说,原本hBitMap所指的图,在SelectObject(hMemDC, hBitMap)后,我们使用gdi函式在hMemDC上画一条线,那么该hBitmap所指的图也会有一条线了。
CDC绘图
图形设备接口一、GDI、DC的概念1.GDI:(Graphics Device Interfase)图形设备接口,是一个应用程序与输出设备之间的中介。
一方面,GDI向应用程序提供一个与设备无关的编程环境,另一方面,它又以设备相关的格式和具体的设备打交道。
user32.dll2.DC:(Device Context)设备描述表,是一种Windows数据结构。
包括了与一个设备的绘制属性相关的信息。
所有的绘制操作通过一个设备描述表进行,绘制线条、形状和文本的Windows API 函数都与DC有关。
二、在Windows Application程序中画线1.定义两个全局变量用于记录鼠标按下的(x,y)坐标。
int nOrginX;int nOrginY;2.响应鼠标按下和鼠标抬起的消息:在Swich中加入case WM_LBUTTONDOWN:case WM_LBUTTONUP:3.在鼠标按下时记录鼠标按下的(x,y)坐标,查MSDN得知WM_LBUTTONDOWN lParam的低字存放x坐标,高字存放y坐标,将其取出存入nOrginX,nOrginY。
case WM_LBUTTONDOWN:nOrginX=lParam & 0x0000ffff;nOrginY=lParam >> 16 & 0x0000ffff;break;4.在鼠标抬起时画线:case WM_LBUTTONUP:HDC hdc;hdc=GetDC(hwnd);PAINTSTRUCT ps;::MoveToEx(hdc,nOrginX,nOrginY,NULL);::LineTo(hdc,LOWORD(lParam),HIWORD(lParam) );::ReleaseDC(hwnd,hdc);三、在MFC程序中画线:1.在CxxxView(其中xxx是你的工程名字)中响应鼠标按下和鼠标抬起的消息(因为只有CxxxView中才能接收到鼠标消息):使用ClassWizard加入WM_LBUTTONDOWN,WM_LBUTTONUP的消息响应函数OnLButtonDown, OnLButtonUp。
MFC中的CDC 绘图(2)
MFC中的CDC 绘图(2)4.面色(刷)在Windows中,面状图必须用刷(brush)来填充,所以面色是由刷色来确定的。
MFC中的刷类为CBrush(它也是CGDIObject的派生类),刷的创建与使用的步骤与笔的相似。
构造函数有4个:CBrush( ); // 创建一个刷的空对象CBrush( COLORREF crColor ); // 创建颜色为crColor的实心刷CBrush( int nIndex, COLORREF crColor ); // 创建风格由nIndex指定且颜色为crColor的条纹(hatch孵化)刷,其中nIndex可取条纹风格(Hatch Styles)值:符号常量数字常量风格HS_HORIZONTAL 0 水平线HS_VERTICAL 1 垂直线HS_FDIAGONAL 2 正斜线HS_BDIAGONAL 3 反斜线HS_CROSS 4 十字线(正网格)HS_DIAGCROSS 5 斜十字线(斜网格)CBrush( CBitmap* pBitmap ); // 创建位图为pBitmap的图案刷如:pDC->FillRect( &rect, new CBrush( RGB(r, g,b) ) );与构造函数相对应,有多个创建不同类型刷的成员函数:BOOL CreateSolidBrush( COLORREF crColor );BOOL CreateHatchBrush( int nIndex, COLORREF crColor );BOOL CreatePatternBrush( CBitmap* pBitmap );BOOL CreateDIBPatternBrush( HGLOBAL hPackedDIB, UINT nUsage );BOOL CreateDIBPatternBrush( const void* lpPackedDIB, UINT nUsage );BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush );BOOL CreateSysColorBrush( int nIndex );预定义的刷对象有BLACK_BRUSH(黑刷)、DKGRAY_BRUSH(暗灰刷)、GRAY_BRUSH(灰刷)、HOLLOW_BRUSH(空刷)、LTGRAY_BRUSH(亮灰刷)、NULL_BRUSH(空刷)、WHITE_BRUSH (白刷)缺省的刷为空刷与笔一样,可以用函数SelectObject或SelectStockObject将自定义的刷或预定义的刷选入DC 中,供绘面状图时使用。
CDC双缓冲防闪屏绘图总结
CDC双缓冲防闪屏绘图总结CDC在屏幕绘图可以用以下方法:CDC dc;dc.CreateCompatibleDC(NULL);CBitmap m_bitmap;m_bitmap.LoadBitmap(IDB_BITMAP1); //载入资源文件dc.SelectObject(&m_bitmap);CDC *pDC = GetDC();pDC->BitBlt(0,0,200,100,&dc,0,0,SRCCOPY);m_bitmap.DeleteObject();dc.DeleteDC();上面虽然可以在屏幕绘图,但是如里需要绘多张图,并且有重叠的部份,当鼠标改变窗口大小时,重叠部份有严重的闪烁。
非常难看CDC *pDC = GetDC();pDC->BitBlt(0,0,200,100,&dc,0,0,SRCCOPY);这个方式是直接在屏幕绘图,如果多张图,即多次调用此方法。
为了避免闪烁,可采用双缓冲的方法,不管你要绘多少张图,先把它们绘在一个内存DC,之后再在屏幕显示DC小知识点:CDC dc;这个是内存dc,使用BitBlt只会在内存中,不会在屏幕显示一旦dc=GetDC();此时dc就与屏幕有关了,BitBlt方法就会输出的屏幕CDC双缓冲防闪屏绘图实例下面的nWidth,nHeight是屏幕的宽高CDC *pDC=this->GetDC(); //此DC负责在屏幕显示CDC dc,sub_dc; //dc负责组建对话框整张大图,sub_dc负责里面小块dc.CreateCompatibleDC(NULL);sub_dc.CreateCompatibleDC(&dc);//注意参数,&dc就指定了sub_dc是基于dc的。
CBitmap bg_bmp,load_bmp;// bg_bmp负责构造背景,load_bmp负责从资源文件载入位图bg_bmp.CreateCompatibleBitmap(pDC,nWidth,nHeight); //先创建一张与对话框当前大小一致的位图dc.SelectObject(&bg_bmp);dc.FillSolidRect(0,0,nWidth,nHeight,RGB(236,236,234)); //构造背景bg_bmp.DeleteObject();//构造第一张图load_bmp.LoadBitmap(IDB_TITLE_L);//从资源载入第一张图sub_dc.SelectObject(&load_bmp);//放到sub_dc中,dc.BitBlt(0,0,16,28,&sub_dc,0,0,SRCCOPY); //把sub_dc的内容写到dc中,此时dc的内容并不会在屏幕显示load_bmp.DeleteObject();//构造第二张图load_bmp.LoadBitmap(IDB_TITLE_BG);//从资源载入第二张图sub_dc.SelectObject(&load_bmp); //放到sub_dc中,dc.StretchBlt(16,0,(nWidth-145),28,&sub_dc,0,0,1,28,SRCCOPY); //再把sub_dc 的内容写到dc中,这样第二张图就与第一张图合在一起变成了一张图load_bmp.DeleteObject();//输出到屏幕pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dc,0,0,SRCCOPY);this->ReleaseDC(pDC);this->ReleaseDC(&dc);this->ReleaseDC(&sub_dc);OK,至此双缓冲绘图完全完成了。
C++ CDC画图
CDC继承层次:CObject└CDC定义:CDC类定义的是设备上下文对象的类。
CDC对象提供处理显示器或打印机等设备上下文的成员函数,以及处理与窗口客户区对应的显示上下文的成员。
通过CDC对象的成员函数进行所有的绘图。
类对设备上下文操作提供了成员函数,处理绘图工具。
安全型图形设备接口(GDI)对象收集,以及处理颜色和调色板。
它还为获取和设置绘图属性、映射,处理视点、窗口扩展、转换坐标,处理区域、剪贴、绘制直线及绘制简单椭圆和多边形等形状提供了成员函数。
另外还为绘制文本、处理字体,使用打印机跳转,滚动和播放元文件提供成员函数。
使用CDC对象时要构造它,然后调用与它平等的、使用设备上下文的Windows 函数的成员函数。
注意:Windows 95下所有屏幕坐标限制在16位以内。
因此向CDC成员函数传递的int必须在-32768至32767之间。
为了特定用途,Microsoft基本类库提供了几个CDC派生类。
CPaintDC 包括BeginPaint和EndPaint调用。
CClientDC管理窗口用户区对应的显示上下文。
CWindowDC管理与整个窗口对应的显示上下文,包括它的结构和控件。
CMetaFileDC与带元文件的设备上下文对应。
CDC包含m_hDC和m_hAttribDC两个设备上下文,它们在CDC对象创建时参考同一个设备。
CDC指导所有对m_hDC的输出GDI调用以及对m_hAttribDC的大部分属性GDI调用(GetTextColor是属性调用的例子,而SetTextColor是一个输出调用)。
例如框架使用这两个设备上下文实现CMetaFileDC对象,在从物理设备读取属性期间向元文件发送输出。
打印预览以相同风格在框架中实现。
还可以以相似方法在特殊应用代码中使用这两个设备上下文。
可能多次需要来自m_hDC和m_hAttribDC设备上下文的文本度量信息。
以下几对函数提供了这项功能:使用m_hAttribDC 使用m_hDCGetTextExtent GetOutputTextExtentGetTabbedTextExtent GetOutputTabbedTextExtentGetTextMetrics GetOutputTextMetricsGetCharWidth GetOutputCharWidthCDC类成员数据成员m_hDC CDC对象使用的输出设备上下文m_hAttribDC CDC对象使用的输出属性上下文构造函数CDC 构造一个CDC对象初始化CreateDC 为指定设备创建设备上下文CreateIC 为指定设备创建信息上下文。
CDC画图
绘图一般在视图类的(屏幕/打印机)绘图消息响应函数OnDraw中进行,例如:void CTestView::OnDraw(CDC* /*pDC*/) {CTestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: 在此处为本机数据添加绘制代码}每次需要重绘窗口时(程序启动/窗口大小改变/全部或部分窗口重现/程序员调用RedrawWindow或UpdateWindow),应用程序框架都会调用该CWnd的消息响应成员函数(的覆盖)来绘制窗口客户区。
在Windows中,绘图一般在视图窗口的客户区进行,使用的是MFC的设备上下文(DC =Device-Context)类CDC中各种绘图函数。
在绘图前,必须先得到客户区大小和DC、设置绘图颜色,然后再根据文档数据或用户操作来绘制图形。
1 几何对象的结构和类为了使用绘图函数,应该先了解绘图所用到的几种表示几何对象的结构和类。
这些结构和类分别定义在头文件windef.h和afxwin.h中。
1.点1)点结构POINT点数据结构POINT用来表示一点的x、y坐标:typedef struct tagPOINT {LONG x;LONG y;} POINT;2)点类CPoint点类CPoint为一个没有基类的独立类,封装了POINT结构,有成员变量x和y,其构造函数有5种:CPoint( );CPoint( int initX, int initY );CPoint( POINT initPt );CPoint( SIZE initSize );CPoint( LPARAM dwPoint ); // 低字设为x、高字设为yCPoint类还定义了4个平移和设置函数:void Offset(int xOffset, int yOffset);void Offset(POINT point);void Offset(SIZE size);void SetPoint(int X, int Y);CPoint类还重载了+、-、+=、-=、==、!=等运算符来支持CPoint对象和CPoint、POINT、SIZE对象之间的运算。
利用CDC实现绘图程序v1
应用Windows绘制一直线,所需的是一个设备环境 对象的指针和直线坐标,设备环境对象的指针叫做 设备环境句柄(HDC)。
– ::MoveTo(HDC hdc, int x, int y); – ::LineTo(HDC hdc, int x, int y);
–ReleaseDC(pDC);
用户最有可能用通用设备环境来做绘图工作。每 次释放一个通用设备环境时,为它们设置的值都 被丢失。但是,可以用下面两个CDC成员函数保存 和恢复一个设备环境的设置值:
–SaveDC()保存设备环境的当前状态。 –RestoreDC()将设备环境恢复到用SaveDC()保存的状态。
14
3.3画形状
这里的形状是一系列封闭线条。 Rectangle()画一个矩形 Pie()画一个饼状楔形 RoundRect()画一个圆角矩形 Draw3dRect()画一个三维矩形 Polygon()画一个多边形 DrawEdge()画一个矩形的边缘 PolyPolygon()创建一个或多个多边形
因为所有的绘图函数只有一个设备环境,因此,每 个函数可能只使用存储在设备环境中20%的属性。
一个设备环境既可以自身包含一种特定的绘图属性, 也可以指向另一个包含某种特定属性ห้องสมุดไป่ตู้对象。例如, 画一条线的属性(如宽度或颜色)可存储在一个单独 的Pen对象中,而由设备环境指向该对象。
创建这些附加的图形对象,与创建一个窗口对象的 方法一样,先创建MFC类对象,然后调用那个类的 成员函数Create()。附加的图形对象一旦被创建, 需要告诉设备环境运用SelectObject()使用该新对象, SelectObject()只是把设备环境指向新的图形对象。
图形输出基本图形显示用CDC绘图函数绘制基本图形
x2-矩形右下角的逻辑x坐标。 y2-矩形右下角的逻辑y坐标。 lpRect-指定矩形的逻辑坐标,可以是一个CRect对象或指向RECT 结构的指针。 Example:在OnDraw函数中,添加如下语句
Example:在OnDraw函数中,添加如下语句 pDC->Ellipse(100,200,400,300); pDC->Ellipse(100,300,300,500); 则 在 矩 形 区 (100,200,400,300) 绘 制 一 个 椭 圆 , 在 正 方 形 区 (100,300,300,500)绘制一个圆。 △CDC::Rectangle 格式:BOOL Rectangle(int x1,int y1,int x2,int式:BOOL Arc(int x1,y1,int x2,int y2,int x3,int y3,int x4,int y4);
BOOL Arc(LPCRECT lpRect,POINT ptStart,POINT ptEnd); 功能:绘制一个椭圆弧。所画弧是由指定的限定矩形所定义的椭 圆的一部分。 返回:若调用成功,则返回非0。 参数:x1-限定矩形左上角的逻辑x坐标。
y1-限定矩形左上角的逻辑y坐标。 x2-限定矩形右下角的逻辑x坐标。 y2-限定矩形右下角的逻辑y坐标。 x3-弧起点的逻辑x坐标(不一定在弧上)。 y3-弧起点的逻辑y坐标(不一定在弧上)。 x4-弧终点的逻辑x坐标(不一定在弧上)。 y4-弧终点的逻辑y坐标(不一定在弧上)。
lpRect-指定限定矩形(以逻辑单位计),可以是一个CRect对象 或指向RECT结构的指针。 ptStart-指定弧起点的逻辑(x,y)坐标,可以是一个POINT结构或一 个CPoint对象。 ptEnd-指定弧终点的逻辑(x,y)坐标,可以是一个POINT结构或一 个CPoint对象。 Example:在OnDraw函数中,添加如下语句
第8章:利用CDC实现绘图程序
CWindowDC对象的窗口句柄保存在成员变量m_hWnd,为构造 CWindowDC,需将CWnd作为参数传递给构造函数。
Visual C++
2.应用程序架构包含的主要类 该程序主要包含的类有CAboutDlg关于对话框类、 CMainFrame主框架类、CSingleDrawDoc文 档类、CSingleDrawView视图类。
有关绘制功能的实现,一般是在视图类中完成, 因此,这一章的实例都是对视图类 CSingleDrawView的操作。
✓ CPaintDC对象在构造时调用CWnd::BeginPaint函数,并返回 DC用于绘图,在析构时自动调用CWnd::EndPaint函数释放DC。 CPaintDC仅在WM_PAINT消息需要响应时才起作用,通常是 在应用程序的OnPaint响应函数中使用。
8.1.4 续1
Visual C++
在由AppWizard创建的MFC应用程序中,视图类的OnDraw 成员函数是一个处理图形的关键虚函数,它带有一个指向设备环 境对象的指针pDC,MFC的绘图成大多都是通过pDC这个指针来
加以访问的。
下面为CDC类的函数的分类
分类 位图函数 剪裁函数 坐标函数 设备描述表函数
Visual C++
用途 操作位图和像素的函数 定义和操作剪裁设备边界的函数 在物理设备和逻辑设备之间转换的函数 获取有关DC及其属性信息的函数
CDC类及绘图函数
首页 »软件开发 » VS2010/MFC编程入门之四十九(图形图像:CDC类及其屏幕绘图函数)VS2010/MFC编程入门之四十九(图形图像:CDC类及其屏幕绘图函数)分类标签: 编程入门VS2010VC++MFC上一节中鸡啄米讲了文本输出的知识,本节的主要内容是CDC类及其屏幕绘图函数。
CDC类简介CDC类是一个设备上下文类。
CDC类提供了用来处理显示器或打印机等设备上下文的成员函数,还有处理与窗口客户区关联的显示上下文的成员函数。
使用CDC的成员函数可以进行所有的绘图操作,包括处理绘图工具、GDI对象的选择、颜色和调色板的处理、获取和设置绘图属性、映射、窗口范围、坐标转换、剪切以及绘制直线、简单图形、椭圆和多边形等,另外它还为文本输出、处理字体、使用打印机跳转和滚动等提供了成员函数。
如上所述,CDC类几乎封装了所有的Windows GDI函数,另外,MFC中还有几个由CDC类派生的子类,包括CWindowDC、CPaintDC、CClientDC、CMetaFileDC,它们用来进行一些特定的绘图操作。
一般我们在使用完CDC对象后要记得删除它,否则会有内存泄露。
很多情况下我们可以调用CWnd::GetDC()函数来获取设备上下文指针,即CDC指针,这个时候记得用完后调用CWnd::ReleaseDC()函数释放设备上下文。
CDC类的屏幕绘图成员函数CDC类有很多成员函数,鸡啄米在这里只大概讲下比较常用的绘图函数,包括绘制点、直线、矩形、椭圆、多边形、文本以及位图等的成员函数。
COLORREF SetPixel(int x,int y,COLORREF crColor);COLORREF SetPixel(POINT point,COLORREF crColor);上面两个成员函数用来将指定坐标点的像素设置为指定的颜色,这样就实现了画点功能。
参数x为点的逻辑x坐标;参数y为点的逻辑y坐标;参数crColor为要为点设置的颜色;参数point指定点的逻辑x坐标和逻辑y坐标,可以为其传入POINT结构体变量或者CPoint对象。
第七章 图形设备接口与绘图应用
基于 MFC 的 Windows 编程与以往 Windows 编程不同,它总是选择一个 MFC 类对设备环境 进行访问。 MFC 提供了几种不同的设备环境类, CDC 是以下所列设备环境类的基类,它封装了 GDI 的一些图形处理函数。常用的派生类有以下 几种: CClientDC : 绘图区域指窗口的客户区,用来立 即响应鼠标事件进行绘图,设备环境的建立和初始 化都在鼠标消息对应的处理程序中。 所谓客户区是指窗口区域中除去边框、标题 栏、菜单栏或可能有的状态栏、对话栏等以外的 部分。坐标( 0 , 0 )通常指客户区的左上角。在 使用 CClientDC 绘图时,通常先调用窗口的 GetClientRect ( )来获取客户区的大小。
Company Logo
CBrush (画刷):利用它可为区域内部填充颜色。 CFont (字体):选择一种具有某种风格和尺寸的字体。 字体常常被当作资源存于磁盘中,其中有一些还依赖于特 定设备。 CRgn (区域):定义一个由多边形、椭圆或一由组合形 成的范围,可以利用它来进行填充、裁剪以及鼠标点击操 作。 . CPalette (调色板):选择一种颜色映射接口,它允许 应用程序在不干扰其他应用程序的前提下,充分利用输出 设备的颜色描绘图形。 CBitmap (位图):定义位图。它是一个象素矩阵。用户 可以利用位图来表示图象,也可以利用它来创建画刷。 通常情况下都是使用 GDI 绘图对象类所创建的对象绘 制各种图形,就好像画家手里必须拿着画笔才能作画一样。
图形设备接口与绘图应用
图形设备接口( GDI , Graphics Device Interface )是 windows 系统中的核心模块,它是一个可执行程序 ( GDI.exe )。 在 windows 应用程序中,图形和文本都是通过 GDI 以图 形方式来处理的, GDI 接受了 windows 应用程序的绘图 请求后,它会根据设备环境( DC )的设置,将这些请求 传给相应的设备驱动程序,从而完成特定硬件的输出。 GDI 之所以能够完成应用程序的绘图请求,是因为它含 有在 Windows 应用程序内部可调用的、且与设备无关的 图形操作函数,这些函数可产生各种各样的线、正文和位 图,它们可以输出到许多不同的输出设备上。 GDI 允许一个应用程序产生画笔、画刷、字体和位图等绘 图工具,以供特定的输出操作使用。
绘图类CDC的理解与使用
绘图类CDC的理解与使用在MFC基础类库中有一个类是专门用来绘图的,这个类叫CDC类。
Windows中所有图形图像包括文字的输出都是通过CDC类完成的,因而CDC类又被称为绘图类。
说起CDC就必须先说DC,DC(Device Context)设备描述表或设备上下文。
在过去,不同的输出设备输出方法不同,以至于开发程序时还要针对具体的物理设备编写输出不同代码,极大地限制了程序开发效率,后来出现了Windows操作系统,它使用与设备无关的图形设备环境DC进行显示。
Windows为每一个设备配备了一个DC,DC里包含有输出设备的所有信息。
DC是一个中间平台,相当于一块画布,我们在向具体物理设备输出图像时先将图像绘制在物理设备的DC上,然后再由DC将图像显示到物理设备上。
为什么要这样做呢?DC这块画布是逻辑画布,我们在它上面绘制图像时无需考虑它的设备属性(逻辑画布没有设备属性),我们可以用同一组函数在不同的物理设备的DC上绘图,然后DC再根据其所包含的具体的物理设备描述表将图像绘制到输出设备。
这是一种与设备无关的图形输出方式,解除了在输出时必须考虑具体物理设备的限制,使我们在编程时只需调用绘图函数完成输出即可。
DC相当于是个资源,我们使用它时要获取它的句柄。
CDC类封装了与绘制图形有关的函数,加上Windows系统中的GDI函数即可完成所有图形的绘制。
CDC类所实例化的对象不仅包含这些成员函数,还有两个数据成员,其中一个就是所要输出的物理设备的DC的句柄。
一个CDC类的对象就是一个绘制者,它不仅有绘图方法还有绘图工具,并且它知道该往哪儿绘图。
CDC类还包含获取和修改属性、选取绘画工具的函数。
CDC有三个常用的派生类CClientDC、CPaintDC、CWindowDC,它们的功能和发挥作用的场合不同。
CClientDC:用于在除OnPaint()消息响应函数外的客户区绘图;CPaintDC:只能在OnPaint()消息响应函数内对客户区绘图;CWindowDC:可在整个框架当中任意地方绘图。
C -CDC画图
CDC继承层次:CObject└CDC定义:CDC类定义的是设备上下文对象的类。
CDC对象提供处理显示器或打印机等设备上下文的成员函数,以及处理与窗口客户区对应的显示上下文的成员。
通过CDC对象的成员函数进行所有的绘图。
类对设备上下文操作提供了成员函数,处理绘图工具。
安全型图形设备接口(GDI)对象收集,以及处理颜色和调色板。
它还为获取和设置绘图属性、映射,处理视点、窗口扩展、转换坐标,处理区域、剪贴、绘制直线及绘制简单椭圆和多边形等形状提供了成员函数。
另外还为绘制文本、处理字体,使用打印机跳转,滚动和播放元文件提供成员函数。
使用CDC对象时要构造它,然后调用与它平等的、使用设备上下文的Windows 函数的成员函数。
注意:Windows 95下所有屏幕坐标限制在16位以内。
因此向CDC成员函数传递的int必须在-32768至32767之间。
为了特定用途,Microsoft基本类库提供了几个CDC派生类。
CPaintDC 包括BeginPaint和EndPaint调用。
CClientDC管理窗口用户区对应的显示上下文。
CWindowDC管理与整个窗口对应的显示上下文,包括它的结构和控件。
CMetaFileDC与带元文件的设备上下文对应。
CDC包含m_hDC和m_hAttribDC两个设备上下文,它们在CDC对象创建时参考同一个设备。
CDC指导所有对m_hDC的输出GDI调用以及对m_hAttribDC的大部分属性GDI调用(GetTextColor是属性调用的例子,而SetTextColor是一个输出调用)。
例如框架使用这两个设备上下文实现CMetaFileDC对象,在从物理设备读取属性期间向元文件发送输出。
打印预览以相同风格在框架中实现。
还可以以相似方法在特殊应用代码中使用这两个设备上下文。
可能多次需要来自m_hDC和m_hAttribDC设备上下文的文本度量信息。
以下几对函数提供了这项功能:使用m_hAttribDC 使用m_hDCGetTextExtent GetOutputTextExtentGetTabbedTextExtent GetOutputTabbedTextExtentGetTextMetrics GetOutputTextMetricsGetCharWidth GetOutputCharWidthCDC类成员数据成员m_hDC CDC对象使用的输出设备上下文m_hAttribDC CDC对象使用的输出属性上下文构造函数CDC 构造一个CDC对象初始化CreateDC 为指定设备创建设备上下文CreateIC 为指定设备创建信息上下文。
第4章 利用CDC类实现绘图程序
第四章利用CDC类实现绘图程序n输出操作是我们必需要掌握和熟练运用的工具,所有输出操作与CDC类是分不开的,在本章中,我们将学习如何运用CDC 类进行输出操作。
n希望大家根据所讲内容进行自学拓展,以达到熟练运用的效果。
n绘图功能的实现,往往要靠重载视图类的OnDraw函数实现。
n该函数用于绘制窗口编写一个简单的文本输入程序:双击OnDraw函数,跳转到该函数页面。
void CMy046View::OnDraw(CDC* pDC) {CMy046Doc* pDoc= GetDocument(); ASSERT_VALID(pDoc);在用户区输出语句n在OnDraw函数中输入:pDC->TextOut(10,10,"我的第一个VC程序!");屏幕坐标(0,0)xy(x0,y0) x0y0如何在工程中添加消息响应函数n1. 生成一个工程n2. 选择View/ClassWizard,打开类向导。
在Message选项中选择对应消息。
或者在相应的ClassView窗口的相应类上单击鼠标右键,选择”Add Windows Message Handle…”选项。
双击添加即可如何在工程中添加消息响应函数n1. 生成一个工程n2. 选择View/ClassWizard,打开类向导。
在Message选项中选择对应消息。
或者在相应的ClassView窗口的相应类上单击鼠标右键,选择”Add Windows Message Handle…”选项。
双击添加即可如何在工程中添加消息响应函数n1. 生成一个工程n2. 选择View/ClassWizard,打开类向导。
在Message选项中选择对应消息。
或者在相应的ClassView窗口的相应类上单击鼠标右键,选择”Add Windows Message Handle…”选项。
双击添加即可如何在工程中添加消息响应函数n1. 生成一个工程n2. 选择View/ClassWizard,打开类向导。
VcWindows绘图专题知识讲座
19
CDC绘图例程之二(MFC世界旳晚霞)
WM_TIMER消息处理函数OnTimer()中随机画点 主要实现函数:
SetPixel(int x,int y)-画点函数 MapRand(int x)-产生随机点 BOOL TextOut( int x, int y, const CString& str ); int SetBkMode( int nBkMode ); 例程演示:
7
7.3 CDC旳派生类
CDC旳几种常用派生类-CPaintDC、CClientDC和 CWindowDC
1.CPaintDC类
-该类用于WM_PAINT消息旳处理程序OnPaint()中 WM_PAINT消息是在窗口被变化大小、重画、刷新时产生 CPaintDC类一般用于在OnPaint()函数中实现诸如窗口重
17
6. 绘制矩形,并用目前画刷进行填充 BOOL Rectangle(int x1,int y1,int x2,int y2)
(x1,y1)和(x2,y2)分别 为矩形旳左上角和右下角 旳逻辑坐标
7. 绘制圆角矩形,并用目前画刷填充
圆角旳高度和宽 度
BOOL RoundRect (int x1,int y1,int x2,int y2,
设备描述表即为设备环境旳属性旳集合
为确保图形输出旳 设备无关性
应用程序与 输出设备之 间旳桥梁
直接访问
顾 客
不允许 Win系统
外设
提供
统一旳设备环境(DC)
使应用程序与设备相连3
2.图形刷新
图形刷新是绘图过程中必须考虑旳主要问题
涉及
(1) 刷新祈求
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
7.2
VC的文本操作
7.2.1 7.2.2 7.2.3 7.2.4
文本输出函数 文本属性控制 文本的字体 文本处理实例
13
7.2.1 文本输出函数
在前面的API编程5.5.2节中讲了一个最简单的文本 输出函数TextOut(),其实API编程模式和MFC编程模式 的最大相似之处在于他们调用的API函数和MFC的成员 函数的参数基本上一致,在MFC中出现了很多缺省参数, 调用起来更简单,但他们的核心参数都是一样的,因此 掌握了某一个API函数的用法,在利用MFC编程时,用 法基本一致。API编程模式和MFC编程模式的最大不同 在于其程序的框架不一样,可以说,API编程模式的程 序框架操作系统已经定义好了,这个框架是最原始的操 作系统框架,熟悉该框架比较容易,但框架内部需要自 己做的工作还很多;而MFC是一个应用程序框架,是构 建在操作系统之上的一个应用程序框架。
9
区域函数 简单绘图函数 文本函数
7.1.3 CDC的内容
1.派生类CPaintDC
(1)CPaintDC是从CDC派生出来的设备描述表类,它常常在窗口的 OnPaint函数中使用。查看MFC的源代码 (Studio\VC98\MFC\SRC\viewcore.cpp)中的OnPaint函数的实现可 以知道,OnPaint函数首先构造一个CPaintDC对象,再调用 OnPrepareDC()函数将其准备好,最后以这个准备好的CPaintDC对象 指针为参数,来调用OnDraw函数进行各种图形处理。 (2)CPaintDC对象在构造时调用CWnd::BeginPaint函数,并返回DC 用于绘图,在析构时自动调用CWnd::EndPaint函数释放DC。 CPaintDC仅在WM_PAINT消息需要响应时才起作用,通常是在应用程 序的OnPaint响应函数中使用。
16
7.2.2 文本属性控制
1 .设置文本的背景色 缺省时,在绘制图形或者输出文本时,背景颜色 是白色。可以使用CDC的成员函数SetBkColor函数来设 置新的背景颜色,函数原型为: Virtual COLORREF SetBkColor(COLORREF crcolor); 其中参数crcolor用于指定新的背景颜色。例如要将 背景颜色设为红色,可以用以下语句: SetBkColor(RGB(255,0,0);
14
7.2.1 续1
文本输出除了前面讲的TextOut()外,常见的还有ExtTextOut() , 该函数的原型为: BOOL ExtTextOut { int x, int y; //输出的位置 UINT nOptions;//指定矩形的类型 LPCRECT lpRect;//输出的字符的矩形区域 const CString& str;//欲输出的字符 LPINT lpDxWidths ;//字符间距 };
该函数用来在一个给定的矩形lpRect区域内输出字符串str,此矩形可 以设置为透明的(nOptions=ETO_OPAQUE)或不透明的,当矩形 区域为不透明时,用当前的背景色填充矩形。
15
7.2.1 续2
此矩形也可以设置为裁剪(nOptions=ETO_CLIPPED) 性质或非裁剪性质,当设置为裁剪性质时,所有在矩形外 面的字符串将被裁剪掉。 上述参数中,nOptions主要设置矩形的类型,可以为 ETO_OPAQUE和ETO_CLIPPED两个值的一个或两个组合; lpDxWidths是一个指向整数数组的指针,此数组中存放以 逻辑单位表示的字符间的距离,第n个数代表第n个和n+1 个字符之间的距离。该参数为NULL时,则按本的背景色 在设备描述表中有两项可以影响背景,一个是背景色,另 一个是背景模式。背景模式可以为透明的(Transparent)或 不透明的(Opaque),缺省为不透明的。当背景模式为不透 明时,按背景颜色的值填充字符的空余部分,如果背景模式 为透明的,将不用背景颜色填充,保留屏幕上原来的颜色。 背景模式可用函数SetBkMode来设置,它设置当前的背景模 式并返回原来的背景模式,该函数的原型为: int SetBkMode(int nBkMode); 参数nkbmode指定背景模式,其值可以是OPAQUE或者 TRANSPARENT,如果值为OPAQUE,则显示时背景都改变为 当前背景颜色。如果值为TRANSPARENT,则不改变背景颜色, 此时,任何SetBkColor函数调用都无效,缺省的背景模式为 OPAQUE。
C++语言程序设计 C++语言程序设计
第七讲 利用CDC实现绘图程序 利用CDC CDC实现绘图程序
中国地质大学(武汉) 中国地质大学(武汉) 计算机学院
本章内容包括设备环境与绘图程序的关系,设备环 境主要功能以在MFC对应的CDC类,利用设备环境类CDC 操纵文本(文本的字体、颜色和属性控制),利用设备环 境类CDC实现简单图形的绘制(点、线、椭圆、矩形和弧 等),各种绘图工具(画笔、画刷)使用。 要求了解CDC编写的绘图程序调用GDI ,进而调用 设备驱动程序的流程,CDC的几个派生类及其使用,掌握 CDC的文本操作和图形绘制、常见的绘图参数设置函数的 用法、常见的绘图工具画笔和画刷的使用,熟练掌握调用 API或CDC成员函数选择库存中的绘图工具。
2
本章内容
7.1 图形绘制的基础知识 7.2 VC的文本操作 7.3 CDC的绘图操作 7.3 Windows绘图工具
3
7.1
图形绘制的基本知识
7.1.1 图形操作的接口——GDI 7.1.2 图形操作有关的CDC类 7.1.3 CDC CDC的内容
4
7.1.1 图形操作的接口——GDI
任何图形程序的输出,都离不开图形设备接口GDI (Graphic Device Interface),它是管理Windows应用程 序在窗口内的绘图操作和与此相关的许多其它信息。如图 形设备(打印机、显示器)的信息、绘图的坐标系统和映 射模式、绘图工具的当前状态(什么样的画笔、画刷、文 本的前景色与背景色、文本所使用的字体)。 Windows的GDI绘制的各种图形(点、线、圆、多 边形、矩形等)是与设备无关的,即在屏幕的窗口内绘图 与在打印机上绘图是相似的。 GDI是一个可执行程序,它 接收Windows应用程序的绘图请求(表现为GDI调用), 并将它们传送给相应的设备驱动程序,再由设备驱动程序 驱动相应的硬件设备,如打印机或显示器输出。
7
7.1.2 续
2. 类CDC CDC是后面所讲的其他DC类的基类。CDC基类定 义了设备描述表对象, 并且提供在显示器、打印机或 Windows用户区上绘图的方法,它封装了使用设备环境 的GDI函数。 所有的绘图操作都是直接或间接运用了CDC的成员 函数,这些函数有的进行设备描述表操作,有的是用来 画图的,还有的函数是用来获取或设置绘图属性,为映 像和视点服务的。 在由AppWizard创建的MFC应用程序中,视图类的 OnDraw成员函数是一个处理图形的关键虚函数,它带 有一个指向设备环境对象的指针pDC,MFC的绘图成大 多都是通过pDC这个指针来加以访问的。 下面为CDC类的函数的分类
5
7.1.1续
应用程序使用GDI可以对三种类型的图形进行操作:文本操作、矢 量图形操作和光栅图形操作(图像操作)。 (1)文本操作是以逻辑坐标为单位来计算文本的输出位置,用户可以通 过各种GDI函数来作出具有各种效果的文本。 (2)矢量图形指的是利用画点、直线、曲线(折线、贝塞尔曲线等)、 多边形、扇形、矩形等函数所绘制的图形。 (3)光栅图形操作是指以光栅图形函数对以位图形式存储的数据进行操 作,它包括各种位图和图标的输出,其在屏幕上表现为对若干个行和 列的像素操作。光栅图形操作是直接从内存到显存的拷贝操作,其缺 点是需要额外的内存空间,优点是操作速度快。
6
7.1.2 图形操作有关的CDC类
1.再论设备描述表 设备描述表是一个用来确定任何设备(如显示 器、打印机)的GDI输出位置和内容属性的集合, 是Windows系统下的一个保存GDI 内部数据的数据 结构,它与特定的显示设备相关。对于显示器,设 备描述表总是与显示器上的特定窗口相关。设备描 述表中保存了显示图形所需要的各种参数值,如显 示颜色、显示坐标、显示方式和背景颜色。在 Windows下程序员对所有的绘图功能的调用,都是 通过设备描述表来进行的。
18
7.2.2续2
3.设置文本的排列方式 在文本显示时遇到的另一个问题是文本的排列方式,它 控制文本和给定点的相对位置。在一个图形中加字符说明 时,常常知道一个字符串的某一个边界,如左边界不应超 过某个位置,或右边界不应超过某个位置,或显示的几行 字符串的中心点对齐等。利用CDC的成员函数SetTextAlign 函数就能方便地实现这种控制,其原型为: UINT SetTextAlign (UINT nFlags); 其中,nFlags为文本的对齐方式,其值如下: TA_LEFT TA_BASELINE TA_BOTTOM 将点同边界矩形的水平中心对齐 S将点同所选字体的基线对齐 将点同边界矩形的底线对齐
8
分类 位图函数 剪裁函数 坐标函数 设备描述表函数 绘图属性函数 绘图工具函数 椭圆和多边形函数 字体函数 线输出函数 映像函数
用途 操作位图和像素的函数 定义和操作剪裁设备边界的函数 在物理设备和逻辑设备之间转换的函数 获取有关DC及其属性信息的函数 获取有关DC及其属性信息的函数 DC 为DC获取和设置颜色及模式的函数 DC获取和设置颜色及模式的函数 枚举在DC中可用的笔和刷子的函数 枚举在DC中可用的笔和刷子的函数 DC 绘制椭圆和多边形函数 获取字体属性的函数 在DC上绘制线的函数 DC上绘制线的函数 创建、获取和控制原点, 创建 、 获取和控制原点 , 扩展窗口和视及为 DC获取和设置映像模式的函数 DC获取和设置映像模式的函数 填充区域和控制区域颜色的函数 提供简单矩形和图标的绘制特性函数 输出文本并获取DC当前选中的字体信息的函 输出文本并获取 DC当前选中的字体信息的函 DC 数