Windows C++ 程序设计4.2.ppt
面向对象与可视化面向对象与可视化程序设计程序设计 -Visual C+Visual C+编程编程主讲教师主讲教师主讲教师主讲教师:唐唐唐唐 龙龙龙龙教授教授教授教授 (计算机科学与技术系计算机科学与技术系计算机科学与技术系计算机科学与技术系)黄维通黄维通黄维通黄维通博士博士博士博士 (计算机与信息管理中心)计算机与信息管理中心)计算机与信息管理中心)计算机与信息管理中心)清清清清 华华华华 大大大大 学学学学2001200120012001年年年年2 2 2 2月月月月1第四章第四章 WindowsWindows的的图形设备接口图形设备接口及绘图及绘图2内容提要内容提要w wWindowsWindows图形设备接口图形设备接口w w绘图工具和颜色绘图工具和颜色w w常用绘图函数常用绘图函数w w应用实例应用实例34.1.4.1.WindowsWindows图形设备接口图形设备接口(GDI)GDI)41.1.GDIGDI的基本概念的基本概念FFGDI是是Windows的重要组成部分的重要组成部分与设备无关的图形设备接口与设备无关的图形设备接口GDIGDIGraphiceGraphice Device Interface Device Interfaceuu就是操作系统屏蔽了硬件设备的差异就是操作系统屏蔽了硬件设备的差异就是操作系统屏蔽了硬件设备的差异就是操作系统屏蔽了硬件设备的差异uu用户编程时无需考虑特殊的硬件设置用户编程时无需考虑特殊的硬件设置用户编程时无需考虑特殊的硬件设置用户编程时无需考虑特殊的硬件设置实现系统与用户或绘图程序之间的信息交实现系统与用户或绘图程序之间的信息交换;换;控制在输出设备上显示图形或文字控制在输出设备上显示图形或文字;5Windows支持与设备无关的图形支持与设备无关的图形开发人员只要建开发人员只要建立与输出设备的立与输出设备的关联,让系统加关联,让系统加载相应的设备驱载相应的设备驱动程序即可动程序即可1.1.GDIGDI的基本概念(续)的基本概念(续)FF用用GDI和设备驱动程序支持图形的输出和设备驱动程序支持图形的输出GDI和和设备驱设备驱动程序动程序6Win系统系统外设外设用用户户直接访问直接访问不允许不允许统一的设备环境统一的设备环境(DC)提供提供使应用程序与设备相连使应用程序与设备相连1.1.GDIGDI的基本概念(续)的基本概念(续)FF设备描述表设备描述表设备环境的属性的集合设备环境的属性的集合FF应用程序通过设备描述表的句柄,建立应用程序通过设备描述表的句柄,建立与设备的联系,实现图形操作。与设备的联系,实现图形操作。7设备描述表属性及其相关函数设备描述表属性及其相关函数8应用应用程序程序设备描述表设备描述表及其属性及其属性设备描述表的句柄设备描述表的句柄(间接地存取)(间接地存取)应用程序每一次图形应用程序每一次图形操作均参照设备描述操作均参照设备描述表中的属性执行表中的属性执行92.2.图形刷新图形刷新F绘图中必须考虑的重要问题,包括绘图中必须考虑的重要问题,包括:刷新请求;刷新请求;对刷新请求的响应;对刷新请求的响应;刷新方法。刷新方法。F出现如下情况时,系统发送出现如下情况时,系统发送WM_PAINT消息作为消息作为刷新请求刷新请求:窗口大小的调整;窗口大小的调整;窗口移动;窗口移动;被覆盖后的恢复。被覆盖后的恢复。102.2.图形刷新(续)图形刷新(续)F对三种不同刷新请求的响应对三种不同刷新请求的响应F窗口移动后的刷新窗口移动后的刷新u用户区移动或显示用户区移动或显示u用户窗口大小改变用户窗口大小改变u程序通过滚动条滚动窗口程序通过滚动条滚动窗口F被覆盖区域的刷新被覆盖区域的刷新u被另一个窗口覆盖的恢复被另一个窗口覆盖的恢复FF对象穿越后的刷新对象穿越后的刷新对象穿越后的刷新对象穿越后的刷新(系统自动完成系统自动完成系统自动完成系统自动完成)u光标或图标拖过用户区光标或图标拖过用户区11应用程序在窗口中应用程序在窗口中绘制了一个椭圆,绘制了一个椭圆,颜色列表框覆盖椭颜色列表框覆盖椭圆的一部分圆的一部分关闭颜色选框后,关闭颜色选框后,应用程序需要恢应用程序需要恢复被覆盖部分的复被覆盖部分的颜色和形状颜色和形状2.2.图形刷新(续)图形刷新(续)12窗口被另一个窗口覆盖的区域称为窗口被另一个窗口覆盖的区域称为无效区域无效区域。Windows系统为每个窗口建立一个系统为每个窗口建立一个PAINTSTRUCT结构结构,其中含有包围其中含有包围无效区域无效区域的一个最小矩形的结构的一个最小矩形的结构RECT,程序程序可据此矩形执行刷新操作。可据此矩形执行刷新操作。TypedefTypedef struct struct tagPAINTSTRUCTtagPAINTSTRUCT HDC HDC hdc hdc;/设备环境句柄设备环境句柄 BOOLBOOL fErase fErase;/一般取真值,表示擦除无效矩形的背景一般取真值,表示擦除无效矩形的背景 RECTRECT rcPaintrcPaint;/无效矩形标识无效矩形标识 BOOLBOOL fRestore fRestore;/;/系统保留系统保留 BOOLBOOL fIncUpdate fIncUpdate;/;/系统保留系统保留 BYTEBYTE rgbReserved rgbReserved1616;/系统保留系统保留 PAINTSTRUCT;PAINTSTRUCT;rcPaint 为标准的为标准的RECT数据结构,标数据结构,标识无效矩形,(包含识无效矩形,(包含左上角和右下角的坐左上角和右下角的坐标)标)132.2.图形刷新(续)图形刷新(续)FF常用的刷新方法常用的刷新方法FF保存副本。刷新时将副本拷贝到相应的窗保存副本。刷新时将副本拷贝到相应的窗口中。口中。FF记录事件。刷新时重新执行这个曾经发生记录事件。刷新时重新执行这个曾经发生的事件。的事件。FF重新绘制。将图形绘制处理程序放在消息重新绘制。将图形绘制处理程序放在消息WM_PAINT响应模块中,刷新时重绘图形。响应模块中,刷新时重绘图形。14(1)调用调用BeginPaint函数函数 响应响应WM_PAINT消息进行图形刷新时,调用消息进行图形刷新时,调用BeginPaint函数获取设备环境函数获取设备环境 hdchdc=BeginPaintBeginPaint(hwndhwnd,&,&psps);/psps为为PAINTSTRUCTPAINTSTRUCT类型结构类型结构系统获取设备环境的系统获取设备环境的同时填写同时填写ps结构,以结构,以标识无效矩形区标识无效矩形区由由BeginPaint获取的设备环境要用获取的设备环境要用EndPaint函数释放函数释放void EndPaint(HWND hwnd,PAINTSTRUCT&ps)3.3.获取设备环境的方法获取设备环境的方法15(2)调用调用GetDC函数函数 如果绘图工作并非由如果绘图工作并非由WM_PAINT消息驱动,则调消息驱动,则调用用GetDC函数获取设备环境。函数获取设备环境。hdchdc=GetDCGetDC(hwndhwnd););由由GetDC获取的设备环境须用获取的设备环境须用ReleaseDC释放释放 void ReleaseDC(HWND hwnd);16174.4.映像模式映像模式F映像模式定义了将逻辑单位转化为设备的度映像模式定义了将逻辑单位转化为设备的度量单位,以及量单位,以及x和和y方向;方向;F程序员可在一个统一的逻辑坐标系中操作,程序员可在一个统一的逻辑坐标系中操作,不必考虑输出设备的坐标系情况。不必考虑输出设备的坐标系情况。F窗口窗口对应逻辑坐标系上所设定的区域;对应逻辑坐标系上所设定的区域;F视口视口对应实际输出设备上所设定的区域。对应实际输出设备上所设定的区域。184.4.映像模式(续)映像模式(续)F坐标系统坐标系统F逻辑坐标系统逻辑坐标系统F设备坐标系统:以象素点来为单位设备坐标系统:以象素点来为单位F屏幕屏幕整个屏幕坐标区为坐标系统整个屏幕坐标区为坐标系统F窗口窗口应用程序的窗口为坐标区(含边界)应用程序的窗口为坐标区(含边界)F用户区用户区窗口中的工作区为坐标系统窗口中的工作区为坐标系统19缺省的映缺省的映射模式射模式将窗口中的对称将窗口中的对称图形映射到视口图形映射到视口时仍为对称图形时仍为对称图形按照窗口和视口按照窗口和视口的坐标比例进行的坐标比例进行映射映射4.4.映像模式(续)映像模式(续)204.4.映像模式(续)映像模式(续)F映像模式的设置映像模式的设置F应用程序可获取设备环境的当前映像模式应用程序可获取设备环境的当前映像模式nMapModenMapMode=GetMapModeGetMapMode(hdchdc););/nMapMode为映像模式的整型标识符为映像模式的整型标识符。F根据需要设置映像模式根据需要设置映像模式SetMapModeSetMapMode(hdchdc,nMapModenMapMode););21窗口窗口区域的定义函数:区域的定义函数:BOOL Set BOOL Set WindowExtExWindowExtEx(HDC HDC hdchdc,int nHeightint nHeight,nWidthnWidth,/窗口高宽,以窗口高宽,以逻辑逻辑单位表示。单位表示。LPSIZE LPSIZE lpSizelpSize /原窗口区域尺寸的原窗口区域尺寸的SIZESIZE结构地址结构地址););视口视口区域的定义函数:区域的定义函数:BOOL SetBOOL Set ViewportExtEx ViewportExtEx(HDC HDC hdchdc,int nHeightint nHeight,nWidthnWidth,/,/新视口高宽,以新视口高宽,以物理物理设备单位表示设备单位表示 LPSIZE LPSIZE lpSizelpSize););只有在映射模式为只有在映射模式为MM_ANISOTROPIC和和MM_ISOTROPIC时才有意义时才有意义22视口和窗口视口和窗口的原点坐标的原点坐标缺省值均为(缺省值均为(0,0)。)。可调用函数可调用函数SetWindowOrgEx设定窗口原点。设定窗口原点。可调用函数可调用函数SetViewportOrgEx设定视口原点。设定视口原点。SetWindowOrgEx函数的原形为函数的原形为:BOOL BOOL SetWindowOrgExSetWindowOrgEx(HDC HDC hdchdc,int int X,Y X,Y,/以以逻辑逻辑单位表示的窗口原点坐标单位表示的窗口原点坐标 LPPOINT LPPOINT lpPointlpPoint /函数调用前原点坐标的函数调用前原点坐标的POINTPOINT结构的地址结构的地址););只有在映射模式为只有在映射模式为MM_ANISOTROPIC和和MM_ISOTROPIC时才有意义时才有意义234.2.4.2.绘图工具和颜色绘图工具和颜色24WHITE_PENBLACK_PENDC_PENNULL_PEN1.1.画笔画笔FF画笔的操作画笔的操作创建画笔创建画笔将画笔选入设备环境将画笔选入设备环境删除画笔删除画笔FF画笔的创建画笔的创建 使用前必须先定义一个画笔句柄。形式如下:使用前必须先定义一个画笔句柄。形式如下:HPEN hP;Windows系统定义的系统定义的四种画笔四种画笔 调用函数调用函数GetStockObject获取一种画笔,如:获取一种画笔,如:hPhP=GetStockObjectGetStockObject(BLACK_PENBLACK_PEN);/取黑色笔取黑色笔25PS_DASH:虚线虚线PS_DASHDOT:点划线点划线PS_DASHDOTDOT:双点划线双点划线PS_DOT:点线点线PS_INSIDEFRAME:实线实线PS_NULL:无无PS_SOLID:实线实线1.1.画笔(续)画笔(续)F创建创建新新画笔,画笔,形式如下:形式如下:hPhP=CreatePenCreatePen(int int nPenStylenPenStyle,/,/确定确定画笔样式画笔样式 int nWidthint nWidth,/画笔画笔宽度宽度 COLORREF COLORREF rgbColorrgbColor /画笔画笔颜色颜色););261.1.画笔(续)画笔(续)F创建画笔后,必须调用创建画笔后,必须调用SelectObjectSelectObject函数将其函数将其选入设备环境。选入设备环境。SelectObjectSelectObject(hdchdc,hPhP););/hPhP为所创建或获取的画笔句柄为所创建或获取的画笔句柄F不再使用当前画笔时,需删除之,释放内存。不再使用当前画笔时,需删除之,释放内存。DeleteObjectDeleteObject(hPhP););272.2.画刷画刷F画刷的操作,包括:创建、选入设备环境和删画刷的操作,包括:创建、选入设备环境和删除。除。F画刷的创建画刷的创建使用画刷需先定义一个画刷句柄。形式如下:使用画刷需先定义一个画刷句柄。形式如下:HBRUSHHBRUSH hBr hBr;/hBr为画刷句柄为画刷句柄调用函数调用函数GetStockObject获取一种画刷获取一种画刷hBrhBr=(HBRUSHHBRUSH)GetStockObjectGetStockObject(nBrushStylenBrushStyle)282.2.画刷(续)画刷(续)FFWindowsWindows系统提供的系统提供的7 7种画刷样式种画刷样式BLACK_BRUSH黑色画刷黑色画刷DKGRAY_BRUSH深灰色画刷深灰色画刷GRAY_BRUSH灰色画刷灰色画刷HOLLOW_BRUSH虚画刷虚画刷LTGRAY_BRUSH亮灰色画刷亮灰色画刷NULL_BRUSH空画刷空画刷WHITE_BRUSH白色画刷白色画刷29HS_BDIAGONAL 45度从左上到右下度从左上到右下HS_DIAGCROSS 45度叉线度叉线HS_FDIAGONAL 45度从左下到右上度从左下到右上HS_CROSS 垂直相交的阴影线垂直相交的阴影线HS_HORIZONTAL 水平阴影线水平阴影线HS_VERTICAL垂直阴影线垂直阴影线2.2.画刷(续)画刷(续)F可调用创建画刷函数:可调用创建画刷函数:F创建具有指定颜色的单色画刷创建具有指定颜色的单色画刷 hBrhBr=CreateSolidBrushCreateSolidBrush(rgbColorrgbColor););F创建指定阴影图案和颜色的画刷创建指定阴影图案和颜色的画刷 hBrhBr=CreateHatchBrushCreateHatchBrush(int int nHctchStylenHctchStyle,COLORREF COLORREF rgbColorrgbColor););302.2.画刷(续)画刷(续)F将画刷选入设备环境将画刷选入设备环境 SelectObject(hdc,hBr););F不使用画刷时,可删除画刷,释放内存不使用画刷时,可删除画刷,释放内存DeleteObject(hBr);31FWindows使用宏使用宏RGB定义绘图的颜色,定义绘图的颜色,其形式为其形式为:F RGB(nRed,nGreen,nBlue)红色红色:RGB(255,0,0)蓝色蓝色:RGB(0,0,255)绿色绿色:RGB(0,255,0)3.3.颜色的设置颜色的设置324.3.4.3.常用绘图函数常用绘图函数331设置画笔当前设置画笔当前位置位置的函数的函数MoveToEx BOOL MoveToEx (HDC hdc,int X,Y,/X、Y分别为新位置的逻辑坐标分别为新位置的逻辑坐标 LPPOINT lpPoint/存放原画笔位置的存放原画笔位置的POINT结构地址结构地址)2 从当前位置向指定坐标点从当前位置向指定坐标点画直线画直线的函数的函数LineToExBOOL BOOL LineToExLineToEx(HDC(HDC hdc hdc,int X,int Y),int X,int Y)/X/X和和Y Y为线段的终点坐标为线段的终点坐标3 从当前位置开始,依次连接从当前位置开始,依次连接lpPoints中指定的各点的中指定的各点的折线折线BOOL Polyline(HDC hdc,LPPOINT lpPoints,/各点坐标的各点坐标的POINT结构数组的指针结构数组的指针 int nCount /nCount为为POINT数组中点的个数数组中点的个数)344 绘制绘制椭圆弧线椭圆弧线BOOL Arc(HDC hdc,int X1,intY1,/边框矩形左上角的逻辑坐标边框矩形左上角的逻辑坐标int X2,int Y2,/边框矩形右下角的逻辑坐标边框矩形右下角的逻辑坐标int X3,int Y3,/椭圆弧起始经线的确定点坐标椭圆弧起始经线的确定点坐标int X4,int Y4/椭圆弧终止经线的确定点坐标椭圆弧终止经线的确定点坐标)(X1,Y1)(X4,Y4)(X3,Y3)(X2,Y2)所画曲线所画曲线355 绘制绘制饼图饼图,并用当前画刷,并用当前画刷填充填充BOOL Pie(HDC hdc,int X1,intY1,/边框矩形左上角的逻辑坐标边框矩形左上角的逻辑坐标int X2,int Y2,/边框矩形右下角的逻辑坐标边框矩形右下角的逻辑坐标int X3,int Y3,/椭圆弧起始经线的确定点坐标椭圆弧起始经线的确定点坐标int X4,int Y4/椭圆弧终止经线的确定点坐标椭圆弧终止经线的确定点坐标)(X1,Y1)(X4,Y4)(X3,Y3)(X2,Y2)填充区域填充区域366 绘制绘制矩形矩形,并用当前画刷,并用当前画刷填充填充BOOL Rectangle(HDC hdc,int X1,int Y1,int X2,int Y2)(X1,Y1)和和(X2,Y2)分别分别为矩形的左上角和右为矩形的左上角和右下角的逻辑坐标下角的逻辑坐标7 绘制绘制圆角矩形圆角矩形,并用当前画刷,并用当前画刷填充填充BOOL RoundRect(HDC hdc,int X1,int Y1,int X2,int Y2,int nHeight,int nWidth)圆角的高度和宽度378.绘制绘制椭圆椭圆,并用当前画刷,并用当前画刷填充填充 BOOL Ellipse(HDC hdc,intX1,intY1,intX2,intY2)9绘制绘制多边形多边形,并用当前画刷,并用当前画刷填充填充BOOL Polygon(HDC hdc,LPPOINT lpPoints,int nCount)包含各点坐标的包含各点坐标的POINT数组的地址数组的地址多边形点多边形点的个数的个数384.4.4.4.应用实例应用实例39【例【例4-1】利用绘图函数创建填充区,三个填充图形:利用绘图函数创建填充区,三个填充图形:第一个是用深灰色画刷填充带圆角的矩形,第一个是用深灰色画刷填充带圆角的矩形,第二个是采用亮灰色画刷填充一个椭圆型图,第二个是采用亮灰色画刷填充一个椭圆型图,第三个是用虚画刷填充饼形图。第三个是用虚画刷填充饼形图。使用虚画刷填充使用虚画刷填充时,看不出填充时,看不出填充效果效果!40#include#include#includelong WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam);BOOL InitWindowsClass(HINSTANCE hInstance);BOOL InitWindows(HINSTANCE hInstance,int nCmdShow);HWND hWndMain;41Int WINAPI WinMain/主函数主函数(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)MSG Message;if(!InitWindowsClass(hInstance)return FALSE;if(!InitWindows(hInstance,nCmdShow)return FALSE;while(GetMessage(&Message,0,0,0)/消息循环消息循环 TranslateMessage(&Message);DispatchMessage(&Message);return Message.wParam;42long WINAPI long WINAPI WndProcWndProc(HWND(HWND hWndhWnd,UINT,UINT iMessageiMessage,UINT UINT wParamwParam,LONG,LONG lParamlParam)HDC hDC;/定义指向设备的句柄定义指向设备的句柄 HBRUSH hBrush;/定义指向画刷的句柄定义指向画刷的句柄 HPEN hPen;/定义指向画笔的句柄定义指向画笔的句柄 PAINTSTRUCT PtStr;/定义指向包含绘图信息的结构变量定义指向包含绘图信息的结构变量 switch(iMessage)/处理消息处理消息case WM_PAINT:/处理绘图消息处理绘图消息 hDC=BeginPaint(hWnd,&PtStr);SetMapMode(hDC,MM_ANISOTROPIC);/设置映像模式设置映像模式 hPen=(HPEN)GetStockObject(BLACK_PEN);/黑色画笔黑色画笔 hBrush=(HBRUSH)GetStockObject(DKGRAY_BRUSH);/深灰深灰色刷色刷 SelectObject(hDC,hBrush);/选择画刷选择画刷消息处理函数消息处理函数消息处理函数消息处理函数43 SelectObject(hDC,hPen);/选择画笔选择画笔 RoundRect(hDC,50,120,100,200,15,15);/绘制绘制圆角矩形圆角矩形 hBrush=(HBRUSH)GetStockObject(LTGRAY_BRUSH);/亮灰亮灰色刷色刷 SelectObject(hDC,hBrush);/选择画刷选择画刷 Ellipse(hDC,150,50,200,150);/绘制绘制椭圆椭圆 hBrush=(HBRUSH)GetStockObject(HOLLOW_BRUSH);/虚虚画刷画刷 SelectObject(hDC,hBrush);/选择画刷选择画刷 Pie(hDC,250,50,300,100,250,50,300,50);/绘制绘制饼形饼形 EndPaint(hWnd,&PtStr);/结束绘图结束绘图 return 0;casecase WM_DESTROYWM_DESTROY:/结束应用程序结束应用程序 PostQuitMessagePostQuitMessage(0);return 0;(0);return 0;default:default:/其他消息处理程其他消息处理程序序 return(return(DefWindowProcDefWindowProc(hWndhWnd,iMessageiMessage,wParamwParam,lParamlParam););44BOOLBOOLBOOLBOOL InitWindows InitWindows InitWindows InitWindows(HINSTANCE(HINSTANCE(HINSTANCE(HINSTANCE hInstance hInstance hInstance hInstance,int,int,int,int nCmdShow nCmdShow nCmdShow nCmdShow)/)/)/)/初始化窗口初始化窗口初始化窗口初始化窗口 HWNDHWNDHWNDHWND hWnd hWnd hWnd hWnd;hWndhWndhWndhWnd=CreateWindowCreateWindowCreateWindowCreateWindow(WinFillWinFillWinFillWinFill,/,/,/,/生成窗口生成窗口生成窗口生成窗口 填充示例程序填充示例程序填充示例程序填充示例程序,WS_OVERLAPPEDWINDOW,WS_OVERLAPPEDWINDOW,WS_OVERLAPPEDWINDOW,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,0,0,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,hInstance hInstance hInstance hInstance,NULL);NULL);NULL);NULL);if(!if(!if(!if(!hWndhWndhWndhWnd)return FALSEreturn FALSEreturn FALSEreturn FALSE;hWndMain hWndMain hWndMain hWndMain=hWndhWndhWndhWnd;ShowWindow ShowWindow ShowWindow ShowWindow(hWndhWndhWndhWnd,nCmdShownCmdShownCmdShownCmdShow););););/显示窗口显示窗口显示窗口显示窗口 UpdateWindowUpdateWindowUpdateWindowUpdateWindow(hWndhWndhWndhWnd););););return TRUE;return TRUE;return TRUE;return TRUE;45BOOLBOOLBOOLBOOL InitWindowsClass InitWindowsClass InitWindowsClass InitWindowsClass(HINSTANCE(HINSTANCE(HINSTANCE(HINSTANCE hInstance hInstance hInstance hInstance)/定义窗口类定义窗口类定义窗口类定义窗口类 WNDCLASS WNDCLASS WNDCLASS WNDCLASS WndClassWndClassWndClassWndClass;WndClassWndClassWndClassWndClass.cbClsExtracbClsExtracbClsExtracbClsExtra=0;=0;=0;=0;WndClassWndClassWndClassWndClass.cbWndExtracbWndExtracbWndExtracbWndExtra=0;=0;=0;=0;WndClass WndClass WndClass WndClass.hbrBackgroundhbrBackgroundhbrBackgroundhbrBackground=(HBRUSH)(=(HBRUSH)(=(HBRUSH)(=(HBRUSH)(GetStockObjectGetStockObjectGetStockObjectGetStockObject(WHITE_BRUSH);(WHITE_BRUSH);(WHITE_BRUSH);(WHITE_BRUSH);WndClassWndClassWndClassWndClass.hCursorhCursorhCursorhCursor=LoadCursorLoadCursorLoadCursorLoadCursor(NULL,IDC_ARROW);(NULL,IDC_ARROW);(NULL,IDC_ARROW);(NULL,IDC_ARROW);WndClassWndClassWndClassWndClass.hIconhIconhIconhIcon=LoadIconLoadIconLoadIconLoadIcon(NULL,END);(NULL,END);(NULL,END);(NULL,END);WndClassWndClassWndClassWndClass.hInstancehInstancehInstancehInstance=hInstancehInstancehInstancehInstance;WndClassWndClassWndClassWndClass.lpfnWndProclpfnWndProclpfnWndProclpfnWndProc=WndProcWndProcWndProcWndProc;WndClassWndClassWndClassWndClass.lpszClassNamelpszClassNamelpszClassNamelpszClassName=WinFillWinFillWinFillWinFill;WndClassWndClassWndClassWndClass.lpszMenuNamelpszMenuNamelpszMenuNamelpszMenuName=NULL;=NULL;=NULL;=NULL;WndClassWndClassWndClassWndClass.style=CS_HREDRAW|CS_VREDRAW;.style=CS_HREDRAW|CS_VREDRAW;.style=CS_HREDRAW|CS_VREDRAW;.style=CS_HREDRAW|CS_VREDRAW;return return return return RegisterClassRegisterClassRegisterClassRegisterClass(&(&(&(&WndClassWndClassWndClassWndClass););););46【例【例4-2】编写一个程序,在屏幕上出现一个圆心沿正弦曲编写一个程序,在屏幕上出现一个圆心沿正弦曲线轨迹移动的实心圆,而且,每隔四分之一周期,圆的填线轨迹移动的实心圆,而且,每隔四分之一周期,圆的填充色和圆的周边颜色都发生变化充色和圆的周边颜色都发生变化(颜色自己选取颜色自己选取),同时,同时,圆的半径在四分之一周期之内由正弦曲线幅值的圆的半径在四分之一周期之内由正弦曲线幅值的0.20.2倍至倍至0.60.6倍线性增长倍线性增长(1)(1)正弦曲线是此题的基础。在正弦曲线是此题的基础。在WndMainWndMain()()函数消息循环前,函数消息循环前,生成正弦曲线各点的坐标。把正弦曲线一个周期的横坐标生成正弦曲线各点的坐标。把正弦曲线一个周期的横坐标分成分成100100个等分点,存储在数组个等分点,存储在数组lpSinlpSin100100中,中,100100个点的个点的坐标计算如下:坐标计算如下:for(for(intint j=0;j100;j+)j=0;j100;j+)/生成正弦曲线的点坐标生成正弦曲线的点坐标 lpSinlpSinj.x=(long)(j*2*Pi/100*60);j.x=(long)(j*2*Pi/100*60);lpSinlpSinj.y=(long)(j.y=(long)(dfRangedfRange*sin(j*2*Pi/100);*sin(j*2*Pi/100);47(2)(2)(2)(2)动态显示圆在正弦曲线上移动动态显示圆在正弦曲线上移动动态显示圆在正弦曲线上移动动态显示圆在正弦曲线上移动数组数组lpSinlpSin100100的长度为的长度为100100设定圆在正弦曲线移动时共有设定圆在正弦曲线移动时共有100100个位置个位置数组中每一个值是圆移动时圆心的坐标数组中每一个值是圆移动时圆心的坐标每四分之一周期有每四分之一周期有2525个位置个位置i=25i=25i=25i=25处于第处于第处于第处于第1 1 1 1个个个个1/41/41/41/4周期,创建周期,创建周期,创建周期,创建红色红色红色红色画笔和画刷;画笔和画刷;画笔和画刷;画笔和画刷;25252525i50i50i50i50处于第处于第处于第处于第2 2 2 2个个个个1/41/41/41/4周期,创建周期,创建周期,创建周期,创建绿色绿色绿色绿色画笔和画刷;画笔和画刷;画笔和画刷;画笔和画刷;50505050i75i75i75i75处于第处于第处于第处于第3 3 3 3个个个个1/41/41/41/4周期,创建周期,创建周期,创建周期,创建蓝色蓝色蓝色蓝色画笔和画刷;画笔和画刷;画笔和画刷;画笔和画刷;75757575i100i100i100i100处于第处于第处于第处于第4 4 4 4个个个个1/41/41/41/4周期,创建周期,创建周期,创建周期,创建黄色黄色黄色黄色画笔和画刷;画笔和画刷;画笔和画刷;画笔和画刷;48 在消息在消息在消息在消息WM_PAINTWM_PAINTWM_PAINTWM_PAINT处理程序中,调用函数处理程序中,调用函数处理程序中,调用函数处理程序中,调用函数BeginPaintBeginPaintBeginPaintBeginPaint()()()()获得获得获得获得设备环境句柄。由此经过线性差分计算圆半径的大小设备环境句柄。由此经过线性差分计算圆半径的大小设备环境句柄。由此经过线性差分计算圆半径的大小设备环境句柄。由此经过线性差分计算圆半径的大小lRadiouslRadiouslRadiouslRadious,第第第第1 1 1 1个个个个1/41/41/41/4周期的程序代码如下:周期的程序代码如下:周期的程序代码如下:周期的程序代码如下:if(i=25)if(i=25)if(i=25)if(i=25)/第一个第一个第一个第一个1/41/41/41/4周期周期周期周期 hPenhPenhPenhPen=CreatePenCreatePenCreatePenCreatePen(PS_DASH,1,(PS_DASH,1,(PS_DASH,1,(PS_DASH,1,RGBRGBRGBRGB(255,0,0);/(255,0,0);/(255,0,0);/(255,0,0);/红笔红笔红笔红笔 hBrushhBrushhBrushhBrush=CreateHatchBrushCreateHatchBrushCreateHatchBrushCreateHatchBrush(HS_BDIAGONAL,(HS_BDIAGONAL,(HS_BDIAGONAL,(HS_BDIAGONAL,RGBRGBRGBRGB(255,0,0);/(255,0,0);/(255,0,0);/(255,0,0);/红刷红刷红刷红刷 /计算半径计算半径计算半径计算半径 lRadiouslRadiouslRadiouslRadious=(long)(=(long)(=(long)(=(long)(dfRangedfRangedfRangedfRange*0.2+i%25*0.2+i%25*0.2+i%25*0.2+i%25*dfRangedfRangedfRangedfRange*0.4/25);*0.4/25);*0.4/25);*0.4/25);.49画笔和画刷选入设备环境后,调用函数画笔和画刷选入设备环境后,调用函数Ellipse()Ellipse()绘制圆形。下面这段代码是动态显示的关键:绘制圆形。下面这段代码是动态显示的关键:Sleep(100);Sleep(100);/停停0.10.1秒秒 if(if(i100i100)InvalidateRect InvalidateRect(hWndhWnd,NULL,1);/,NULL,1);/刷新用户区刷新用户区 i100i10