Windows的发展•DOS及图形界面、鼠标的使用•单道程序•Windows3.1、Windows3.2•假多道程序、TTF、OLE•Windows95•…•Windows10、windows2016(支持docker、linux命令)•跨平台(多种设备),开源.NET,可运行于多种平台•各个版本的PE版Windows的特点•WYSIWYG(所见即所得)•标准化的界面•通用,减少学习成本•界面单一,没有现代web界面丰富•目前有和现代web融合的趋势•图形设备接口(GDI)•多道程序、抢占型•动态链接库•版本兼容性高•F6的切换功能仍然存在编程示例•控制台程序(console)编程示例•Windows程序Windows程序的组成•头文件•程序入口MessageBox简介•参数1句柄•参数2正文•参数3标题•参数4按钮的指定,常量(用|并操作)•返回值IDOK、IDCANCEL、IDABORT、IDTRY、IDIGNORE、ISYES、ISNOVisualc++6.0使用介绍•项目和工作区•项目辅助文件(因visual版本而异)•Windows和console•工程/设置/链接/工程选项:subsystem:console和subsystem:windows•Make文件Unicode简介钟世刚常用编码•莫尔斯码•BCDIC(二进制编码的十进制交换编码)、EBCDIC•代码页(950繁体中文、936简体中文)•ASCII•扩展ASCII•ISO8859-1(别名Latin-1,包含所有ASCII)•DBCS(双字节编码,是一种统称)ASCIIUnicode码•纯粹的列表,与存储无关•UTF-8•UTF-16•UTF-32•Word的alt+x可查看字节序•“大端”(BigEndian,BE)•“小端”(LittleEndian,LE)窗口与消息钟世刚•MessageBox功能有限,用CreateWindow生成全功能的窗口•窗口的“控件”(或称“子窗口控件”):标题栏、菜单栏、工具栏、滚动条、按钮(单选、复选)、列表框、文本框等•消息(操作系统和用户程序的分工合作)•窗口结构(“窗口类”)•面向对象VS操作系统中的结构•多个窗口可用同一个窗口类•窗口过程几个知识点•客户区域•无效:窗口首次创建、窗口大小变化、窗口重叠•重绘•UpdateWindow会发一条消息WM_PAINT•队列消息和非队列消息•Send(一般是调用特定windows函数)和Post(同步和异步)几个知识点•窗口过程•Hwnd•Message•wParam•lParam•GetMessage函数从消息队列获得一个消息并将它复制到MSG结构。•遇到WM_QUIT消息,返回0然后结束循环•其它返回非0值•DispatchMessage函数分发消息到MSG结构中的窗口句柄关联的窗口过程。•工程/设置/链接•工程选项:subsystem:console和subsystem:windows•对象/库模块:winmm.lib,且hellowin.wav位于当前目录(演示:用快捷方式的当前位置)几个知识点程序分为程序代码和UI资源两大部分。资源的实际内容是二进制代码,借助各种工具产生。://怎样拒绝退出?文本输出钟世刚•客户区域的大小和用户的操作有关•字符尺寸会影响图形尺寸•很多绘图函数和设备无关•重绘工作由程序自己负责几个知识点•以下情况会产生WM_PAINT消息,由程序来处理重绘工作:•用户移动窗口•用户调整窗口大小•程序调用ScrollWindow或ScrollDC函数(水平和垂直滚动一个位矩形)•程序调用InvalidateRect或InvalidateRgn函数(会产生WM_PAINT消息)•以下情况,Windows会处理重绘工作:•鼠标指针在客户区域内移动•在客户区内拖动图标•“调用”重绘:想办法生成WM_PAINT消息WM_PAINT消息•需要重绘的部分•自动产生WM_PAINT消息•无效矩形:覆盖无效区域的最小矩形•InvalidateRect函数会强制一矩形失效•获得无效区域的坐标•窗口过程收到WM_PAINT消息时•任何时候可调用GetUpateRect•不会连续产生WM_PAINT消息无效区域•调用BeginPaint函数,客户区域变成有效•调用ValidateRect函数,使指定区域有效•若不再存在无效区域,则删除消息队列中的WM_PAINT消息有效区域•输出文本也是用GDI函数•常用:TextOut(hdc,x,y,psText,iLength)•Hdc:设置环境句柄•X,y:坐标,单位是像素•psText:字符串指针•iLength:字符数•Hdc是GDI函数都需要的GDI•在同一条消息的处理中完成句柄的获取和释放(CreateDC除外)•设备环境句柄获取方式一•BeginPaint获取句柄,并填充绘制信息结构,自动使客户区域有效,裁剪区域是原无效区域•EndPaint释放句柄•可在调用BeginPaint之前调用InvalidateRect(hwnd,NULL,TRUE)以扩大裁剪区域至整个客户区,最后的参数TRUE表示需要擦除背景•设备环境句柄获取方式二•GetDC,获取句柄,裁剪区域是整个客户区,不进行区域有效化•ReleaseDC,释放句柄•validateRect(hwnd,NULL),使整个客户区有效化•避免死循环:若不自己处理重绘,则要调用DefWindowProc设备环境•返回的设备环境句柄是整个窗口•可对标题栏(在窗口客户区之外)等进行处理•消息是WM_NCPAINTGetWindowDC•用GetSystemMetrics获取用户界面尺寸•用GetTextMetrics获取字体尺寸TEXTMETRICtm;hdc=GetDC(hwnd);GetTextMetrics(hdc,&tm);ReleaseDC(hwnd,hdc);用户尺寸和字符大小•高度文本尺寸的度量•宽度•tmAveCharWidth小写字符的加权平均宽度•tmMaxCharWidth最宽的字符宽度•大写字符的平均宽度的估计:1.5*tmAveCharWidth文本尺寸的度量•不同消息处理代码之间共享的变量,只能是global或static•典型代码文本的格式化滚动条•CreateWindow的参数指定WS_VSCROLL以产生滚动条•处理消息WM_CREATE时计算字符的宽和高•处理消息WM_VSCROLL时•计算位置数据•用SetScrollPos重新绘制滚动条•用InvalidateRect产生WM_PAINT消息•处理消息WM_PAINT时注意考虑当前滚动条的值•或用SCROLLINFO,完美地处理滚动条功能垂直滚动条编程第5章绘图基础钟世刚本章内容5.1GDI的结构5.2设备环境5.3点和线的绘制5.4绘制填充区域5.5GDI映射模式5.6矩形、区域和剪裁5.1GDI的结构5.1GDI的结构•GDI(GraphicsDeviceInterface)•设备分为:光栅设备(点阵设备)和矢量设备•在显示器和打印机之上的抽象•也可以使用底层的特定函数•对设备颜色能力也进行了抽象5.1GDI的结构5.1GDI的结构•GDI函数分类•获取和释放设备环境•获取设备环境信息•绘图函数•设置和获取设备环境属性•与GDI对象相关的函数,不需要设备环境,但要手工销毁5.1GDI的结构•GDI的基本图形•线条和曲线•可被填充的封闭区域•位图,可分为设备相关和设备无关•文本5.1GDI的结构•杂项•映射模式和转换•缺省为像素方式•可用其它度量标准•世界坐标•图元文件(metafile)•区域•路径•剪裁•调色板•打印5.2设备环境•上下文(context)5.2设备环境获取设备环境句柄在处理WM_PAINT时:处理非WM_PAINT时:5.2设备环境•获取设备环境信息•GetDeviceCaps(hdc,iIndex)•GetSystemMetrics也可获得屏幕信息•SetTextAlign(hdc,TA_RIGHT|TA_TOP)•分析DEVCAPS15.2设备环境设备的尺寸用GetDeviceCaps获取纵横比有4:3和16:9屏幕分辨率可在显示属性中修改5.2设备环境色彩真彩,24位高彩,16位256色,调色板+索引值多数GDI函数按如下方式表示颜色,用宏RGB构建5.2设备环境•保存设备环境属性•一般对设备环境属性的修改是临时的,止于句柄的释放•长生命周期的方式•wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;•临时切换(可嵌套多层)•idSaved=SaveDC(hdc)•RestoreDC(hdc,idSaved)5.3点和线的绘制•5.3.1设定像素•GetPixel(hdc,x,y)•SetPixel(hdc,x,y,crColor)5.3点和线的绘制5.3.2直线LineTo画直线。Polyline和PolylineTo画一系列相连的直线。PolyPolyline画多组相连的线。Arc画椭圆线。PolyBezier和PolyBezierTo画贝塞尔曲线。设备环境中的5个属性影响画线:画笔当前位置、画笔、背景模式、背景颜色和绘制模式5.3点和线的绘制•5.3.2直线•Polyline(hdc,apt,n)的点坐标apt是一个数组•Polyline既不使用也不改变当前位置•PolylineTo,当前位置会设为最后一条线段的终点•分析程序SINEWAVE5.3点和线的绘制•5.3.3边框绘制函数•Rectangle、RoundRect画矩形•Ellipse画椭圆•Pie画部分椭圆,呈扇形•Chord画部分椭圆,呈弓形5.3点和线的绘制•5.3.3边框绘制函数•画矩形Rectangle(hdc,xLeft,yTop,xRight,yBottom);5.3点和线的绘制•5.3.3边框绘制函数•画椭圆Ellipse(hdc,xLeft,yTop,xRight,yBottom);(xLeft,yTop),(xRight,yBottom)构成的虚线称为椭圆的外接矩形5.3点和线的绘制•5.3.3边框绘制函数•画圆角矩形RoundRect(hdc,xLeft,yTop,xRight,yBottom,xCornerEllipse,yCornerEllipse)•如果xCornerEllipse等於xLeft与xRight的差,且yCornerEllipse等於yTop与yBottom的差,那么RoundRect函数将画出一个椭圆,这个椭园是由四个园角所组成。5.3点和线的绘制•5.3.3边框绘制函数•Arc画椭圆线,Pie画部分椭圆,呈扇形(封闭),Chord画部分椭圆,呈弓形(封闭)•参数:(hdc,xLeft,yTop,xRight,yBottom,xStart,yStart,xEnd,yEnd)5.3点和线的绘制•5.3.3边框绘制函数•分析程序LINEDEMO.C5.3点和线的绘制•5.3.4贝塞尔样条曲线•DrawBezier(hdc,apt)•PolyBezier(hdc,apt,iCount)•apt:POINT结构数组的指针,包括了样条端点和控制点的坐标,其顺序是起点的坐标、起点的控制点的坐标、终点的控制点的坐标和终点的坐标。•iCount:数组中的点的个数•分析程序BEZIER.C5.3点和线的绘制•5.3.5画笔•通常利用设备描述表中的默认画笔进行画线,也可以把预先设计好的