首页 >> 大全

5、绘图基础

2023-10-12 大全 28 作者:考证青年

设备环境 1、

《4、文本输出》中介绍了设备环境句柄的获取方法。但有时并不需要绘图,只是获取一些设备环境句柄相关的信息,可以使用。也是返回一个HDC,但是不能对其进行绘制

2、

用于获取设备环境的一些显示能力,比如:

 - HORZSIZE:以毫米为单位的物理屏幕宽度- VERTSIZE:以毫米为单位的物理屏幕高度- HORZRES:水平方向像素数- VERTRES:垂直方向像素数- LOGPIXELSX:水平方向每英寸像素数- LOGPIXELSY:垂直方向每英寸像素数

和的值并不可靠。它们并不等于实际的物理屏幕尺寸,在win10系统中测试也不满足书本中提供的公式:

书中还提到,在 NT中,和是固定的值,用来表示标准的显示器尺寸。

3、字号和字体在屏幕显示大小

字号(字体大小)是用“点值”(也称“磅”)来表示的,1磅大约是1/72英寸。通过获取到的表示垂直方向每英寸像素数,那么 / 72就是1磅的字体高度,这个值和中的 - 相等。

我们可以在系统设置中改变屏幕分辨率。如果减小屏幕分辨率, 并不会改变,只是总像素数减少了,单个像素的面积变大,所以同样的字号显示得更大。

4、色彩

在GDI函数中,使用来表示一个颜色值,是一个32位无符号整型。最高8位是0,其后每8位分别用于指定红、绿、蓝。所以实际只有24位被实际用于表示颜色。提供了几个宏用于:

#define RGB(r,g,b)          ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#define GetRValue(rgb)      (LOBYTE(rgb))
#define GetGValue(rgb)      (LOBYTE(((WORD)(rgb)) >> 8))
#define GetBValue(rgb)      (LOBYTE((rgb)>>16))

5、保存设备环境

默认情况下,设备环境句柄被释放后,对设备环境属性所做的所有改变都会丢失。如果想保存这些修改,可以:

绘制点和线 1、点

虽然一般不会直接操作像素,但GDI提供了相关函数

2、线

3、GDI对象–画笔

有6种GDI对象:画笔、画刷、位图、区域、字体和调色板。

使用GDI对象时,需要调用把GDI对象选入设备环境中,调用可以获取设备环境中当前使用的GDI对象。不再使用的GDI对象需要调用删除GDI。提供了一些预定义好的GDI对象,可以调用来获取预定义的GDI对象。

画笔决定了线条的颜色、宽度和样式。提供了3种预定义画笔:

是设备环境中的默认画笔。需要使用其他画笔时,可以调用把画笔选入设备环境中。

除了预定义画笔,还可以自定义画笔:

使用完毕后,应该删除所有创建的画笔对象。但不能在被选入设备环境时删除,也不能删除预定义的画笔对象。

调用可以从画笔对象句柄中读取画笔属性到逻辑画笔中:

GetObject(hPen, sizeof(LOGPEN), (LPVOID)&logpen);

的返回值是设备环境中上一个GDI对象,这一特性可以用于中:

SelectObject(hdc, CreatePen(PS_DASH, 0 RGB(255, 0, 0)));
DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));

或者

hPen = SelectObject(hdc, CreatePen(PS_DASH, 0 RGB(255, 0, 0)));
DelectObject(SelectObject(hdc, hPen));

4、填充间隙

绘制中,很多地方存在间隙,比如虚线间或者文本输出间的空白部分。

这些间隙是由设备环境的背景模式和背景颜色共同控制的

只有两种背景模式

绘图基础知识_绘图基础实验报告_

背景模式默认是不透明,背景颜色默认是白色。

5、绘图模式

对像素颜色执行一个按位布尔运算称为“光栅操作”(ROP),如果只涉及两种像素颜色则称为“二元光栅操作”(ROP2)。

使用画笔进行绘制时,像素最终颜色是原颜色和画笔颜色进行一个光栅操作的结果。定义了16中ROP2运算,被称为绘图模式。

填充区域 1、边框绘制

下列函数先用画笔绘制边框线,再用画刷填充区域。

BOOL WINAPI Rectangle(HDC hdc, int left, int top, int right, int bottom);

根据左上角和右下角坐标绘制矩形,实际绘制时不包含右下角像素,而是往上、左缩了一个像素。(hdc, 1, 1, 5, 4)绘制结果:

BOOL WINAPI Ellipse(HDC hdc, int left, int top, int right, int bottom);

根据左上角和右下角确定一个虚拟的矩形边框,然后在矩形边框内绘制矩形。

BOOL  WINAPI RoundRect(HDC hdc, int left, int top, int right, int bottom, int width, int height);

相比多了width和参数。圆角矩形的圆角是按照椭圆绘制的,每个圆角对应椭圆的一个象限。width和定义了椭圆对应虚拟矩形边框的宽和长,加上左上角和右下角左边可以确定4个椭圆。

BOOL  WINAPI Chord(HDC hdc,int x1, int y1, int x2, int y2, int x3,  int y3, int x4, int y4);
BOOL WINAPI Pie(HDC hdc, int left, int top, int right, int bottom, int xr1, int yr1, int xr2, int yr2);

