




已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
教 案 用 纸 填充空隙问题:在使用点式画笔和虚线画笔时,点和虚线之间的空隙会怎样呢?这取决于DC的两个属性背景模式和背景颜色。默认背景模式为OPAQUE,在这种方式下,Windows使用背景色来填充空隙,默认的背景色为白色。 SetBkColor函数COLORREF SetBkColor( HDC hdc, / handle of device context COLORREF crColor / background color value); GetBkColor函数COLORREF GetBkColor( HDC hdc / handle of device context); SetBkMode函数int SetBkMode( HDC hdc, / handle of device context int iBkMode / flag specifying background mode);其中iBkMode为TRANSPARENT或者OPAQUE GetBkMode函数int GetBkMode( HDC hdc / handle to device context of interest);说明:通过SetBkColor函数可以改变填充空隙的背景色,通过SetBkMode将背景模式转换为TRANSPARENT,可以阻止Windows填充空隙。 绘图方式 光栅运算像素间的按位布尔运算叫做“光栅运算”,简记为“ROP”。由于绘图只涉及两种像素(画笔和目标),因此又称为“ROP2”运算。即当Windows使用画笔来画线时,它实际上执行画笔像素与目标位置处原来像素之间的某种按位布尔运算。 绘图模式种类绘图模式 布尔操作R2_BLACK 0R2_NOTMERGEPEN (P|D)R2_MASKNOTPEN P&DR2_NOTCOPYPEN PR2_MASKPENNOT P&DR2_NOT DR2_XORPEN PDR2_NOTMASKPEN (P&D)R2_MASKPEN P&DR2_NOTXORPEN (PD)R2_NOP DR2_MERGENOTPEN P|DR2_COPYPEN(默认) PR2_MERGEPENNOT P|DR2_MERGEPEN P|DR2_WHITE 1注意:以上模式指在单色系统中绘图的模式。 SetROP2函数int SetROP2( HDC hdc, / handle of device context int fnDrawMode / drawing mode); GetROP2函数int GetROP2( HDC hdc / handle of device context);六 绘制填充区域图形以当前设备描述表中选择的刷子来填充。 现有画刷WHITE_BRUSHLTGRAY_BRUSHGRAY_BRUSHDKGRAY_BRUSHBLACK_BRUSHNULL_BRUSH(HOLLOW_BRUSH) 选择现有画刷HBRUSH hBrush;hBrush=GetStockObject(GRAY_BRUSH);SelectObject(hdc,hBrush);用下面语句画一个没有边界框的图形。SelectObject(hdc,GetStockObject(NULL_PEN);用下面语句画一个没有填充的图形。SelectObject(hdc,GetStockObject(NULL_BRUSH); Polygon函数和多边形填充方式 Polygon函数BOOL Polygon( HDC hdc, / handle to device context CONST POINT *lpPoints, / pointer to polygons vertices int nCount / count of polygons vertices);其中nCount是点的数目,如果该数组中的最后一个点与第一个点不同,则Windows将会再加一条线,将最后一个点与第一个点连起来。(在Polyline函数中,Windows不会这么做)。 SetPolyFillMode函数int SetPolyFillMode( HDC hdc, / handle to device context int iPolyFillMode / polygon fill mode);其中,iPolyFillMode取值ALTERNATE或WINDING。说明:ALTERNATE方式,即假设从一个无穷大的封闭区域内部的点画线,只有假想的线穿过了奇数条边界线时,才填充封闭区域。WINDING方式,即假设从一个无穷大的封闭区域内部的点画线,如果假想的线穿过了奇数条边界线,区域就被填充。如果假想的线穿过了偶数条边界线,则如果一个方向的边界线数与另一个方向的边界线数不相等,就填充区域,否则不填充。例如,见上图中的物体。线上的箭头指出了画线的方向。两种方式都会填充三个封闭的L形区域,号码为13。号码为4和5的两个小内部区域,在ALTERNATE方式下不会被填充。但是,在WINDING方式下,号码为5的区域会被填充,因为从区域内必须穿过两条相同方向的线才能到达图形外部。号码为4的区域不会被填充,因为必须穿过两条方向相反的线。 ALTWIND程序关键部分LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static POINT aptFigure 10 = 10,70, 50,70, 50,10, 90,10, 90,50, 30,50, 30,90, 70,90, 70,30, 10,30 ; static int cxClient, cyClient ; HDC hdc ; int i ; PAINTSTRUCT ps ; POINT apt10 ; switch (message) case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, GetStockObject (GRAY_BRUSH) ; for (i = 0 ; i 10 ; i+) apti.x = cxClient * aptFigurei.x / 200 ; apti.y = cyClient * aptFigurei.y / 100 ; SetPolyFillMode (hdc, ALTERNATE) ; Polygon (hdc, apt, 10) ; for (i = 0 ; i 10 ; i+) apti.x += cxClient / 2 ; SetPolyFillMode (hdc, WINDING) ; Polygon (hdc, apt, 10) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; return DefWindowProc (hwnd, message, wParam, lParam) ; 创建画刷 CreateSolidBrush函数HBRUSH CreateSolidBrush( COLORREF crColor / brush color value);说明:函数中的Solid并不是指画刷为纯色。在将画刷选入DC中时,Windows创建一个抖动色的位图,并为画刷使用该位图。 CreateHatchBrush函数HBRUSH CreateHatchBrush( int fnStyle, / hatch style COLORREF clrref / color value);说明:其中,iHatchStyle参数描述影线标记的外观。取值如下: CreateBrushIndirect函数HBRUSH CreateBrushIndirect( CONST LOGBRUSH *lplb / pointer to structure describing brush);typedef struct tagLOGBRUSH / lb UINT lbStyle; COLORREF lbColor; LONG lbHatch; LOGBRUSH;lbStylelbColorlbHatchBS_SOLIDBS_HOLLOWBS_HATCHEDBS_PATTERNBS_DIBPATTERNPT画刷的色彩忽略影线的色彩忽略忽略忽略忽略影线画刷风格位图的句柄指向DIB的指针 选择、删除和获得画刷SelectObject(hd,hBrush);DeleteObject(hBrush);GetObject(hBrush,sizeof(LOGBRUSH),(LPVOID)&logbrush);七 GDI映射方式“映射方式”是一种几乎影响任何客户区绘图的设备描述表属性。另外有4种设备描述表属性窗口原点、视口原点、窗口范围和视口范围与映射方式密切相关。大多数GDI绘图函数都需要使用坐标值,这种坐标值使用的都是一种“逻辑单位”。Windows必须将逻辑单位转换为“设备单位”,即像素。这种转换是由映射方式、窗口和视口的原点,以及窗口和视口的范围所控制的。映射方式还隐含地给出了x轴和y轴的指向。 映射方式种类映射方式逻辑单位增 加 值x值y值MM_TEXTMM_LOMETRICMM_HIMETRICMM_LOENGLISHMM_HIENGLISHMM_TWIPSMM_ISOTROPICMM_ANISOTROPIC像素0.1mm0.01mm0.01in.0.001in.1/1440 in.任意(x=y)任意(x!=y)右右右右右右可选可选下上上上上上可选可选默认映射方式为MM_TEXT SetMapMode函数int SetMapMode( HDC hdc, / handle of device context int fnMapMode / new mapping mode); GetMapMode函数int GetMapMode( HDC hdc / handle of device context);注意:虽然在GDI函数中指定的坐标是32位的值,但是仅有Windows NT 能够处理全32位。在Windows 98中,坐标被限制为16位,范围从-32768到32767。 设备坐标和逻辑坐标 使用设备坐标的情况Windows对所有消息(如WM_MOVE、WM_SIZE和WM_MOUSEMOVE),对所有非GDI函数,甚至对一些GDI函数,永远使用设备坐标。GetSystemMetrics不是GDI函数,所以它总是以设备单位为量度来返回大小的。尽管GetDeviceCaps是GDI函数,但是Windows仍然对HORZRES和VERTRES以设备单位作为返回值,因为该函数的目的之一就是给程序提供以像素为单位的设备大小。 使用逻辑坐标的情况基本上大多数GDI函数使用逻辑坐标。而且GetTextMetrics调用中返回的TEXTMETRIC结构的值是使用逻辑单位的。 设备坐标系Windows将GDI函数中指定的逻辑坐标映射为设备坐标。 屏幕坐标当我们使用整个屏幕时,就根据“屏幕坐标”进行操作。屏幕的左上角为(0,0)点,屏幕坐标用在WM_MOVE消息(对于非子窗口)以及下列Windows函数中:CreateWindow和MoveWindow(都是对于非子窗口)、GetMessagePos、GetCursorPos、SetCursorPos、GetWindowRect、WindowsFromPoint等。它们或者是与窗口无关的函数,或者是必须相对于整个屏幕点来移动(或者寻找)窗口的函数。如果以DISPLAY为参数调用CreateDC,以获取整个屏幕的设备描述表,则默认情况下GDI调用中指定的逻辑坐标将被映射为屏幕坐标。 整窗口坐标“整窗口坐标”以程序的整个窗口为基准,如标题栏、菜单、滚动条和窗口框都包括在内。整窗口坐标在Windows极少使用,但是如果用GetWindowDC获取设备描述表,GDI函数中的逻辑坐标就会转换为整个窗口坐标。 客户区坐标客户区坐标是最常使用的坐标系,点(0,0)是客户区的左上角。当使用GetDc或BeginPaint获取设备表述表时,GDI函数中的逻辑坐标就会默认地转换为客户区坐标。 ClientToScreen函数BOOL ClientToScreen( HWND hWnd, / window handle for source coordinates LPPOINT lpPoint / pointer to structure containing screen coordinates); ScreenToClient函数BOOL ScreenToClient( HWND hWnd, / window handle for source coordinates LPPOINT lpPoint / address of structure containing coordinates); GetWindowRect函数BOOL GetWindowRect( HWND hWnd, / handle to window LPRECT lpRect / address of structure for window coordinates);说明:该函数用于获取屏幕坐标下的整个窗口的位置和大小。 视口和窗口 视口“视口”是基于设备坐标(像素)的。通常,视口和客户区相同,但是,如果用户已经用GetWindowDC或CreateDC获取了一个设备描述表,则视口也可以指整窗口坐标或者屏幕坐标。点(0,0)是客户区(或者整个窗口或屏幕)的左上角,x的值向右增加,y的值向下增加。 窗口“窗口”是基于逻辑坐标的,逻辑坐标可以是像素、mm、英寸,或者用户想要的任何其他单位。 转换公式 从窗口坐标转化为视口坐标:其中,(xWindow,yWindow)是待转换的逻辑点;(xViewport,yViewport)是转换后的设备坐标点,更像客户区坐标;(xWinOrg,yWinOrg)是逻辑坐标的窗口原点;(xViewOrg,yViewOrg)是设备坐标的视口原点。在默认的设备描述表中,这两个点均被设置为(0,0),但是它们可以改变。这表明,逻辑点(xWinOrg,yWinOrg)总被映射为设备点(xViewOrg,yViewOrg)。如果窗口和视口的原点是默认值(0,0),则公式简化为:在上公式中,(xWinExt,yWinExt)是逻辑坐标的窗口范围;(xViewExt,yViewExt)是设备坐标的窗口范围。在多数映射方式中,范围是映射方式所隐含的,不能够改变。每个范围自身没有什么意义,但是视口范围与窗口范围的比是逻辑单位转换为设备单位的换算因子。例如,当用户设置MM_LOENGLISH映射方式时,Windows将xViewExt设置为某个像素而将xWinExt设置为xViewExt像素占据的一英寸内有几百像素的长度。比值给出了一英寸内有几百个像素的数值。注意:范围可以为负,逻辑x轴上的不一定非得在向右时增加;逻辑y轴上的值不一定非得在向下时增加。 从视口坐标转换为窗口坐标 DPtoLP函数BOOL DPtoLP( HDC hdc, / handle to device context LPPOINT lpPoints, / pointer to array of points int nCount / count of points); LPtoDP函数BOOL LPtoDP( HDC hdc, / handle of device context LPPOINT lpPoints, / array of points int nCount / count of points);例如:GetClientRect(hwnd,&rect); DPtoLP(hdc,(PPOINT)&rect,2); 处理MM_TEXT 默认值窗口原点:(0,0) 可以改变视口原点:(0,0) 可以改变窗口范围:(1,1) 不可改变视口范围:(1,1) 不可改变 简化公式 SetViewportOrgEx函数BOOL SetViewportOrgEx( HDC hdc, / handle of device context int X, / new x-coordinate of viewport origin int Y, / new y-coordinate of viewport origin LPPOINT lpPoint / address of structure receiving original origin);说明:用于改变视口的原点。 SetWindowOrgEx函数BOOL SetWindowOrgEx( HDC hdc, / handle of device context int X, / new x-coordinate of window origin int Y, / new y-coordinate of window origin LPPOINT lpPoint / address of structure receiving original origin);说明:用于改变窗口的原点。如果将视口原点改变为(xViewOrg,yViewOrg),则逻辑点(0,0)就会映射为设备点(xViewOrg,yViewOrg)。如果将窗口原点改变为(xWinOrg,yWinOrg),则逻辑点(xWinOrg,yWinOrg)将会映射为设备点(0,0)。例如,假设客户区为cxClient个像素宽和cyClient个像素高。如果将逻辑点(0,0)定义为客户区的中心,则进行如下调用:SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);则客户区的坐标系变成如下形状:这时在客户区的左上角开始显示文本,需进行如下调用:TextOut(hdc,-cxClient/2,-cyClient/2,”HELLO”,5);用以下调用代替上述调用:(效果相同)SetWindowOrgEx(hdc,-cxClient/2,-cyClient/2,NULL)TextOut(hdc,-cxClient/2,-cyClient/2,”HELLO”,5);一般情况下,不会将这两个函数一起用,除非知道这么做的结果:SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);SetWindowOrgEx(hdc,-cxClient/2,-cyClient/2,NULL); GetViewportOrgEx函数BOOL GetViewportOrgEx( HDC hdc, / handle of device context LPPOINT lpPoint / address of structure receiving the viewport origin); GetWindowOrgEx函数BOOL GetWindowOrgEx( HDC hdc, / handle of device context LPPOINT lpPoint / address of structure receiving the window origin); “度量”映射方式Windows包含5种以物理尺寸来表示逻辑坐标的映射方式。由于x轴和y轴的逻辑坐标映射为相同的物理单位,这些映射方式能使用户画出不变形的圆和矩形。映射方式逻辑单位英寸mmMM_LOENGLISHMM_LOMETRICMM_HIENGLISHMM_TWIPSMM_HIMETRIC0.01英寸0.1mm0.001英寸1/1400英寸0.01mm0.010.003940.0010.0006940.0003940.2540.10.02540.01760.01 默认值窗口原点:(0,0) 可以改变视口原点:(0,0) 可以改变窗口范围:(?,?) 不可改变视口范围:(?,?) 不可改变对于MM_LOENGLISH,Windows计算的范围如下:例如:假设Windows 98使用96 dpi的系统字体,这样对MM_LOENGLISH来说,96除以100的比值是0.01英寸装像素数。对MM_LOMETRIC来说,96除以254的比值是0.1mm中的像素数。Windows 98下的映射方式:映射方式视口范围(x,y)窗口范围(x,y)MM_LOMETRIC MM_HIMETRICMM_LOENGLISH MM_HIENGLISH MM_TWIPS (96,96)(96,96)(96,96)(96,96)(96,96)(254,-254)(2540,-2540)(100,-100)(1000,-1000)(1440,-1440)Windows NT下的映射方式:映射方式视口范围(x,y)窗口范围(x,y)MM_LOMETRIC MM_HIMETRICMM_LOENGLISH MM_HIENGLISH MM_TWIPS (1024,-768)(1024,-768)(1024,-768)(1024,-768)(1024,-768)(3200,2400)(32000,24000)(1260,945)(12598,9449)(18142,13606) 例子例1:SetMapMode(hdc,MM_LOENGLISH);TextOut(hdc,100,-100,”Hello”,5);将把文本显示在距离客户区左边和上边各1英寸的地方。例2: SetViewportOrgEx(hdc,0,cyClient,NULL);此时的坐标系如下图所示:例3: SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);此时的坐标系如下图所示:例4:也可使用SetWindowOrgEx函数来改变(0,0)点,因为该函数的参数必须使用逻辑单位,因此需用DPtoLP函数转换为逻辑坐标。程序如下:pt.x=cxClient;pt.y=cyClient;DPtoLP(hdc,&pt,1);SetWindowOrgEx(hdc,-pt.x/2,-pt.y/2,NULL);上面的代码将逻辑(0,0)点改变到客户区的中央。 “自作主张”映射方式只有MM_ISOTROPIC和MM_ANISOTROPIC这两种映射方式可以改变视口和窗口范围,即可以改变Windows用来转换逻辑和设备坐标的换算因子。词“isotropic”的意思是“各向同性”;“anisotropic”的意思是“各向异性”。MM_ISOTROPIC使用相同的轴,x轴上的逻辑单位与y轴上的逻辑单位的物理尺寸相等。这对用户创建纵横比与显示比无关的图像是有很大帮助的。MM_ISOTROPIC与度量映射方式之间的区别是,使用MM_ISOTROPIC,用户可以控制逻辑单位的物理尺寸。Windows程序完全可以通过调整窗口的大小和视口的范围来处理图像大小的变化。因此,不管窗口尺寸怎样变化,Windows程序都可以在绘图函数中使用相同的逻辑单位。MM_TEXT和度量映射方式称为“全约束”映射方式,即用户不能改变窗口和视口的范围以及Windows将逻辑坐标换算为设备坐标的方法。MM_ISOTROPIC是一种“半约束”的映射方式,Windows允许用户改变窗口和视口范围,但只是调整它们,以便x和y逻辑单位代表同样的物理尺寸。MM_ANISOTROPIC映射方式是“无约束”的,用户可以改变窗口和视口范围,但是Windows不调整这些值。 MM_ISOTROPIC映射方式设置为MM_ISOTROPIC时,Windows使用与MM_LOMETRIC同样的窗口和视口范围。区别在于,用户可以调用SetWindowExtEx和SetViewportExtEx来根据自己的偏好改变范围了,然后,Windows将调整范围的值,以便两条轴上的逻辑单位有相同的物理距离。例如:假设用户想要一个“传统的”单象限虚拟坐标系,其中(0,0)在客户区的左下角,宽度和高度的范围都是032767,并且希望x和y轴的单位具有同样的物理尺寸。程序如下:SetMapMode(hdc,MM_ISOTROPIC);SetWindowExtEx(hdc,32767,32767,NULL);SetViewportExtEx(hdc,cxClient,-cyClient,NULL);SetViewportOrgEx(hdc,0,cyClient,NULL);注意:如果其后用GetWindowExtEx和GetViewportExtEx 函数获得了窗口和视口的范围,可以发现,它们并不是先前指定的值。Windows将根据显示设备的纵横比来调整范围,以便两条轴上的逻辑单位表示相同的物理尺寸。 MM_ANISOTROPIC:根据需要放缩图像在MM_ANISOTROPIC映射方式下,Windows不对用户所设置的值进行调整,即不需要维持正确的纵横比。例1:下面的代码将(0,0)设置为客户区的左下角,x轴和y都为032767。SetMapMode(hdc,MM_ANISOTROPIC);SetWindowExtEx(hdc,32767,32767,NULL);SetViewportExtEx(hdc,cxClient,-cyClient,NULL);SetViewportOrgEx(hdc,0,cyClient,NULL);与MM_ISOTROPIC方式下,相似的代码导致客户区的一部分在轴的范围之外。但是对于MM_ANISOTROPIC,不论其尺度多大,客户的右上角总是(32767,32767)。如果客户区不是正方形的,则逻辑x和y的单位具有不同的物理尺度。例2:SetMapMode(hdc,MM_ANISOTROPIC);SetWindowExtEx(hdc,1000,1000,NULL);SetViewportExtEx(hdc,cxClient/2,-cyClient/2,NULL);SetViewprotOrgEx(hdc,cxClient/2,cyClient/2,NULL);例3:另一种使用MM_ANISOTROPIC的方法是将x和y轴的单位固定,但其值不相等,程序如下:SetMapMode(hdc,MM_ANISOTROPIC);SetWindowExtEx(hdc,1,1,NULL);SetViewportExtEx(hdc,cxChar,cyChar,NULL);TextOut(hdc,3,2,TEXT(“Hello”),5);在距离客户区左边三个字符,上边二个字符处显示文本。例4:当用户第一次设置MM_ANISOTROPIC映射方式时,它总是继承前面所设置的映射方式的范围,这会很方便。SIZE size;SetMapMode(hdc,MM_LOENGLISH);SetMapMode(hdc,MM_ANISOTROPIC);GetViewportExtEx(hdc,&size);SetViewportExtEx(hdc,size.cx,-size.cy,NULL); WHATSIZE程序片段void Show (HWND hwnd, HDC hdc, int xText, int yText, int iMapMode, TCHAR * szMapMode) TCHAR szBuffer 60 ; RECT rect ; SaveDC (hdc) ; SetMapMode (hdc, iMapMode) ; GetClientRect (hwnd, &rect) ; DPtoLP (hdc, (PPOINT) &rect, 2) ; RestoreDC (hdc, -1) ; TextOut (hdc, xText, yText, szBuffer, wsprintf (szBuffer, TEXT (%-20s %7d %7d %7d %7d), szMapMode, rect.left, rect.right, rect.top, rect.bottom) ; LRESULT CALLBACK WndProc (HWND hwnd, U
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 细胞的生物膜系统
- 南方能源产品讲解
- 网络入侵检测技术
- 如何控制微生物污染药品
- 宪法日宣誓活动实施方案大纲
- 述职汇报用好还是用
- 手术病人护理常规
- 区域活动指导讲座实务要点
- 医院空气净化管理标准解析
- 体育锻炼心率讲解
- 2025室内设计私人定制合同全面详细版
- 与欧美网红合作合同范本
- 母猪的分娩和护理技术
- 冷库维保合同(2025版)
- 2025年北京市三力考试试题及答案
- 2025年智能家居软装搭配智能家居行业市场前景展望报告
- 2025年双鸭山宝清县融媒体中心招聘考试笔试试题(含答案)
- 2025年北京市人力资源市场薪酬数据报告(二季度)
- 广告牌安装后维护养护措施
- 山西煤矿建设管理办法
- 高职院校实训室管理办法
评论
0/150
提交评论