Chord和Pie绘制的图形都是椭圆的一部分,所以前面参数和相同,先确定一个椭圆。后面4个参数在椭圆弧线上确定了起点、终点两个点。

BOOL  WINAPI Arc(HDC hdc, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);

Arc绘制的并不是一个有填充区域的封闭图形,而是椭圆上的一条弧线。

BOOL  WINAPI Polygon(HDC hdc, CONST POINT *apt, int cpt);

根据提供的坐标点绘制多边形,如果最后一个点和第一个点不同,则连接两点。

BOOL WINAPI PolyPolygon(HDC hdc, CONST POINT *apt, CONST INT *asz, int csz);

根据提供的坐标点绘制多个多边形。

和绘制的多边形可能构成多个封闭区域,如何对这些区域进行填充取决于多边形的填充模,调用可以设置设备环境的多边形填充模式:

上图是模式的一个例子,以下面POINT数组为传参:

POINT apt[5] = {0, 20, 60, 20, 10, 60, 30, 0, 50, 60};

边框线的方向依赖于POINT数组提供的坐标顺序,比如第一个点是(0,20),第二个点是(60,20),所以边框线AB的方向是从A到B。

从中间的五边形区域向左画一条射线,经过了边框线EA和CD。关键是相对于射线的方向怎么理解?我认为是垂直于射线的方向,比如图中的射线是水平的,则相对于射线的方向应该取垂直方向。那么,EA边框线在垂直方向是向上,CD边框线在垂直方向也是向上。即向下的边框线数目是0,向上的边框线数目是2,故需要填充。

2、画刷

提供了6种预定义画刷:

当然也可以创建自定义画刷。提供了5个函数来创建画刷:

HBRUSH  WINAPI CreateSolidBrush(COLORREF color);

绘图基础实验报告_绘图基础知识_

HBRUSH  WINAPI CreateHatchBrush(int iHatch, COLORREF color);
// 6种阴影线样式
#define HS_HORIZONTAL       0       /* ----- */
#define HS_VERTICAL         1       /* ||||| */
#define HS_FDIAGONAL        2       /* \\\\\ */
#define HS_BDIAGONAL        3       /* / */
#define HS_CROSS            4       /* +++++ */
#define HS_DIAGCROSS        5       /* xxxxx */

HBRUSH  WINAPI CreatePatternBrush(HBITMAP hbm);
HBRUSH  WINAPI CreateDIBPatternBrush(HGLOBAL h, UINT iUsage);

HBRUSH  WINAPI CreateBrushIndirect(CONST LOGBRUSH *plbrush);/* Logical Brush (or Pattern) */
typedef struct tagLOGBRUSH
{UINT        lbStyle;COLORREF    lbColor;ULONG_PTR   lbHatch;
} LOGBRUSH, *PLOGBRUSH, NEAR *NPLOGBRUSH, FAR *LPLOGBRUSH;

属性定义了另外两个属性的意义:

h

画刷颜色

忽略

(空画刷)

忽略

忽略

阴影线颜色

阴影线样式

忽略

位图句柄

忽略

指向DIB的指针

类似画笔,可以利用从画刷句柄中读取画刷信息到逻辑画刷中:

GetObject(hBrush, sizeof(LOGBRUSH), (LPVOID)&logbrush);

映射模式 矩形、区域和裁剪 1、处理矩形

除了,还提供了一些其它处理矩形的函数:

2、区域

区域是一种GDI对象,是对一块空间的描述,可以是任意形状。

将区域选进设备环境,是对设备环境绘图空间的一种裁剪,就会把绘图限制在区域指定的空间内,在区域外的绘图动作会被忽略。

HRGN    WINAPI CreateRectRgn(int x1, int y1, int x2, int y2);
HRGN    WINAPI CreateRectRgnIndirect(CONST RECT *lprect);

HRGN    WINAPI CreateRoundRectRgn(int x1, int y1, int x2, int y2, int w, int h);

HRGN    WINAPI CreateEllipticRgn(int x1, int y1, int x2, int y2);
HRGN    WINAPI CreateEllipticRgnIndirect(CONST RECT *lprect);

HRGN  WINAPI CreatePolygonRgn(CONST POINT *pptl, int cPoint, int iMode);
HRGN  WINAPI CreatePolyPolygonRgn(CONST POINT *pptl, CONST INT  *pc, int cPoly,int iMode);

int     WINAPI CombineRgn(HRGN hrgnDst, HRGN hrgnSrc1, HRGN hrgnSrc2, int iMode);
// iMode区域合并方式
#define RGN_AND             1				
#define RGN_OR              2			
#define RGN_XOR             3
#define RGN_DIFF            4				// hrgnSrc1不在hrgnSrc2的部分
#define RGN_COPY            5				// hrgnSrc1全部
// 返回值
#define ERROR               0				// 错误
#define NULLREGION          1				// 空区域
#define SIMPLEREGION        2				// 矩形、椭圆或多边形简单区域
#define COMPLEXREGION       3				// 矩形、椭圆或多边形组合区域

类似矩形,也提供了一些处理区域的函数

3、裁剪

除了把区域选入设备环境外,还可以调用使一个区域无效,从而在处理消息时把绘制动作限制在特定区域内。相对的,可以使一个区域有效。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了