基本说明

EasyX 是针对 C++ 的图形库，可以帮助 C/C++ 初学者快速上手图形和游戏编程。

比如，可以基于 EasyX 图形库很快的用几何图形画一个房子，或者一辆移动的小车，可以编写俄罗斯方块、贪吃蛇、黑白棋等小游戏，可以练习图形学的各种算法，等等。

许多人学编程都是从 C 语言入门的，而现状是：

1. 有些学校以 Turbo C 为环境学习 C 语言，只是 Turbo C 实在太老了，复制粘贴都很不方便。

2. 有些学校直接拿 VC 来讲 C 语言，因为 VC 的编辑和调试环境都很优秀，并且 VC 有适合教学的免费版本。可惜在 VC 里面只能做一些文字性的练习题，想画条直线或一个圆都很难，例如需要注册窗口类、建消息循环等等，初学者会受严重打击的。初学编程想要绘图就得用 TC，很是无奈。

3. 还有计算机图形学，这门课程的重点是绘图算法，而不是 Windows 编程。所以，许多老师不得不用 TC 教学，因为 Windows 绘图太复杂了，会偏离教学的重点。新的图形学的书有不少是用的 OpenGL，可是门槛依然很高。

所以，我们想给大家一个更好的学习平台，就是 VC 方便的开发平台和 TC 简单的绘图功能，于是就有了这个 EasyX 库。如果您刚开始学 C 语言，或者您是一位教 C 语言的老师，再或者您在教计算机图形学，那么这个库一定会让您兴奋的。

EasyX 20210730
https://easyx.cn


安装

系统支持

操作系统：Windows XP(sp3) 及以上操作系统。
编译环境：Visual C++ 6.0，Visual Studio 2008 至 Visual Studio 2019 (x86 & x64)。

安装

请下载最新版 EasyX 安装程序，直接运行，并跟随提示安装即可。

安装程序会自动检测您已经安装的 VC 版本，并根据您的选择将对应的 .h 和 .lib 文件安装至 VC 的 include 和 lib 文件夹内。安装程序不会修改注册表或者您本机的其它任何文件。

卸载

由于安装程序并不修改注册表，因此您在应用程序列表中不会看到 EasyX 的卸载项。如需卸载，请再次执行对应版本的安装程序，并根据提示卸载。也可以手动将相关的 .h 和 .lib 删除，系统中不会残留任何垃圾信息。

手动安装方法

EasyX 安装程序是用 7-Zip 封装的自解压缩包程序。

手动安装时，可以直接用 7-Zip 将安装文件解压，再根据下面的文件列表说明，将解压后的相关文件分别拷贝到 VC 对应的 include 和 lib 文件夹内。

您也可以将所需的 include 和 lib 文件夹放到任意位置，然后在 VC 中增加 Lib 和 Include 的引用路径。

文件列表说明：

EasyX 安装程序
    ├ include <folder>
    │	├ easyx.h 					// 头文件(提供了当前最新版本的接口)
    │	└ graphics.h				// 头文件(在 easyx.h 的基础上，保留了若干旧接口)
    ├ lib <folder>
    │	├ VC6 <folder>
    │	│	└ x86 <folder>
    │	│		├ EasyXa.lib		// VC6 库文件(MBCS 版本)
    │	│		└ EasyXw.lib		// VC6 库文件(Unicode 版本)
    │	├ VC2008 <folder>
    │	│	├ x64 <folder>
    │	│	│	├ EasyXa.lib		// VC2008 ~ 2013 库文件(x64, MBCS 版本)
    │	│	│	└ EasyXw.lib		// VC2008 ~ 2013 库文件(x64, Unicode 版本)
    │	│	└ x86 <folder>
    │	│		├ EasyXa.lib		// VC2008 ~ 2013 库文件(x86, MBCS 版本)
    │	│		└ EasyXw.lib		// VC2008 ~ 2013 库文件(x86, Unicode 版本)
    │	└ VC2015 <folder>
    │		├ x64 <folder>
    │		│	├ EasyXa.lib		// VC2015 ~ 2019 库文件(x64, MBCS 版本)
    │		│	└ EasyXw.lib		// VC2015 ~ 2019 库文件(x64, Unicode 版本)
    │		└ x86 <folder>
    │			├ EasyXa.lib		// VC2015 ~ 2019 库文件(x86, MBCS 版本)
    │			└ EasyXw.lib		// VC2015 ~ 2019 库文件(x86, Unicode 版本)
    └ Setup.hta						// 安装程序

获取帮助文档

EasyX 的使用帮助，请参考 https://docs.easyx.cn。

可以从该网站下载离线版本的帮助文档。

项目依赖

EasyX 库采用静态链接方式，不会为您的程序增加任何额外的 DLL 依赖。


超简单的使用教程

EasyX 在使用上非常简单。

比如：启动 Visual C++，创建一个空的控制台项目（Win32 Console Application），然后添加一个新的代码文件(.cpp)，并引用 graphics.h 头文件就可以了。

看一个画圆的例子：

#include <graphics.h>		// 引用图形库头文件
#include <conio.h>
int main()
{
    initgraph(640, 480);	// 创建绘图窗口，大小为 640x480 像素
    circle(200, 200, 100);	// 画圆，圆心(200, 200)，半径 100
    _getch();				// 按任意键继续
    closegraph();			// 关闭绘图窗口
    return 0;
}

当然，EasyX 也可以在 Win32 Application 项目上使用。需要注意的是，Win32 Application 项目没有控制台，所以无法使用控制台相关的函数。


基本概念

相关内容如下：

基本概念 | 描述
颜色 | 描述颜色的各种表示方法。
坐标 | 描述坐标系。
设备 | 描述“设备”概念。


颜色

EasyX 使用 24bit 真彩色，不支持调色板模式。

表示颜色的方法

1. 用预定义常量表示颜色

常量			值			颜色
--------		--------	--------
BLACK			0			黑
BLUE			0xAA0000	蓝
GREEN			0x00AA00	绿
CYAN			0xAAAA00	青
RED				0x0000AA	红
MAGENTA			0xAA00AA	紫
BROWN			0x0055AA	棕
LIGHTGRAY		0xAAAAAA	浅灰
DARKGRAY		0x555555	深灰
LIGHTBLUE		0xFF5555	亮蓝
LIGHTGREEN		0x55FF55	亮绿
LIGHTCYAN		0xFFFF55	亮青
LIGHTRED		0x5555FF	亮红
LIGHTMAGENTA	0xFF55FF	亮紫
YELLOW			0x55FFFF	黄
WHITE			0xFFFFFF	白

2. 用 16 进制数字表示颜色

16 进制的颜色表示规则为：0xbbggrr (bb=蓝，gg=绿，rr=红)

3. 用 RGB 宏合成颜色

详见 RGB。

4. 用 HSLtoRGB、HSVtoRGB 转换其他色彩模型到 RGB 颜色

详见 HSLtoRGB、HSVtoRGB。

示例

以下是几种设置画线颜色的方法：

setlinecolor(0xff0000);
setlinecolor(BLUE);
setlinecolor(RGB(0, 0, 255));
setlinecolor(HSLtoRGB(240, 1, 0.5));


坐标

在 EasyX 中，坐标分两种：物理坐标和逻辑坐标。

物理坐标

物理坐标是描述设备的坐标体系。

坐标原点在设备的左上角，X 轴向右为正，Y 轴向下为正，度量单位是像素。

坐标原点、坐标轴方向、缩放比例都不能改变。

逻辑坐标

逻辑坐标是在程序中用于绘图的坐标体系。

坐标默认的原点在窗口的左上角，X 轴向右为正，Y 轴向下为正，度量单位是点。

默认情况下，逻辑坐标与物理坐标是一一对应的，一个逻辑点等于一个物理像素。

在本手册中，凡是没有注明的坐标，均指逻辑坐标。

请参阅

setorigin：修改坐标原点。

setaspectratio：修改坐标轴方向。

setaspectratio：修改缩放比例。


设备

“设备”，是指绘图表面。

在 EasyX 中，设备分两种，一种是默认的绘图窗口，另一种是 IMAGE 对象。通过 SetWorkingImage 函数可以设置当前用于绘图的设备。

设置当前用于绘图的设备后，所有的绘图函数都会绘制在该设备上。


函数说明

EasyX 函数分为以下几类：

  • 绘图设备相关函数
  • 颜色模型
  • 颜色及样式设置相关函数
  • 绘制图形相关函数
  • 文字输出相关函数
  • 图像处理相关函数
  • 消息处理相关函数
  • 其它函数
  • graphics.h 新增函数


绘图设备相关函数

相关函数如下：

函数或数据类型 | 描述
cleardevice | 清除屏幕内容。
initgraph | 初始化绘图窗口。
closegraph | 关闭图形窗口。
getaspectratio | 获取当前缩放因子。
setaspectratio | 设置当前缩放因子。
graphdefaults | 恢复绘图窗口为默认值。
setorigin | 设置坐标原点。
setcliprgn | 设置当前绘图设备的裁剪区。
clearcliprgn | 清除裁剪区的屏幕内容。


clearcliprgn

这个函数用于清空裁剪区。

void clearcliprgn();

参数

无

返回值

无

示例

无


cleardevice

这个函数使用当前背景色清空绘图设备。

void cleardevice();

参数

无

返回值

无

示例

无


closegraph

这个函数用于关闭绘图窗口。

void closegraph();

参数

无

返回值

无

示例

无


getaspectratio

这个函数用于获取当前缩放因子。

void getaspectratio(
    float *pxasp,
    float *pyasp
);

参数

pxasp

返回 x 方向上的缩放因子。

pyasp

返回 y 方向上的缩放因子。

返回值

无

示例

无


graphdefaults

这个函数用于重置视图、当前点、绘图色、背景色、线形、填充样式、字体为默认值。

void graphdefaults();

参数

无

返回值

无

示例

无


initgraph

这个函数用于初始化绘图窗口。

HWND initgraph(
    int width,
    int height,
    int flag = NULL
);

参数

width

绘图窗口的宽度。

height

绘图窗口的高度。

flag

绘图窗口的样式，默认为 NULL。可为以下值：

值 | 含义
EW_DBLCLKS | 在绘图窗口中支持鼠标双击事件。
EW_NOCLOSE | 禁用绘图窗口的关闭按钮。
EW_NOMINIMIZE | 禁用绘图窗口的最小化按钮。
EW_SHOWCONSOLE | 显示控制台窗口。

返回值

返回新建绘图窗口的句柄。

示例

以下代码片段创建一个尺寸为 640x480 的绘图窗口：

initgraph(640, 480);

以下代码片段创建一个尺寸为 640x480 的绘图窗口，同时显示控制台窗口：

initgraph(640, 480, EW_SHOWCONSOLE);

以下代码片段创建一个尺寸为 640x480 的绘图窗口，同时显示控制台窗口，并禁用关闭按钮：

initgraph(640, 480, EW_SHOWCONSOLE | EW_NOCLOSE);


setaspectratio

这个函数用于设置当前缩放因子。

void setaspectratio(
    float xasp,
    float yasp
);

参数

xasp

x 方向上的缩放因子。例如绘制宽度为 100 的矩形，实际的绘制宽度为 100 * xasp。

yasp

y 方向上的缩放因子。例如绘制高度为 100 的矩形，实际的绘制高度为 100 * yasp。

返回值

无

备注

如果缩放因子为负，可以实现坐标轴的翻转。例如，执行 setaspectratio(1, -1) 后，可使 y 轴向上为正。

示例

无


setcliprgn

这个函数用于设置当前绘图设备的裁剪区。

void setcliprgn(HRGN hrgn);

参数

hrgn

区域的句柄。创建区域所使用的坐标为物理坐标。
如果该值为 NULL，表示取消之前设置的裁剪区。

返回值

无

备注

HRGN 是 Windows 定义的表示区域的句柄。将该区域设置为裁剪区后，任何区域外的绘图都将无效（但仍然可以通过操作显示缓冲区在裁剪区外绘图）。

可以使用 Windows GDI 函数创建一个区域。例如，创建矩形区域可以使用函数：
HRGN CreateRectRgn(int left, int top, int right, int bottom);

此外，还可以使用函数 CreateEllipticRgn 创建椭圆形的区域，使用 CreatePolygonRgn 创建多边形的区域等等。还可以使用 CombineRgn 组合区域。更多关于区域的 GDI 函数，请参考 MSDN 中的 Region Functions。

注意：创建区域后，如果不再使用，请执行 DeleteObject(HRGN hrgn) 以释放该区域对应的系统资源。

示例

以下代码用于创建一个矩形裁剪区，并在该裁剪区内画圆，请观察裁剪效果：

#include <graphics.h>
#include <conio.h>

int main()
{
    // 初始化绘图窗口
    initgraph(640, 480);

    // 创建一个矩形区域
    HRGN rgn = CreateRectRgn(100, 100, 200, 200);
    // 将该矩形区域设置为裁剪区
    setcliprgn(rgn);
    // 不再使用 rgn，清理 rgn 占用的系统资源
    DeleteObject(rgn);

    // 画圆，受裁剪区影响，只显示出四段圆弧
    circle(150, 150, 55);

    // 取消之前设置的裁剪区
    setcliprgn(NULL);

    // 画圆，不再受裁剪区影响，显示出一个完整的圆
    circle(150, 150, 60);

    // 按任意键退出
    _getch();
    closegraph();
}


setorigin

这个函数用于设置坐标原点。

void setorigin(int x, int y);

x

原点的 x 坐标（使用物理坐标）。

y

原点的 y 坐标（使用物理坐标）。

返回值

无

示例

无


颜色模型

相关函数如下：

函数或数据类型 | 描述
GetBValue | 返回指定颜色中的蓝色值。
GetGValue | 返回指定颜色中的绿色值。
GetRValue | 返回指定颜色中的红色值。
HSLtoRGB | 转换 HSL 颜色为 RGB 颜色。
HSVtoRGB | 转换 HSV 颜色为 RGB 颜色。
RGB | 通过红、绿、蓝颜色分量合成颜色。
RGBtoGRAY | 转换 RGB 颜色为 灰度颜色。
RGBtoHSL | 转换 RGB 颜色为 HSL 颜色。
RGBtoHSV | 转换 RGB 颜色为 HSV 颜色。
BGR | 交换颜色中的红色和蓝色。


BGR

BGR 宏用于交换颜色中的红色和蓝色。

COLORREF BGR(COLORREF color);

参数

color

需要交换红色和蓝色的颜色。

返回值

返回交换红色和蓝色后的颜色。

备注

颜色在内存中的表示形式为：0xbbggrr (bb=蓝，gg=绿，rr=红)，但是显示缓冲区中的颜色表现形式为 0xrrggbb。注意，两者的红色和蓝色是相反的。直接操作显示缓冲区时，可以通过 BGR 宏交换颜色的红色和蓝色部分。

示例

无


GetBValue

GetBValue 宏用于返回指定颜色中的蓝色值。

BYTE GetBValue(COLORREF rgb);

参数

rgb

指定的颜色。

返回值

返回指定颜色中的蓝色值，值的范围是 0~255。

备注

GetBValue 宏在 Windows SDK 中定义。

示例

无


GetGValue

GetGValue 宏用于返回指定颜色中的绿色值。

BYTE GetGValue(COLORREF rgb);

参数

rgb

指定的颜色。

返回值

返回指定颜色中的绿色值，值的范围是 0~255。

备注

GetGValue 宏在 Windows SDK 中定义。

示例

无


GetRValue

GetRValue 宏用于返回指定颜色中的红色值。

BYTE GetRValue(COLORREF rgb);

参数

rgb

指定的颜色。

返回值

返回指定颜色中的红色值，值的范围是 0~255。

备注

GetRValue 宏在 Windows SDK 中定义。

示例

无


HSLtoRGB

该函数用于转换 HSL 颜色为 RGB 颜色。

COLORREF HSLtoRGB(
    float H,
    float S,
    float L
);

参数

H

原 HSL 颜色模型的 Hue(色相) 分量，0 <= H < 360。

S

原 HSL 颜色模型的 Saturation(饱和度) 分量，0 <= S <= 1。

L

原 HSL 颜色模型的 Lightness(亮度) 分量，0 <= L <= 1。

返回值

对应的 RGB 颜色。

备注

HSL 又称 HLS。

HSL 的颜色模型如图所示：

H 是英文 Hue 的首字母，表示色相，即组成可见光谱的单色。红色在 0 度，绿色在 120 度，蓝色在 240 度，以此方向过渡。

S 是英文 Saturation 的首字母，表示饱和度，等于 0 时为灰色。在最大饱和度 1 时，具有最纯的色光。

L 是英文 Lightness 的首字母，表示亮度，等于 0 时为黑色，等于 0.5 时是色彩最鲜明的状态，等于 1 时为白色。

示例

请参见 示例程序 中的“彩虹”。


HSVtoRGB

该函数用于转换 HSV 颜色为 RGB 颜色。

COLORREF HSVtoRGB(
    float H,
    float S,
    float V
);

参数

H

原 HSV 颜色模型的 Hue(色相) 分量，0 <= H < 360。

S

原 HSV 颜色模型的 Saturation(饱和度) 分量，0 <= S <= 1。

V

原 HSV 颜色模型的 Value(明度) 分量，0 <= V <= 1。

返回值

对应的 RGB 颜色。

备注

HSV 又称 HSB。

HSV 的颜色模型如图所示：

H 是英文 Hue 的首字母，表示色相，即组成可见光谱的单色。红色在 0 度，绿色在 120 度，蓝色在 240 度，以此方向过渡。

S 是英文 Saturation 的首字母，表示饱和度，等于 0 时为灰色。在最大饱和度 1 时，每一色相具有最纯的色光。

V 是英文 Value 的首字母，表示明度，等于 0 时为黑色，在最大明度 1 时，是色彩最鲜明的状态。

示例

HSV 颜色模型类似于 HSL，示例程序 中的“彩虹”是 HSL 模型的操作范例，可以参考。


RGB

RGB 宏用于将红、绿、蓝颜色分量合成颜色。

COLORREF RGB(
    BYTE byRed,		// 颜色的红色部分
    BYTE byGreen,	// 颜色的绿色部分
    BYTE byBlue		// 颜色的蓝色部分
);

参数

byRed

颜色的红色部分，取值范围：0~255。

byGreen

颜色的绿色部分，取值范围：0~255。

byBlue

颜色的蓝色部分，取值范围：0~255。

返回值

返回合成的颜色。

备注

可以通过 GetRValue、GetGValue、GetBValue 宏从颜色中分离出红、绿、蓝颜色分量。

RGB 宏在 Windows SDK 中定义。

示例

无


RGBtoGRAY

该函数用于返回与指定颜色对应的灰度值颜色。

COLORREF RGBtoGRAY(
    COLORREF rgb
);

参数

rgb

原 RGB 颜色。

返回值

对应的灰度颜色。

示例

无


RGBtoHSL

该函数用于转换 RGB 颜色为 HSL 颜色。

void RGBtoHSL(
    COLORREF rgb,
    float *H,
    float *S,
    float *L
);

参数

rgb

原 RGB 颜色。

H

用于返回 HSL 颜色模型的 Hue(色相) 分量，0 <= H < 360。

S

用于返回 HSL 颜色模型的 Saturation(饱和度) 分量，0 <= S <= 1。

L

用于返回 HSL 颜色模型的 Lightness(亮度) 分量，0 <= L <= 1。

返回值

无

备注

HSL 详见 HSLtoRGB。

示例

无


RGBtoHSV

该函数用于转换 RGB 颜色为 HSV 颜色。

void RGBtoHSV(
    COLORREF rgb,
    float *H,
    float *S,
    float *V
);

参数

rgb

原 RGB 颜色。

H

用于返回 HSV 颜色模型的 Hue(色相) 分量，0 <= H < 360。

S

用于返回 HSV 颜色模型的 Saturation(饱和度) 分量，0 <= S <= 1。

V

用于返回 HSV 颜色模型的 Value(明度) 分量，0 <= V <= 1。

返回值

无

备注

HSV 详见 HSVtoRGB。

示例

无


图形颜色及样式设置相关函数

相关函数如下：

函数或数据类型 | 描述
FILLSTYLE | 填充样式对象。
getbkcolor | 获取当前设备背景色。
getbkmode | 获取当前设备图案填充和文字输出时的背景模式。
getfillcolor | 获取当前设备填充颜色。
getfillstyle | 获取当前设备填充样式。
getlinecolor | 获取当前设备画线颜色。
getlinestyle | 获取当前设备画线样式。
getpolyfillmode | 获取当前设备多边形填充模式。
getrop2 | 获取当前设备二元光栅操作模式。
LINESTYLE | 画线样式对象。
setbkcolor | 设置当前设备绘图背景色。
setbkmode | 设置当前设备图案填充和文字输出时的背景模式。
setfillcolor | 设置当前设备填充颜色。
setfillstyle | 设置当前设备填充样式。
setlinecolor | 设置当前设备画线颜色。
setlinestyle | 设置当前设备画线样式。
setpolyfillmode | 设置当前设备多边形填充模式。
setrop2 | 设置当前设备二元光栅操作模式。


FILLSTYLE

填充样式对象。

class FILLSTYLE();

公有成员

int style;

填充形式，详见 setfillstyle 函数重载的 style 参数。

long hatch;

填充图案样式，详见 setfillstyle 函数重载的 hatch 参数。

IMAGE* ppattern;

填充图像，详见 setfillstyle 函数重载的 ppattern 参数。

备注

参数的详细含义及使用方法请参考 setfillstyle 函数。

示例

请参考 setfillstyle 函数中的示例。


getbkcolor

这个函数用于获取当前设备背景色。

COLORREF getbkcolor();

参数

无

返回值

返回当前设备背景色。

示例

无


getbkmode

这个函数用于获取当前设备图案填充和文字输出时的背景模式。

int getbkmode();

参数

无

返回值

如果函数执行成功，返回值表示当前设备背景混合模式，值为 OPAQUE 或 TRANSPARENT，详见 setbkmode 函数的参数。如果函数执行失败，返回值为 0。

示例

无


getfillcolor

这个函数用于获取当前设备填充颜色。

COLORREF getfillcolor();

参数

无

返回值

返回当前设备填充颜色。

示例

无

请参阅

setfillcolor，getfillstyle，setfillstyle


getfillstyle

这个函数用于获取当前设备填充样式。

void getfillstyle(
    FILLSTYLE* pstyle
);

参数

pstyle

返回当前设备填充样式。详见 setfillstyle。

返回值

无

示例

无


getlinecolor

这个函数用于获取当前设备画线颜色。

COLORREF getlinecolor();

参数

无

返回值

返回当前设备画线颜色。

示例

无

请参阅

setlinecolor，getlinestyle，setlinestyle


getlinestyle

这个函数用于获取当前设备画线样式。

void getlinestyle(
    LINESTYLE* pstyle
);

参数

pstyle

返回当前设备画线样式。详见 setlinestyle。

返回值

无

示例

无


getpolyfillmode

这个函数用于获取当前设备多边形填充模式。

int getpolyfillmode();

参数

无

返回值

如果函数执行成功，返回值表示当前设备多边形填充模式，值为 ALTERNATE 或 WINDING，详见 setpolyfillmode 函数的参数。如果函数执行失败，返回值为 0。

示例

无


getrop2

这个函数用于获取当前设备二元光栅操作模式。

int getrop2();

参数

无

返回值

返回当前设备二元光栅操作码，详见 setrop2 函数。

示例

无


LINESTYLE

画线样式对象。

class LINESTYLE();

公有成员

DWORD style;

画线样式，详见 setlinestyle 函数的 style 参数。

DWORD thickness;

线的宽度，以像素为单位。

DWORD* puserstyle;

用户自定义样式数组，详见 setlinestyle 函数的 puserstyle 参数

DWORD userstylecount;

用户自定义样式数组的元素数量。

备注

参数的详细含义及使用方法请参考 setlinestyle 函数。

示例

请参考 setlinestyle 函数中的示例。


setbkcolor

这个函数用于设置当前设备绘图背景色。

void setbkcolor(COLORREF color);

参数

color

指定要设置的背景颜色。

返回值

无

备注

在设置背景色之后，并不会改变现有背景色，而是只改变背景色的值，之后再执行绘图语句，例如 outtextxy，会使用新设置的背景色值。

如果需要修改全部背景色，可以在设置背景色后执行 cleardevice() 函数。

示例

以下示例实现在蓝色背景下绘制红色的矩形：

#include <graphics.h>
#include <conio.h>

int main()
{
    // 初始化绘图窗口
    initgraph(640, 480);

    // 设置背景色为蓝色
    setbkcolor(BLUE);
    // 用背景色清空屏幕
    cleardevice();

    // 设置绘图色为红色
    setcolor(RED);
    // 画矩形
    rectangle(100, 100, 300, 300);

    // 按任意键退出
    _getch();
    closegraph();
}


setbkmode

这个函数用于设置当前设备图案填充和文字输出时的背景模式。

void setbkmode(int mode);

参数

mode

指定图案填充和文字输出时的背景模式，可以是以下值：

值 | 描述
OPAQUE | 背景用当前背景色填充（默认）。
TRANSPARENT | 背景是透明的。

返回值

无

示例

无


setfillcolor

这个函数用于设置当前设备填充颜色。

void setfillcolor(COLORREF color);

参数

color

填充颜色。

返回值

无

示例

设置蓝色填充：

setfillcolor(BLUE);

请参阅

getfillcolor，getfillstyle，setfillstyle


setfillstyle

这个函数用于设置当前设备填充样式。

void setfillstyle(
    FILLSTYLE* pstyle
);
void setfillstyle(
    int style,
    long hatch = NULL,
    IMAGE* ppattern = NULL
);
void setfillstyle(
    BYTE* ppattern8x8
);

参数

pstyle

指向填充样式 FILLSTYLE 的指针。

style

指定填充样式。可以是以下宏或值：

宏 | 值 | 含义
BS_SOLID | 0 | 固实填充。
BS_NULL | 1 | 不填充。
BS_HATCHED | 2 | 图案填充。
BS_PATTERN | 3 | 自定义图案填充。
BS_DIBPATTERN | 5 | 自定义图像填充。

hatch

指定填充图案，仅当 style 为 BS_HATCHED 时有效。填充图案的颜色由函数 setfillcolor 设置，背景区域使用背景色还是保持透明由函数 setbkmode 设置。hatch 参数可以是以下宏或值：

宏 | 值 | 含义
HS_HORIZONTAL | 0 |
HS_VERTICAL | 1 |
HS_FDIAGONAL | 2 |
HS_BDIAGONAL | 3 |
HS_CROSS | 4 |
HS_DIAGCROSS | 5 |

ppattern

指定自定义填充图案或图像，仅当 style 为 BS_PATTERN 或 BS_DIBPATTERN 时有效。
当 style 为 BS_PATTERN 时，ppattern 指向的 IMAGE 对象表示自定义填充图案，IMAGE 中的黑色（BLACK）对应背景区域，非黑色对应图案区域。图案区域的颜色由函数 settextcolor 设置。
当 style 为 BS_DIBPATTERN 时，ppattern 指向的 IMAGE 对象表示自定义填充图像，以该图像为填充单元实施填充。

ppattern8x8

指定自定义填充图案，效果同 BS_PATTERN，该重载以 BYTE[8] 数组定义 8 x 8 区域的填充图案。数组中，每个元素表示一行的样式，BYTE 类型有 8 位，按位从高到低表示从左到右每个点的状态，由此组成 8 x 8 的填充单元，将填充单元平铺实现填充。对应的二进制位为 0 表示背景区域，为 1 表示图案区域。

返回值

无

示例

以下代码片段设置固实填充：

setfillstyle(BS_SOLID);

以下代码片段设置填充图案为斜线填充：

setfillstyle(BS_HATCHED, HS_BDIAGONAL);

以下代码片段设置自定义图像填充（由 res\\bk.jpg 指定填充图像）：

IMAGE img;
loadimage(&img, _T("res\\bk.jpg"));
setfillstyle(BS_DIBPATTERN, NULL, &img);

以下完整代码设置自定义的填充图案（小矩形填充），并使用该图案填充一个三角形：

#include <conio.h>
#include <graphics.h>

int main()
{
    // 创建绘图窗口
    initgraph(640, 480);

    // 定义填充单元
    IMAGE img(10, 8);

    // 绘制填充单元
    SetWorkingImage(&img);	// 设置绘图目标为 img 对象
    setbkcolor(BLACK);		// 黑色区域为背景色
    cleardevice();
    setfillcolor(WHITE);	// 白色区域为自定义图案
    solidrectangle(1, 1, 8, 5);
    SetWorkingImage(NULL);	// 恢复绘图目标为默认绘图窗口

    // 设置填充样式为自定义填充图案
    setfillstyle(BS_PATTERN, NULL, &img);

    // 设置自定义图案的填充颜色
    settextcolor(GREEN);

    // 绘制无边框填充三角形
    POINT pts[] = { {50, 50}, {50, 200}, {300, 50} };
    solidpolygon(pts, 3);

    // 按任意键退出
    _getch();
    closegraph();
}

以下代码片段设置自定义的填充图案（圆形图案填充）：

setfillstyle((BYTE*)"\x3e\x41\x80\x80\x80\x80\x80\x41");

以下代码片段设置自定义的填充图案（细斜线夹粗斜线图案填充）：

setfillstyle((BYTE*)"\x5a\x2d\x96\x4b\xa5\xd2\x69\xb4");


setlinecolor

这个函数用于设置当前设备画线颜色。

void setlinecolor(COLORREF color);

参数

color

将要设置的画线颜色。

返回值

无

示例

无

请参阅

getlinecolor，getlinestyle，setlinestyle


setlinestyle

这个函数用于设置当前设备画线样式。

void setlinestyle(
    const LINESTYLE* pstyle
);
void setlinestyle(
    int style,
    int thickness = 1,
    const DWORD *puserstyle = NULL,
    DWORD userstylecount = 0
);

参数

pstyle

指向画线样式 LINESTYLE 的指针。

style

画线样式（详见备注）。

thickness

线的宽度，以像素为单位。

puserstyle

用户自定义样式数组，仅当线型为 PS_USERSTYLE 时该参数有效。
数组第一个元素指定画线的长度，第二个元素指定空白的长度，第三个元素指定画线的长度，第四个元素指定空白的长度，以此类推。

userstylecount

用户自定义样式数组的元素数量。

返回值

无

备注

参数 style 指定了画线样式，该样式由直线样式、端点样式、连接样式三类组成。可以是其中一类或多类的组合。同一类型中只能指定一个样式。

直线样式可以是以下值：

值 | 含义
PS_SOLID | 线形为实线。
PS_DASH | 线形为：------------
PS_DOT | 线形为：············
PS_DASHDOT | 线形为：-·-·-·-·-·-·
PS_DASHDOTDOT | 线形为：-··-··-··-··
PS_NULL | 线形为不可见。
PS_USERSTYLE | 线形样式为用户自定义，由参数 puserstyle 和 userstylecount 指定。

宏 PS_STYLE_MASK 是直线样式的掩码，可以通过该宏从画线样式中分离出直线样式。

端点样式可以是以下值：

值 | 含义
PS_ENDCAP_ROUND | 端点为圆形。
PS_ENDCAP_SQUARE | 端点为方形。
PS_ENDCAP_FLAT | 端点为平坦。

宏 PS_ENDCAP_MASK 是端点样式的掩码，可以通过该宏从画线样式中分离出端点样式。

连接样式可以是以下值：

值 | 含义
PS_JOIN_BEVEL | 连接处为斜面。
PS_JOIN_MITER | 连接处为斜接。
PS_JOIN_ROUND | 连接处为圆弧。

宏 PS_JOIN_MASK 是连接样式的掩码，可以通过该宏从画线样式中分离出连接样式。

掩码宏表示对应样式组所占用的所有位。例如，对于一个已经混合了多种样式的 style 变量，如果希望仅将直线样式修改为点划线，可以这么做：

style = (style & ~PS_STYLE_MASK) | PS_DASHDOT;

示例

以下代码片段设置画线样式为点划线：

setlinestyle(PS_DASHDOT);

以下代码片段设置画线样式为宽度 3 像素的虚线，端点为平坦的：

setlinestyle(PS_DASH | PS_ENDCAP_FLAT, 3);

以下代码片段设置画线样式为宽度 10 像素的实线，连接处为斜面：

setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 10);

以下代码片段设置画线样式为自定义样式（画 5 个像素，跳过 2 个像素，画 3 个像素，跳过 1 个像素……），端点为平坦的：

DWORD a[4] = {5, 2, 3, 1};
setlinestyle(PS_USERSTYLE | PS_ENDCAP_FLAT, 1, a, 4);


setpolyfillmode

这个函数用于设置当前设备多边形填充模式。

void setpolyfillmode(int mode);

参数

mode

指定多边形填充模式，可以是以下值：

值 | 描述
ALTERNATE | 交替填充模式（默认值）。 在该模式中，对于每条水平扫描线，从左向右逐像素扫描，当遇到多边形的奇数条边时，开始填充；当遇到偶数条边时，停止填充。 例如五角星，五条边多次相交，采用 ALTERNATE 模式填充时，中心的五边形不被填充。
WINDING | 根据绘图方向填充的模式。 在该模式中，对于每条水平扫描线，从左向右逐像素扫描，当遇到多边形的奇数条边时，开始填充；当遇到偶数条边时，需要进一步根据穿过该扫描线的边的方向判断：如果从上向下穿越扫描线的边数和从下向上穿越扫描线的边数不同，则开始填充，边数相同，则停止填充。 例如五角星，五条边多次相交，采用 WINDING 模式填充时，中心的五边形会被填充。

返回值

无

备注

该设置影响 fillpolygon、solidpolygon、clearpolygon 三个绘制多边形函数的执行效果。

示例

请参见 solidpolygon 函数的示例。


setrop2

这个函数用于设置当前设备二元光栅操作模式。

void setrop2(int mode);

参数

mode

二元光栅操作码。该函数支持全部的 16 种二元光栅操作码，罗列如下：

值 | 描述
R2_BLACK | 绘制出的像素颜色 = 黑色
R2_COPYPEN | 绘制出的像素颜色 = 当前颜色（默认）
R2_MASKNOTPEN | 绘制出的像素颜色 = 屏幕颜色 AND (NOT 当前颜色)
R2_MASKPEN | 绘制出的像素颜色 = 屏幕颜色 AND 当前颜色
R2_MASKPENNOT | 绘制出的像素颜色 = (NOT 屏幕颜色) AND 当前颜色
R2_MERGENOTPEN | 绘制出的像素颜色 = 屏幕颜色 OR (NOT 当前颜色)
R2_MERGEPEN | 绘制出的像素颜色 = 屏幕颜色 OR 当前颜色
R2_MERGEPENNOT | 绘制出的像素颜色 = (NOT 屏幕颜色) OR 当前颜色
R2_NOP | 绘制出的像素颜色 = 屏幕颜色
R2_NOT | 绘制出的像素颜色 = NOT 屏幕颜色
R2_NOTCOPYPEN | 绘制出的像素颜色 = NOT 当前颜色
R2_NOTMASKPEN | 绘制出的像素颜色 = NOT (屏幕颜色 AND 当前颜色)
R2_NOTMERGEPEN | 绘制出的像素颜色 = NOT (屏幕颜色 OR 当前颜色)
R2_NOTXORPEN | 绘制出的像素颜色 = NOT (屏幕颜色 XOR 当前颜色)
R2_WHITE | 绘制出的像素颜色 = 白色
R2_XORPEN | 绘制出的像素颜色 = 屏幕颜色 XOR 当前颜色

注：
1. AND / OR / NOT / XOR 为布尔运算。
2. "屏幕颜色"指绘制所经过的屏幕像素点的颜色。
3. "当前颜色"是指将要绘制的颜色。

返回值

无

备注

该函数设置的二元光栅操作码仅影响线条和填充（包括 IMAGE 填充）的输出，不影响文字和 IMAGE 的输出。

示例

无


图形绘制相关函数

相关函数如下：

函数或数据类型 | 描述
arc | 画椭圆弧。
circle | 画无填充的圆。
clearcircle | 清空圆形区域。
clearellipse | 清空椭圆区域。
clearpie | 清空扇形区域。
clearpolygon | 清空多边形区域。
clearrectangle | 清空矩形区域。
clearroundrect | 清空圆角矩形区域。
ellipse | 画无填充的椭圆。
fillcircle | 画有边框的填充圆。
fillellipse | 画有边框的填充椭圆。
fillpie | 画有边框的填充扇形。
fillpolygon | 画有边框的填充多边形。
fillrectangle | 画有边框的填充矩形。
fillroundrect | 画有边框的填充圆角矩形。
floodfill | 填充区域。
getheight | 获取绘图区的高度。
getpixel | 获取点的颜色。
getwidth | 获取绘图区的宽度。
line | 画直线。
pie | 画无填充的扇形。
polybezier | 画三次方贝塞尔曲线。
polyline | 画多条连续的线。
polygon | 画无填充的多边形。
putpixel | 画点。
rectangle | 画无填充的矩形。
roundrect | 画无填充的圆角矩形。
solidcircle | 画无边框的填充圆。
solidellipse | 画无边框的填充椭圆。
solidpie | 画无边框的填充扇形。
solidpolygon | 画无边框的填充多边形。
solidrectangle | 画无边框的填充矩形。
solidroundrect | 画无边框的填充圆角矩形。


arc

这个函数用于画椭圆弧。

void arc(
    int left,
    int top,
    int right,
    int bottom,
    double stangle,
    double endangle
);

参数

left

圆弧所在椭圆的外切矩形的左上角 x 坐标。

top

圆弧所在椭圆的外切矩形的左上角 y 坐标。

right

圆弧所在椭圆的外切矩形的右下角 x 坐标。

bottom

圆弧所在椭圆的外切矩形的右下角 y 坐标。

stangle

圆弧起始角的弧度。

endangle

圆弧终止角的弧度。

返回值

无

示例

无


circle

这个函数用于画无填充的圆。

void circle(
    int x,
    int y,
    int radius
);

参数

x

圆心 x 坐标。

y

圆心 y 坐标。

radius

圆的半径。

返回值

无

备注

该函数使用当前画线样式绘制无填充的圆。

示例

无


clearcircle

这个函数用于清空圆形区域。

void clearcircle(
    int x,
    int y,
    int radius
);

参数

x

圆心 x 坐标。

y

圆心 y 坐标。

radius

圆的半径。

返回值

无

备注

该函数使用背景色清空圆形区域。

示例

无


clearellipse

这个函数用于清空椭圆区域。

void clearellipse(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

椭圆外切矩形的左上角 x 坐标。

top

椭圆外切矩形的左上角 y 坐标。

right

椭圆外切矩形的右下角 x 坐标。

bottom

椭圆外切矩形的右下角 y 坐标。

返回值

无

备注

该函数使用当前背景色清空椭圆区域。

由于屏幕像素点坐标是整数，因此用圆心和半径描述的椭圆无法处理直径为偶数的情况。而该函数的参数采用外切矩形来描述椭圆，可以解决这个问题。

当外切矩形为正方形时，可以清空圆形区域。

示例

无


clearpie

这个函数用于清空扇形区域。

void clearpie(
    int left,
    int top,
    int right,
    int bottom,
    double stangle,
    double endangle
);

参数

left

扇形所在椭圆的外切矩形的左上角 x 坐标。

top

扇形所在椭圆的外切矩形的左上角 y 坐标。

right

扇形所在椭圆的外切矩形的右下角 x 坐标。

bottom

扇形所在椭圆的外切矩形的右下角 y 坐标。

stangle

扇形的起始角的弧度。

endangle

扇形的终止角的弧度。

返回值

无

备注

该函数使用当前背景色清空扇形区域。

示例

无


clearpolygon

这个函数用于清空多边形区域。

void clearpolygon(
    const POINT *points,
    int num
);

参数

points

每个点的坐标，数组元素个数为 num。
该函数会自动连接多边形首尾。

num

多边形顶点的个数。

返回值

无

备注

该函数使用当前背景色清空多边形区域。

示例

以下代码片段清空一个三角形区域(两种方法)：

// 方法 1
POINT pts[] = { {50, 200}, {200, 200}, {200, 50} };
clearpolygon(pts, 3);
// 方法 2
int pts[] = {50, 200,  200, 200,  200, 50};
clearpolygon((POINT*)pts, 3);


clearrectangle

这个函数用于清空矩形区域。

void clearrectangle(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

矩形左部 x 坐标。

top

矩形顶部 y 坐标。

right

矩形右部 x 坐标。

bottom

矩形底部 y 坐标。

返回值

无

备注

该函数使用当前背景色清空矩形区域。

示例

无


clearroundrect

这个函数用于清空圆角矩形区域。

void clearroundrect(
    int left,
    int top,
    int right,
    int bottom,
    int ellipsewidth,
    int ellipseheight
);

参数

left

圆角矩形左部 x 坐标。

top

圆角矩形顶部 y 坐标。

right

圆角矩形右部 x 坐标。

bottom

圆角矩形底部 y 坐标。

ellipsewidth

构成圆角矩形的圆角的椭圆的宽度。

ellipseheight

构成圆角矩形的圆角的椭圆的高度。

返回值

无

备注

该函数使用当前背景色清空圆角矩形区域。

示例

无


ellipse

这个函数用于画无填充的椭圆。

void ellipse(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

椭圆外切矩形的左上角 x 坐标。

top

椭圆外切矩形的左上角 y 坐标。

right

椭圆外切矩形的右下角 x 坐标。

bottom

椭圆外切矩形的右下角 y 坐标。

返回值

无

备注

该函数使用当前画线样式绘制无填充的椭圆。

由于屏幕像素点坐标是整数，因此用圆心和半径描述的椭圆无法处理直径为偶数的情况。而该函数的参数采用外切矩形来描述椭圆，可以解决这个问题。

当外切矩形为正方形时，可以绘制圆。

示例

无


fillcircle

这个函数用于画有边框的填充圆。

void fillcircle(
    int x,
    int y,
    int radius
);

参数

x

圆心 x 坐标。

y

圆心 y 坐标。

radius

圆的半径。

返回值

无

备注

该函数使用当前线形和当前填充样式绘制有外框的填充圆。

示例

无


fillellipse

这个函数用于画有边框的填充椭圆。

void fillellipse(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

椭圆外切矩形的左上角 x 坐标。

top

椭圆外切矩形的左上角 y 坐标。

right

椭圆外切矩形的右下角 x 坐标。

bottom

椭圆外切矩形的右下角 y 坐标。

返回值

无

备注

该函数使用当前线形和当前填充样式绘制有边框的填充椭圆。

由于屏幕像素点坐标是整数，因此用圆心和半径描述的椭圆无法处理直径为偶数的情况。而该函数的参数采用外切矩形来描述椭圆，可以解决这个问题。

当外切矩形为正方形时，可以绘制填充圆。

示例

无


fillpie

这个函数用于画有边框的填充扇形。

void fillpie(
    int left,
    int top,
    int right,
    int bottom,
    double stangle,
    double endangle
);

参数

left

扇形所在椭圆的外切矩形的左上角 x 坐标。

top

扇形所在椭圆的外切矩形的左上角 y 坐标。

right

扇形所在椭圆的外切矩形的右下角 x 坐标。

bottom

扇形所在椭圆的外切矩形的右下角 y 坐标。

stangle

扇形的起始角的弧度。

endangle

扇形的终止角的弧度。

返回值

无

示例

无


fillpolygon

这个函数用于画有边框的填充多边形。

void fillpolygon(
    const POINT *points,
    int num
);

参数

points

每个点的坐标，数组元素个数为 num。
该函数会自动连接多边形首尾。

num

多边形顶点的个数。

返回值

无

备注

该函数使用当前线形和当前填充样式绘制有外框的填充多边形。

示例

以下代码片段绘制一个封闭的填充三角形(两种方法)：

// 方法 1
POINT pts[] = { {50, 200}, {200, 200}, {200, 50} };
fillpolygon(pts, 3);
// 方法 2
int pts[] = {50, 200,  200, 200,  200, 50};
fillpolygon((POINT*)pts, 3);


fillrectangle

这个函数用于画有边框的填充矩形。

void fillrectangle(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

矩形左部 x 坐标。

top

矩形顶部 y 坐标。

right

矩形右部 x 坐标。

bottom

矩形底部 y 坐标。

返回值

无

备注

该函数使用当前线形和当前填充样式绘制有外框的填充矩形。

示例

无


fillroundrect

这个函数用于画有边框的填充圆角矩形。

void fillroundrect(
    int left,
    int top,
    int right,
    int bottom,
    int ellipsewidth,
    int ellipseheight
);

参数

left

圆角矩形左部 x 坐标。

top

圆角矩形顶部 y 坐标。

right

圆角矩形右部 x 坐标。

bottom

圆角矩形底部 y 坐标。

ellipsewidth

构成圆角矩形的圆角的椭圆的宽度。

ellipseheight

构成圆角矩形的圆角的椭圆的高度。

返回值

无

备注

该函数使用当前线形和当前填充样式绘制有外框的填充矩形。

示例

无


floodfill

这个函数用于填充区域。

void floodfill(
    int x,
    int y,
    COLORREF color,
    int filltype = FLOODFILLBORDER
);

参数

x

待填充区域内任意点的 x 坐标。

y

待填充区域内任意点的 y 坐标。

color

待填充的边界或区域的颜色。具体解释取决于参数 filltype 的值。

filltype

要执行的填充操作的类型。可以是以下宏或值：

宏 | 值 | 含义
FLOODFILLBORDER | 0 | 填充动作在颜色参数 color 围成的封闭区域内填充。
FLOODFILLSURFACE | 1 | 填充动作在颜色参数 color 指定的连续颜色表面填充。

返回值

无

备注

对于 FLOODFILLBORDER 填充类型，填充动作以 (x, y) 为起点，向周围扩散，直到遇到 border 指定的颜色才会终止。指定的区域必须是封闭的。适用于填充具有固定颜色边界的区域。

对于 FLOODFILLSURFACE 填充类型，填充动作以 (x, y) 为起点，只要邻接的颜色为 color, 填充就会延伸。适用于填充具有多种颜色边界的区域。

填充的颜色通过函数 setfillcolor 设置，填充的样式通过函数 setfillstyle 设置。

示例

无


getheight

这个函数用于获取绘图区高度。

int getheight();

参数

无

返回值

返回绘图区高度。

示例

无


getpixel

这个函数用于获取点的颜色。

COLORREF getpixel(
    int x,
    int y
);

参数

x

要获取颜色的 x 坐标。

y

要获取颜色的 y 坐标。

返回值

指定点的颜色。

示例

无


getwidth

该函数用于获取绘图区宽度。

int getwidth();

参数

无

返回值

返回绘图区宽度。

示例

无


line

这个函数用于画直线。

void line(
    int x1,
    int y1,
    int x2,
    int y2
);

参数

x1

直线的起始点的 x 坐标。

y1

直线的起始点的 y 坐标。

x2

直线的终止点的 x 坐标。

y2

直线的终止点的 y 坐标。

返回值

无

示例

无


pie

这个函数用于画无填充的扇形。

void pie(
    int left,
    int top,
    int right,
    int bottom,
    double stangle,
    double endangle
);

参数

left

扇形所在椭圆的外切矩形的左上角 x 坐标。

top

扇形所在椭圆的外切矩形的左上角 y 坐标。

right

扇形所在椭圆的外切矩形的右下角 x 坐标。

bottom

扇形所在椭圆的外切矩形的右下角 y 坐标。

stangle

扇形的起始角的弧度。

endangle

扇形的终止角的弧度。

返回值

无

示例

无


polybezier

这个函数用于画三次方贝塞尔曲线。

void polybezier(
    const POINT *points,
    int num
);

参数

points

描述三次方贝塞尔曲线的坐标点。坐标依次为：起点、控制点1、控制点2、终点(起点)、控制点1、控制点2、终点(起点)、……、控制点2、终点。

num

坐标点的数量。由于描述一条三次方贝塞尔曲线需要 4 个点，后一条贝塞尔曲线的起点与前一条的终点相同，所以必须确保 (num - 1) % 3 == 0。

返回值

无

备注

每条三次方贝塞尔曲线由 4 个点构成：起点、控制点1、控制点2、终点。贝塞尔曲线从起点画向终点，形状受控制点 1 和控制点 2 影响。

下一条贝塞尔曲线的起点是前一条的终点。如果希望前后两条贝塞尔曲线的连接点平滑，请确保这三个点在同一条直线：前一条的控制点 2、前一条的终点（后一条的起点）、后一条的控制点 1。

这个图案不会被填充。

示例

以下代码绘制两条连续的贝塞尔曲线：

#include <graphics.h>
#include <conio.h>

int main()
{
    initgraph(640, 480);	// 初始化图形窗口

    //				起始点		控制点1		控制点2		终点/起点	控制点1		控制点2		终点
    POINT pts[] = {	{150, 200}, {160, 150}, {240, 150}, {250, 100}, {260, 150}, {340, 150}, {350, 200} };

    setlinecolor(DARKGRAY);
    polyline(pts, 7);		// 画灰色的辅助线

    setlinecolor(GREEN);
    polybezier(pts, 7);		// 画绿色的贝塞尔曲线

    getch();				// 按任意键退出
    closegraph();

    return 0;
}


polygon

这个函数用于画无填充的多边形。

void polygon(
    const POINT *points,
    int num
);

参数

points

每个点的坐标，数组元素个数为 num。
该函数会自动连接多边形首尾。

num

多边形顶点的个数。

返回值

无

示例

以下代码片段绘制一个三角形(两种方法)：

// 方法 1
POINT pts[] = { {50, 200}, {200, 200}, {200, 50} };
polygon(pts, 3);
// 方法 2
int pts[] = {50, 200,  200, 200,  200, 50};
polygon((POINT*)pts, 3);


polyline

这个函数用于画连续的多条线段。

void polyline(
    const POINT *points,
    int num
);

参数

points

每个点的坐标，数组元素个数为 num。

num

多条线段的顶点个数。

返回值

无

示例

以下代码片段绘制连续的两条线段(两种方法)：

// 方法 1
POINT pts[] = { {50, 200}, {200, 200}, {200, 50} };
polyline(pts, 3);
// 方法 2
int pts[] = {50, 200,  200, 200,  200, 50};
polyline((POINT*)pts, 3);


putpixel

这个函数用于画点。

void putpixel(
    int x,
    int y,
    COLORREF color
);

参数

x

点的 x 坐标。

y

点的 y 坐标。

color

点的颜色。

返回值

无

示例

无


rectangle

这个函数用于画无填充的矩形。

void rectangle(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

矩形左部 x 坐标。

top

矩形顶部 y 坐标。

right

矩形右部 x 坐标。

bottom

矩形底部 y 坐标。

返回值

无

示例

无


roundrect

这个函数用于画无填充的圆角矩形。

void roundrect(
    int left,
    int top,
    int right,
    int bottom,
    int ellipsewidth,
    int ellipseheight
);

参数

left

圆角矩形左部 x 坐标。

top

圆角矩形顶部 y 坐标。

right

圆角矩形右部 x 坐标。

bottom

圆角矩形底部 y 坐标。

ellipsewidth

构成圆角矩形的圆角的椭圆的宽度。

ellipseheight

构成圆角矩形的圆角的椭圆的高度。

返回值

无

示例

无


solidcircle

这个函数用于画无边框的填充圆。

void solidcircle(
    int x,
    int y,
    int radius
);

参数

x

圆心 x 坐标。

y

圆心 y 坐标。

radius

圆的半径。

返回值

无

备注

该函数使用当前填充样式绘制无外框的填充圆。

示例

无


solidellipse

这个函数用于画无边框的填充椭圆。

void solidellipse(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

椭圆外切矩形的左上角 x 坐标。

top

椭圆外切矩形的左上角 y 坐标。

right

椭圆外切矩形的右下角 x 坐标。

bottom

椭圆外切矩形的右下角 y 坐标。

返回值

无

备注

该函数使用当前填充样式绘制无边框的填充椭圆。

由于屏幕像素点坐标是整数，因此用圆心和半径描述的椭圆无法处理直径为偶数的情况。而该函数的参数采用外切矩形来描述椭圆，可以解决这个问题。

当外切矩形为正方形时，可以绘制填充圆。

示例

无


solidpie

这个函数用于画无边框的填充扇形。

void solidpie(
    int left,
    int top,
    int right,
    int bottom,
    double stangle,
    double endangle
);

参数

left

扇形所在椭圆的外切矩形的左上角 x 坐标。

top

扇形所在椭圆的外切矩形的左上角 y 坐标。

right

扇形所在椭圆的外切矩形的右下角 x 坐标。

bottom

扇形所在椭圆的外切矩形的右下角 y 坐标。

stangle

扇形的起始角的弧度。

endangle

扇形的终止角的弧度。

返回值

无

备注

该函数使用当前填充样式绘制无外框的填充扇形。

示例

无


solidpolygon

这个函数用于画无边框的填充多边形。

void solidpolygon(
    const POINT *points,
    int num
);

参数

points

每个点的坐标，数组元素个数为 num。
该函数会自动连接多边形首尾。

num

多边形顶点的个数。

返回值

无

备注

该函数使用当前线形和当前填充样式绘制无边框的填充多边形。

示例

以下代码片段绘制一个封闭的填充三角形(两种方法)：

// 方法 1
POINT pts[] = { {50, 200}, {200, 200}, {200, 50} };
solidpolygon(pts, 3);
// 方法 2
int pts[] = {50, 200,  200, 200,  200, 50};
solidpolygon((POINT*)pts, 3);

以下完整代码绘制一个五角星：

#include <graphics.h>
#include <conio.h>
#include <math.h>

#define PI 3.14159265359

int main()
{
    // 创建绘图窗口
    initgraph(640, 480);

    // 定义数组，保存五角星的五个顶点坐标
    POINT pts[5];

    // 计算五角星的五个顶点坐标
    double a = PI / 2;
    for (int i = 0; i < 5; i++)
    {
        pts[i].x = int(320 + cos(a) * 100);
        pts[i].y = int(240 - sin(a) * 100);
        a += PI * 4 / 5;
    }

    // 设置填充模式为 WINDING
    setpolyfillmode(WINDING);
    // 设置填充颜色为红色
    setfillcolor(RED);
    // 绘制五角星(无边框)
    solidpolygon(pts, 5);

    // 按任意键退出
    _getch();
    closegraph();
}


solidrectangle

这个函数用于画无边框的填充矩形。

void solidrectangle(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

矩形左部 x 坐标。

top

矩形顶部 y 坐标。

right

矩形右部 x 坐标。

bottom

矩形底部 y 坐标。

返回值

无

备注

该函数使用当前填充样式绘制无外框的填充矩形。

示例

无


solidroundrect

这个函数用于画无边框的填充圆角矩形。

void solidroundrect(
    int left,
    int top,
    int right,
    int bottom,
    int ellipsewidth,
    int ellipseheight
);

参数

left

圆角矩形左部 x 坐标。

top

圆角矩形顶部 y 坐标。

right

圆角矩形右部 x 坐标。

bottom

圆角矩形底部 y 坐标。

ellipsewidth

构成圆角矩形的圆角的椭圆的宽度。

ellipseheight

构成圆角矩形的圆角的椭圆的高度。

返回值

无

备注

该函数使用当前填充样式绘制无外框的填充圆角矩形。

示例

无


文字输出相关函数

相关函数和数据如下：

函数或数据类型 | 描述
gettextcolor | 获取当前字体颜色。
gettextstyle | 获取当前字体样式。
LOGFONT | 保存字体样式的结构体。
outtextxy | 在指定位置输出字符串。
drawtext | 在指定区域内以指定格式输出字符串。
settextcolor | 设置当前字体颜色。
settextstyle | 设置当前字体样式。
textheight | 获取字符串实际占用的像素高度。
textwidth | 获取字符串实际占用的像素宽度。


drawtext

这个函数用于在指定区域内以指定格式输出字符串。

int drawtext(
    LPCTSTR str,
    RECT* pRect,
    UINT uFormat
);
int drawtext(
    TCHAR c,
    RECT* pRect,
    UINT uFormat
);

参数

str

待输出的字符串。

pRect

指定的矩形区域的指针。某些 uFormat 标志会使用这个矩形区域做返回值。详见后文说明。

uFormat

指定格式化输出文字的方法。详见后文说明。

c

待输出的字符。

返回值

函数执行成功时，返回文字的高度。

如果指定了 DT_VCENTER 或 DT_BOTTOM 标志，返回值表示从 pRect->top 到输出文字的底部的偏移量。

如果函数执行失败，返回 0。

备注

默认情况下，输出字符串的背景会用当前背景色填充。使用函数 setbkmode 可以设置文字的背景部分保持透明或使用背景色填充。

以下是 uFormat 参数可以使用的设置项，用来设置文字输出时的格式：

标志 | 描述
DT_BOTTOM | 调整文字位置到矩形底部，仅当和 DT_SINGLELINE 一起使用时有效。
DT_CALCRECT | 检测矩形的宽高。如果有多行文字，drawtext 使用 pRect 指定的宽度，并且扩展矩形的底部以容纳每一行文字。如果只有一行文字，drawtext 修改 pRect 的右边以容纳最后一个文字。无论哪种情况，drawtext 都返回格式化后的文字高度，并且不输出文字。
DT_CENTER | 文字水平居中。
DT_EDITCONTROL | 以单行编辑的方式复制可见文本。具体的说，就是以字符的平均宽度为计算依据，同时用这个方式应用于编辑控制，并且这种方式不显示可见部分的最后一行。
DT_END_ELLIPSIS 对于文本显示，如果字符串的末字符不在矩形内，它会被截断并以省略号标识。 如果是一个单词而不是一个字符，其末尾超出了矩形范围，它不会被截断。
字符串不会被修改，除非指定了 DT_MODIFYSTRING 标志。
DT_EXPANDTABS | 展开 TAB 符号。 默认每个 TAB 占8个字符位置。注意，DT_WORD_ELLIPSIS、DT_PATH_ELLIPSIS 和 DT_END_ELLIPSIS 不能和 DT_EXPANDTABS 一起用。
DT_EXTERNALLEADING | 在行高里包含字体的行间距。通常情况下，行间距不被包含在正文的行高里。
DT_HIDEPREFIX Windows 2000/XP: 忽略文字中的前缀字符(&)，并且前缀字符后面的字符不会出现下划线。其他前缀字符仍会被处理。例如：
输入字符串:		"A&bc&&d"
通常输出:		"Abc&d"
DTDT_HIDEPREFIX:"Abc&d"
DT_INTERNAL | 使用系统字体计算文字的宽高等属性。
DT_LEFT | 文字左对齐。
DT_MODIFYSTRING | 修改指定字符串为显示出的正文。仅当和 DT_END_ELLIPSIS 或 DT_PATH_ELLIPSIS 标志同时使用时有效。
DT_NOCLIP | 使输出文字不受 pRect 裁剪限制。使用 DT_NOCLIP 会使 drawtext 执行稍快一些。
DT_NOFULLWIDTHCHARBREAK | Windows 2000/XP: 防止换行符插入到 DBCS (double-wide character string，即宽字符串)，换行规则相当于 SBCS 字符串。仅当和 DT_WORDBREAK 一起使用时有效。例如，汉字就是宽字符，设置该标志后，连续的汉字会像英文单词一样不被换行符中断。
DT_NOPREFIX 关闭前缀字符的处理。通常，DrawText 解释前缀转义符 & 为其后的字符加下划线，解释 && 为显示单个 &。指定 DT_NOPREFIX，这种处理被关闭。例如：
输入字符串:	"A&bc&&d"
通常输出:	"Abc&d"
DT_NOPREFIX:	"A&bc&&d"
DT_PATH_ELLIPSIS 对于显示的文字，用省略号替换字符串中间的字符以便容纳于矩形内。如果字符串包含反斜杠(\)，DT_PATH_ELLIPSIS 尽可能的保留最后一个反斜杠后面的文字。
字符串不会被修改，除非指定了DT_MODIFYSTRING标志。
DT_PREFIXONLY Windows 2000/XP:仅仅在(&)前缀字符的位置下绘制一个下划线。不绘制字符串中的任何其他字符。例如：
输入字符串:	"A&bc&&d"
通常输出:	"Abc&d"
DT_PREFIXONLY:	" _   "
DT_RIGHT | 文字右对齐。
DT_RTLREADING | 设置从右向左的阅读顺序（当文字是希伯来文或阿拉伯文时）。默认的阅读顺序是从左向右。
DT_SINGLELINE | 使文字显示在一行。回车和换行符都无效。
DT_TABSTOP | 设置 TAB 制表位。uFormat 的 15–8 位指定 TAB 的字符宽度。默认 TAB 表示 8 个字符宽度。注意，DT_CALCRECT、DT_EXTERNALLEADING、DT_INTERNAL、DT_NOCLIP 和 DT_NOPREFIX 不能和 DT_TABSTOP 一起用。
DT_TOP | 文字顶部对齐。
DT_VCENTER | 文字垂直居中。仅当和 DT_SINGLELINE 一起使用时有效。
DT_WORDBREAK | 自动换行。当文字超过右边界时会自动换行(不拆开单词)。回车符同样可以换行。
DT_WORD_ELLIPSIS | 截去无法容纳的文字，并在末尾增加省略号。

示例

以下范例在屏幕中央输出字符串“Hello World”：

#include <graphics.h>
#include <conio.h>

int main()
{
    // 绘图窗口初始化
    initgraph(640, 480);

    // 在屏幕中央输出字符串
    RECT r = {0, 0, 639, 479};
    drawtext(_T("Hello World"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

    // 按任意键退出
    _getch();
    closegraph();
}


gettextcolor

这个函数用于获取当前文字颜色。

COLORREF gettextcolor();

参数

无

返回值

返回当前的文字颜色。

示例

无

请参阅

settextcolor，gettextstyle，settextstyle


gettextstyle

这个函数用于获取当前字体样式。

void gettextstyle(LOGFONT *font);

参数

font指向 LOGFONT 结构体的指针。

返回值

无

示例

请参见 settextstyle 函数的示例。


LOGFONT

这个结构体定义了字体的属性。

struct LOGFONT {
    LONG lfHeight;
    LONG lfWidth
    LONG lfEscapement;
    LONG lfOrientation;
    LONG lfWeight;
    BYTE lfItalic;
    BYTE lfUnderline;
    BYTE lfStrikeOut;
    BYTE lfCharSet;
    BYTE lfOutPrecision;
    BYTE lfClipPrecision;
    BYTE lfQuality;
    BYTE lfPitchAndFamily;
    TCHAR lfFaceName[LF_FACESIZE];
};

成员

lfHeight

指定高度（逻辑单位）。

lfWidth

指定字符的平均宽度（逻辑单位）。如果为 0，则比例自适应。

lfEscapement

字符串的书写角度，单位 0.1 度，默认为 0。

lfOrientation

每个字符的书写角度，单位 0.1 度，默认为 0。

lfWeight

字符的笔画粗细，范围 0~1000，0 表示默认粗细，使用数字或下表中定义的宏均可。

宏 | 粗细值
FW_DONTCARE | 0
FW_THIN | 100
FW_EXTRALIGHT | 200
FW_ULTRALIGHT | 200
FW_LIGHT | 300
FW_NORMAL | 400
FW_REGULAR | 400
FW_MEDIUM | 500
FW_SEMIBOLD | 600
FW_DEMIBOLD | 600
FW_BOLD | 700
FW_EXTRABOLD | 800
FW_ULTRABOLD | 800
FW_HEAVY | 900
FW_BLACK | 900

lfItalic

指定字体是否是斜体。

lfUnderline

指定字体是否有下划线。

lfStrikeOut

指定字体是否有删除线。

lfCharSet

指定字符集。可以使用以下预定义的值：

  • ANSI_CHARSET
  • BALTIC_CHARSET
  • CHINESEBIG5_CHARSET
  • DEFAULT_CHARSET （字符集基于本地操作系统。例如，系统位置是 English (United States)，字符集将设置为 ANSI_CHARSET）
  • EASTEUROPE_CHARSET
  • GB2312_CHARSET
  • GREEK_CHARSET
  • HANGUL_CHARSET
  • MAC_CHARSET
  • OEM_CHARSET （字符集依赖本地操作系统）
  • RUSSIAN_CHARSET
  • SHIFTJIS_CHARSET
  • SYMBOL_CHARSET
  • TURKISH_CHARSET

lfOutPrecision

指定文字的输出精度。输出精度定义输出与所请求的字体高度、宽度、字符方向、行距、间距和字体类型相匹配必须达到的匹配程度。可以是以下值：

值 | 含义
OUT_DEFAULT_PRECIS | 指定默认的映射行为。
OUT_DEVICE_PRECIS | 当系统包含多个名称相同的字体时，指定设备字体。
OUT_OUTLINE_PRECIS | 指定字体映射选择 TrueType 和其它的 outline-based 字体。
OUT_RASTER_PRECIS | 当系统包含多个名称相同的字体时，指定光栅字体（即点阵字体）。
OUT_STRING_PRECIS | 这个值并不能用于指定字体映射，只是指定点阵字体枚举数据。
OUT_STROKE_PRECIS | 这个值并不能用于指定字体映射，只是指定 TrueType 和其他的 outline-based 字体，以及矢量字体的枚举数据。
OUT_TT_ONLY_PRECIS | 指定字体映射只选择 TrueType 字体。如果系统中没有安装 TrueType 字体，将选择默认操作。
OUT_TT_PRECIS | 当系统包含多个名称相同的字体时，指定 TrueType 字体。

lfClipPrecision

指定文字的剪辑精度。剪辑精度定义如何剪辑字符的一部分位于剪辑区域之外的字符。可以是以下值：

值 | 含义
CLIP_DEFAULT_PRECIS | 指定默认的剪辑行为。
CLIP_STROKE_PRECIS | 这个值并不能用于指定字体映射，只是指定光栅（即点阵）、矢量或 TrueType 字体的枚举数据。
CLIP_EMBEDDED | 当使用内嵌的只读字体时，必须指定这个标志。
CLIP_LH_ANGLES | 如果指定了该值，所有字体的旋转都依赖于坐标系统的方向是逆时针或顺时针。 如果没有指定该值，设备字体始终逆时针旋转，但是其它字体的旋转依赖于坐标系统的方向。 该设置影响 lfOrientation 参数的效果。

lfQuality

指定文字的输出质量。输出质量定义图形设备界面 (GDI) 必须尝试将逻辑字体属性与实际物理字体的字体属性进行匹配的仔细程度。可以是以下值：

值 | 含义
ANTIALIASED_QUALITY | 指定输出质量是抗锯齿的（如果字体支持）。
DEFAULT_QUALITY | 指定输出质量不重要。
DRAFT_QUALITY | 草稿质量。字体的显示质量是不重要的。对于光栅字体（即点阵字体），缩放是有效的，这就意味着可以使用更多的尺寸，但是显示质量并不高。如果需要，粗体、斜体、下划线和删除线字体会被合成。
NONANTIALIASED_QUALITY | 指定输出质量不是抗锯齿的。
PROOF_QUALITY | 正稿质量。指定字体质量比匹配字体属性更重要。对于光栅字体（即点阵字体），缩放是无效的，会选用其最接近的字体大小。虽然选中 PROOF_QUALITY 时字体大小不能精确地映射，但是输出质量很高，并且不会有畸变现象。如果需要，粗体、斜体、下划线和删除线字体会被合成。

如果 ANTIALIASED_QUALITY 和 NONANTIALIASED_QUALITY 都未被选择，抗锯齿效果将依赖于控制面板中字体抗锯齿的设置。

lfPitchAndFamily

指定以常规方式描述字体的字体系列。字体系列描述大致的字体外观。字体系列用于在所需精确字体不可用时指定字体。1~2 位指定字体间距，可以是以下值：

值 | 含义
DEFAULT_PITCH | 指定默认间距。
FIXED_PITCH | 指定固定间距。
VARIABLE_PITCH | 指定可变间距。

4~7 位指定字体系列，可以是以下值：

值 | 含义
FF_DECORATIVE | 指定特殊字体。例如 Old English。
FF_DONTCARE | 指定字体系列不重要。
FF_MODERN | 指定具有或不具有衬线的等宽字体。例如，Pica、Elite 和 Courier New 都是等宽字体。
FF_ROMAN | 指定具有衬线的等比字体。例如 MS Serif。
FF_SCRIPT | 指定设计为类似手写体的字体。例如 Script 和 Cursive。
FF_SWISS | 指定不具有衬线的等比字体。例如 MS Sans Serif。

字体间距和字体系列可以用布尔运算符 OR 连接(即符号 |)。

lfFaceName

字体名称，名称不得超过 31 个字符。如果是空字符串，系统将使用第一个满足其它属性的字体。


outtextxy

这个函数用于在指定位置输出字符串。

void outtextxy(
    int x,
    int y,
    LPCTSTR str
);
void outtextxy(
    int x,
    int y,
    TCHAR c
);

参数

x

字符串输出时头字母的 x 轴的坐标值。

y

字符串输出时头字母的 y 轴的坐标值。

str

待输出的字符串的指针。

c

待输出的字符。

返回值

无

备注

该函数不会改变当前位置。

字符串常见的编码有两种：MBCS 和 Unicode。VC6 新建的项目默认为 MBCS 编码，VC2008 及高版本的 VC 默认为 Unicode 编码。LPCTSTR 可以同时适应两种编码。为了适应两种编码，请使用 TCHAR 字符串及相关函数。

默认情况下，输出字符串的背景会用当前背景色填充。使用函数 setbkmode 可以设置文字的背景部分保持透明或使用背景色填充。

示例

// 输出字符串（MBCS 字符集）
char s[] = "Hello World";
outtextxy(10, 20, s);
// 输出字符串（Unicode 字符集）
wchar_t s[] = L"Hello World";
outtextxy(10, 20, s);

// 输出字符串（项目字符集）
TCHAR s[] = _T("Hello World");
outtextxy(10, 20, s);
// 输出字符（MBCS 字符集）
char c = 'A';
outtextxy(10, 40, c);
// 输出字符（项目字符集）
TCHAR c = _T('A');
outtextxy(10, 40, c);
// 输出数值，先将数字格式化输出为字符串（MBCS 字符集）
char s[5];
sprintf(s, "%d", 1024);
outtextxy(10, 60, s);
// 输出数值 1024，先将数字格式化输出为字符串（项目字符集）
TCHAR s[5];
_stprintf(s, _T("%d"), 1024);		// 高版本 VC 推荐使用 _stprintf_s 函数
outtextxy(10, 60, s);


settextcolor

这个函数用于设置当前文字颜色。

void settextcolor(COLORREF color);

参数

color

要设置的文字颜色。

返回值

无

示例

无

请参阅

gettextcolor，gettextstyle，settextstyle


settextstyle

这个函数用于设置当前字体样式。

void settextstyle(
    int nHeight,
    int nWidth,
    LPCTSTR lpszFace
);
void settextstyle(
    int nHeight,
    int nWidth,
    LPCTSTR lpszFace,
    int nEscapement,
    int nOrientation,
    int nWeight,
    bool bItalic,
    bool bUnderline,
    bool bStrikeOut
);
void settextstyle(
    int nHeight,
    int nWidth,
    LPCTSTR lpszFace,
    int nEscapement,
    int nOrientation,
    int nWeight,
    bool bItalic,
    bool bUnderline,
    bool bStrikeOut,
    BYTE fbCharSet,
    BYTE fbOutPrecision,
    BYTE fbClipPrecision,
    BYTE fbQuality,
    BYTE fbPitchAndFamily
);
void settextstyle(const LOGFONT *font);

参数

nHeight

指定高度（逻辑单位）。

nWidth

字符的平均宽度（逻辑单位）。如果为 0，则比例自适应。

lpszFace

字体名称。

nEscapement

字符串的书写角度，单位 0.1 度。

nOrientation

每个字符的书写角度，单位 0.1 度。

nWeight

字符的笔画粗细，范围 0~1000。0 表示默认粗细。详见 LOGFONT 结构体。

bItalic

是否斜体。

bUnderline

是否有下划线。

bStrikeOut

是否有删除线。

fbCharSet

指定字符集。详见 LOGFONT 结构体。

fbOutPrecision

指定文字的输出精度。详见 LOGFONT 结构体。

fbClipPrecision

指定文字的剪辑精度。详见 LOGFONT 结构体。

fbQuality

指定文字的输出质量。详见 LOGFONT 结构体。

fbPitchAndFamily

指定以常规方式描述字体的字体系列。详见 LOGFONT 结构体。

font

指向 LOGFONT 结构体的指针。

返回值

无

示例

// 设置当前字体为高 16 像素的“Consolas”。(VC6 / VC2008 / VC2010 / VC2012)
settextstyle(16, 0, _T("Consolas"));
outtextxy(0, 0, _T("测试"));
// 设置输出效果为抗锯齿 (VC6 / VC2008 / VC2010 / VC2012)
LOGFONT f;
gettextstyle(&f);						// 获取当前字体设置
f.lfHeight = 48;						// 设置字体高度为 48
_tcscpy(f.lfFaceName, _T("黑体"));		// 设置字体为“黑体”(高版本 VC 推荐使用 _tcscpy_s 函数)
f.lfQuality = ANTIALIASED_QUALITY;		// 设置输出效果为抗锯齿
settextstyle(&f);						// 设置字体样式
outtextxy(0, 50, _T("抗锯齿效果"));


textheight

这个函数用于获取字符串实际占用的像素高度。

int textheight(LPCTSTR str);
int textheight(TCHAR c);

参数

str

指定的字符串指针。

c

指定的字符。

返回值

该字符串实际占用的像素高度。

示例

无


textwidth

这个函数用于获取字符串实际占用的像素宽度。

int textwidth(LPCTSTR str);
int textwidth(TCHAR c);

参数

str

指定的字符串指针。

c

指定的字符。

返回值

该字符串实际占用的像素宽度。

示例

无


图像处理相关函数

相关函数和数据如下：

函数或数据类型 | 描述
IMAGE | 保存图像的对象。
loadimage | 读取图片文件。
saveimage | 保存绘图内容至图片文件。
getimage | 从当前绘图设备中获取图像。
putimage | 在当前绘图设备上绘制指定图像。
GetWorkingImage | 获取指向当前绘图设备的指针。
rotateimage | 旋转 IMAGE 中的绘图内容。
SetWorkingImage | 设定当前绘图设备。
Resize | 调整指定绘图设备的尺寸。
GetImageBuffer | 获取绘图设备的显示缓冲区指针。
GetImageHDC | 获取绘图设备句柄。


getimage

这个函数用于从当前绘图设备中获取图像。

// 从当前绘图设备获取图像
void getimage(
    IMAGE* pDstImg,		// 保存图像的 IMAGE 对象指针
    int srcX,			// 要获取图像区域左上角 x 坐标
    int srcY,			// 要获取图像区域的左上角 y 坐标
    int srcWidth,		// 要获取图像区域的宽度
    int srcHeight		// 要获取图像区域的高度
);

参数

pDstImg

保存图像的 IMAGE 对象指针。

srcX

要获取图像区域的左上角 x 坐标。

srcY

要获取图像区域的左上角 y 坐标。

srcWidth

要获取图像区域的宽度。

srcHeight

要获取图像区域的高度。

返回值

无

示例

请参考 putimage 函数示例。


GetImageBuffer

这个函数用于获取绘图设备的显示缓冲区指针。

DWORD* GetImageBuffer(IMAGE* pImg = NULL);

参数

pImg

绘图设备指针。如果为 NULL，表示默认的绘图窗口。

返回值

返回绘图设备的显示缓冲区指针。

备注

获取到的显示缓冲区指针可以直接读写。

在显示缓冲区中，每个点占用 4 个字节，因此：显示缓冲区的大小 = 宽度 × 高度 × 4 (字节)。像素点在显示缓冲区中按照从左到右、从上向下的顺序依次排列。访问显示缓冲区请勿越界，否则会造成难以预料的后果。

显示缓冲区中的每个点对应 RGBTRIPLE 类型的结构体：

struct RGBTRIPLE {
    BYTE rgbtBlue;
    BYTE rgbtGreen;
    BYTE rgbtRed;
}

RGBTRIPLE 在内存中的表示形式为：0xrrggbb (bb=蓝，gg=绿，rr=红)，而常用的 COLORREF 在内存中的表示形式为：0xbbggrr。注意，两者的红色和蓝色是相反的，请用 BGR 宏交换红色和蓝色。

如果操作绘图窗口的显示缓冲区，请在操作完毕后，执行 FlushBatchDraw() 使操作生效。

示例

以下代码通过直接操作显示缓冲区绘制渐变的蓝色：

#include <graphics.h>
#include <conio.h>

int main()
{
    // 初始化绘图窗口
    initgraph(640, 480);

    // 获取指向显示缓冲区的指针
    DWORD* pMem = GetImageBuffer();

    // 直接对显示缓冲区赋值
    for(int i = 0; i < 640 * 480; i++)
        pMem[i] = BGR(RGB(0, 0, i * 256 / (640 * 480) ));

    // 使显示缓冲区生效（注：操作指向 IMAGE 的显示缓冲区不需要这条语句）
    FlushBatchDraw();

    // 按任意键退出
    _getch();
    closegraph();
}


GetImageHDC

这个函数用于获取绘图设备句柄(HDC)。

HDC GetImageHDC(IMAGE* pImg = NULL);

参数

pImg

绘图设备指针。如果为 NULL，表示默认的绘图窗口。

返回值

返回绘图设备句柄(HDC)。

备注

获取到的 HDC 句柄可以用在 Windows GDI 函数中。

每个 IMAGE 对象都有一个 HDC 句柄，可以通过 HDC 句柄实现对该 IMAGE 的 GDI 函数操作。在同一个 IMAGE 设备中，请勿混用 EasyX 绘图函数和 GDI 绘图函数。

示例

#include <graphics.h>
#include <conio.h>

int main()
{
    // 初始化绘图窗口
    initgraph(640, 480);

    // 获取默认绘图窗口的 HDC 句柄
    HDC hdc = GetImageHDC();

    // 执行 Windows GDI 绘图函数
    MoveToEx(hdc, 10, 10, NULL);
    LineTo(hdc, 100, 100);

    // 创建大小为 200x200 的 img 对象
    IMAGE img(200, 200);

    // 获取该 img 对象的 HDC 句柄
    hdc = GetImageHDC(&img);

    // 执行 Windows GDI 绘图函数
    Ellipse(hdc, 0, 50, 199, 150);

    // 将 img 对象显示到绘图窗口上面
    putimage(100, 0, &img);

    // 按任意键退出
    _getch();
    closegraph();
}


GetWorkingImage

这个函数用于获取当前的绘图设备。

IMAGE* GetWorkingImage();

参数

无

返回值

返回指向当前绘图设备的指针。如果返回值为 NULL，表示当前绘图设备为绘图窗口。

示例

无


IMAGE

图像对象。

class IMAGE(int width = 0, int height = 0);

公有成员

int getwidth();

返回 IMAGE 对象的宽度，以像素为单位。

int getheight();

返回 IMAGE 对象的高度，以像素为单位。

operator =

实现 IMAGE 对象的直接赋值。该操作仅拷贝源图像的内容，不拷贝源图像的绘图窗口。

示例

以下代码片段创建 img1、img2 两个对象，之后加载图片 test.jpg 到 img1，并通过赋值操作将 img1 的内容拷贝到 img2：

IMAGE img1, img2;
loadimage(&img1, _T("test.jpg"));
img2 = img1;

以下代码片段创建 img 对象，之后加载图片 test.jpg，并将图片的宽高赋值给变量 w、h：

IMAGE img;
loadimage(&img, _T("test.jpg"));
int w, h;
w = img.getwidth();
h = img.getheight();

更多示例请参考 putimage 函数示例。


loadimage

这个函数用于从文件中读取图像。

// 从图片文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
    IMAGE* pDstImg,			// 保存图像的 IMAGE 对象指针
    LPCTSTR pImgFile,		// 图片文件名
    int nWidth = 0,			// 图片的拉伸宽度
    int nHeight = 0,		// 图片的拉伸高度
    bool bResize = false	// 是否调整 IMAGE 的大小以适应图片
);
// 从资源文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
    IMAGE* pDstImg,			// 保存图像的 IMAGE 对象指针
    LPCTSTR pResType,		// 资源类型
    LPCTSTR pResName,		// 资源名称
    int nWidth = 0,			// 图片的拉伸宽度
    int nHeight = 0,		// 图片的拉伸高度
    bool bResize = false	// 是否调整 IMAGE 的大小以适应图片
);

参数

pDstImg

保存图像的 IMAGE 对象指针。如果为 NULL，表示图片将读取至绘图窗口。

pImgFile

图片文件名。支持 bmp / gif / jpg / png / tif / emf / wmf / ico 格式的图片。gif 格式的图片仅加载第一帧；gif 与 png 均不支持透明。

nWidth

图片的拉伸宽度。加载图片后，会拉伸至该宽度。如果为 0，表示使用原图的宽度。

nHeight

图片的拉伸高度。加载图片后，会拉伸至该高度。如果为 0，表示使用原图的高度。

bResize

是否调整 IMAGE 的大小以适应图片。

pResType

图片资源类型。

pResName

图片资源名称。

返回值

无

备注

如果创建 IMAGE 对象的时候没有指定宽高，可以通过 Resize 函数设置。

对于没有设置宽高的 IMAGE 对象，执行 loadimage 会将其宽高设置为和读取的图片一样的尺寸。

示例

以下完整示例实现了加载图片“D:\test.jpg”至绘图窗口：

#include <graphics.h>
#include <conio.h>

// 主函数
int main()
{
    // 绘图窗口初始化
    initgraph(640, 480);

    // 读取图片至绘图窗口
    loadimage(NULL, _T("D:\\test.jpg"));

    // 按任意键退出
    _getch();
    closegraph();
}

以下代码片段实现了加载图片“D:\test.jpg”至绘图窗口（MBCS 及 Unicode 自适应）：

loadimage(NULL, _T("D:\\test.jpg"));

以下代码片段实现了加载“IMAGE”分类下的图像资源“Player”至 img 对象，并在屏幕的指定位置显示：

IMAGE img;
loadimage(&img, _T("IMAGE"), _T("Player"));
putimage(100, 100, &img);	// 在另一个位置再次显示背景

以下代码片段实现了加载“IMAGE”分类下的图像资源 IDR_PLAYER 至 img 对象，并在屏幕的指定位置显示：

IMAGE img;
loadimage(&img, _T("IMAGE"), MAKEINTRESOURCE(IDB_PLAYER));
putimage(100, 100, &img);	// 在另一个地方再次显示背景


putimage

这个函数的几个重载用于在当前设备上绘制指定图像。

// 绘制图像
void putimage(
    int dstX,				// 绘制位置的 x 坐标
    int dstY,				// 绘制位置的 y 坐标
    IMAGE *pSrcImg,			// 要绘制的 IMAGE 对象指针
    DWORD dwRop = SRCCOPY	// 三元光栅操作码
);
// 绘制图像(指定宽高和起始位置)
void putimage(
    int dstX,				// 绘制位置的 x 坐标
    int dstY,				// 绘制位置的 y 坐标
    int dstWidth,			// 绘制的宽度
    int dstHeight,			// 绘制的高度
    IMAGE *pSrcImg,			// 要绘制的 IMAGE 对象指针
    int srcX,				// 绘制内容在 IMAGE 对象中的左上角 x 坐标
    int srcY,				// 绘制内容在 IMAGE 对象中的左上角 y 坐标
    DWORD dwRop = SRCCOPY	// 三元光栅操作码
);

参数

详见函数原型内的注释。

备注

三元光栅操作码（即位操作模式），支持全部的 256 种三元光栅操作码，常用的几种如下：

值 | 含义
DSTINVERT | 目标图像 = NOT 目标图像
MERGECOPY | 目标图像 = 源图像 AND 当前填充颜色
MERGEPAINT | 目标图像 = 目标图像 OR (NOT 源图像)
NOTSRCCOPY | 目标图像 = NOT 源图像
NOTSRCERASE | 目标图像 = NOT (目标图像 OR 源图像)
PATCOPY | 目标图像 = 当前填充颜色
PATINVERT | 目标图像 = 目标图像 XOR 当前填充颜色
PATPAINT | 目标图像 = 目标图像 OR ((NOT 源图像) OR 当前填充颜色)
SRCAND | 目标图像 = 目标图像 AND 源图像
SRCCOPY | 目标图像 = 源图像
SRCERASE | 目标图像 = (NOT 目标图像) AND 源图像
SRCINVERT | 目标图像 = 目标图像 XOR 源图像
SRCPAINT | 目标图像 = 目标图像 OR 源图像

注：

  1. AND / OR / NOT / XOR 为布尔运算。
  2. "当前填充颜色"是指通过 setfillcolor 设置的用于当前填充的颜色。
  3. 查看全部的三元光栅操作码请参考这里：三元光栅操作码。

返回值

无

示例

以下代码片段将屏幕 (0,0) 起始的 100x100 的图像拷贝至 (200,200) 位置：

IMAGE img;
getimage(&img, 0, 0, 100, 100);
putimage(200, 200, &img);


Resize

这个函数用于调整指定绘图设备的尺寸。

void Resize(
    IMAGE* pImg,
    int width,
    int height
);

参数

pImg

指定要调整尺寸的绘图设备。如果为 NULL，则表示默认绘图窗口。

width

指定绘图设备的宽度。

height

指定绘图设备的高度。

返回值

无

备注

无

示例

无


rotateimage

这个函数用于旋转 IMAGE 中的绘图内容。

void rotateimage(
    IMAGE *dstimg,
    IMAGE *srcimg,
    double radian,
    COLORREF bkcolor = BLACK,
    bool autosize = false,
    bool highquality = true
);

参数

dstimg

指定目标 IMAGE 对象指针，用来保存旋转后的图像。

srcimg

指定原 IMAGE 对象指针。

radian

指定旋转的弧度。

bkcolor

指定旋转后产生的空白区域的颜色。默认为黑色。

autosize

指定目标 IMAGE 对象是否自动调整尺寸以完全容纳旋转后的图像。默认为 false。

highquality

指定是否采用高质量的旋转。在追求性能的场合请使用低质量旋转。默认为 true。

返回值

无

示例

以下示例加载图片 "C:\\test.jpg" 并旋转 30 度 (PI / 6)，然后显示在左上角：

#include <graphics.h>
#include <conio.h>

#define PI 3.14159265359

int main()
{
    // 绘图窗口初始化
    initgraph(640, 480);

    // 定义图像
    IMAGE img1, img2;

    // 从文件加载图像
    loadimage(&img1, _T("C:\\test.jpg"));

    // 旋转图像 30 度 (PI / 6)
    rotateimage(&img2, &img1, PI / 6);

    // 显示旋转后的图像
    putimage(0, 0, &img2);

    // 按任意键退出
    _getch();
    closegraph();
}


saveimage

这个函数用于保存绘图内容至图片文件。

void saveimage(
    LPCTSTR strFileName,
    IMAGE* pImg = NULL
);

参数

strFileName

指定文件名。文件名的扩展名表示保存的图片格式，支持 bmp / gif / jpg / png / tif 格式。已存在的文件将被覆盖。

pImg

指向 IMAGE 对象的指针。如果为 NULL，表示绘图窗口。

返回值

无

示例

以下示例保存绘图窗口的内容为 "D:\test.bmp"：

#include <graphics.h>
#include <conio.h>

int main()
{
    // 绘图窗口初始化
    initgraph(640, 480);

    // 绘制图像
    outtextxy(100, 100, _T("Hello World!"));

    // 保存绘制的图像
    saveimage(_T("D:\\test.bmp"));

    // 按任意键退出
    _getch();
    closegraph();
}


SetWorkingImage

这个函数用于设定当前的绘图设备。

void SetWorkingImage(IMAGE* pImg = NULL);

参数

pImg

绘图设备指针。如果为 NULL，表示绘图设备为默认绘图窗口。

返回值

无

备注

如果需要对某个 IMAGE 做绘图操作，可以通过该函数将其设置为当前的绘图设备，之后所有的绘图语句都会绘制在该 IMAGE 上面。将参数置为 NULL 可恢复对默认绘图窗口的绘图操作。

示例

#include <graphics.h>
#include <conio.h>

int main()
{
    // 初始化绘图窗口
    initgraph(640, 480);

    // 创建 200x200 的 img 对象
    IMAGE img(200, 200);

    // 设置绘图目标为 img 对象
    SetWorkingImage(&img);
    // 以下绘图操作都会绘制在 img 对象上面
    line(0, 100, 200, 100);
    line(100, 0, 100, 200);
    circle(100, 100, 50);

    // 设置绘图目标为绘图窗口
    SetWorkingImage();
    // 将 img 对象显示在绘图窗口中
    putimage(220, 140, &img);

    // 按任意键退出
    _getch();
    closegraph();
}


三元光栅操作

这篇文档列出了 putimage 函数支持的所有三元光栅操作码。

三元光栅操作码定义了源图像与目标图像的位合并形式，这个合并形式是以下三个操作数对应像素的布尔运算：

操作数 | 含义
D | 目标图像
P | 当前填充颜色
S | 源图像

布尔运算符包括以下几种：

操作 | 含义
a | 位的 AND 运算(双目运算)
n | 位的 NOT 运算(单目运算)
o | 位的 OR 运算(双目运算)
x | 位的 XOR 运算(双目运算)

所有的布尔操作都采用逆波兰表示法，例如，“当前填充颜色 or 源图像”可表示为：PSo。（当然 SPo 也是等价的，这里只列举出了其中一种等价格式）

三元光栅操作码是 __int32 类型，其高位字是布尔操作索引，低位字是操作码。布尔操作索引的 16 个位中，高 8 位用 0 填充，低 8 位是当前填充颜色、源图像和目标图像的布尔操作结果。例如，PSo 和 DPSoo 的操作索引如下：

P | S | D | PSo | DPSoo
0 | 0 | 0 | 0 | 0
0 | 0 | 1 | 0 | 1
0 | 1 | 0 | 1 | 1
0 | 1 | 1 | 1 | 1
1 | 0 | 0 | 1 | 1
1 | 0 | 1 | 1 | 1
1 | 1 | 0 | 1 | 1
1 | 1 | 1 | 1 | 1
操作索引: | - | - | 00FCh | 00FEh

上例中，PSo 的操作索引是 00FC (从下往上读)，DPSoo 的是 00FE。这些值定义了相应的三元光栅操作码在“三元光栅操作码”表格中的位置，PSo 在 252 (00FCh) 行，DPSoo 在 254 (00FEh) 行。常用的三元光栅操作码已经定义了常量名，程序中可以直接使用。

三元光栅操作码

布尔功能 (16 进制) | 光栅操作 (16 进制) | 布尔功能的逆波兰表示法 | 常量名
00 | 00000042 | 0 | BLACKNESS
01 | 00010289 | DPSoon |
02 | 00020C89 | DPSona |
03 | 000300AA | PSon |
04 | 00040C88 | SDPona |
05 | 000500A9 | DPon |
06 | 00060865 | PDSxnon |
07 | 000702C5 | PDSaon |
08 | 00080F08 | SDPnaa |
09 | 00090245 | PDSxon |
0A | 000A0329 | DPna |
0B | 000B0B2A | PSDnaon |
0C | 000C0324 | SPna |
0D | 000D0B25 | PDSnaon |
0E | 000E08A5 | PDSonon |
0F | 000F0001 | Pn |
10 | 00100C85 | PDSona |
11 | 001100A6 | DSon | NOTSRCERASE
12 | 00120868 | SDPxnon |
13 | 001302C8 | SDPaon |
14 | 00140869 | DPSxnon |
15 | 001502C9 | DPSaon |
16 | 00165CCA | PSDPSanaxx |
17 | 00171D54 | SSPxDSxaxn |
18 | 00180D59 | SPxPDxa |
19 | 00191CC8 | SDPSanaxn |
1A | 001A06C5 | PDSPaox |
1B | 001B0768 | SDPSxaxn |
1C | 001C06CA | PSDPaox |
1D | 001D0766 | DSPDxaxn |
1E | 001E01A5 | PDSox |
1F | 001F0385 | PDSoan |
20 | 00200F09 | DPSnaa |
21 | 00210248 | SDPxon |
22 | 00220326 | DSna |
23 | 00230B24 | SPDnaon |
24 | 00240D55 | SPxDSxa |
25 | 00251CC5 | PDSPanaxn |
26 | 002606C8 | SDPSaox |
27 | 00271868 | SDPSxnox |
28 | 00280369 | DPSxa |
29 | 002916CA | PSDPSaoxxn |
2A | 002A0CC9 | DPSana |
2B | 002B1D58 | SSPxPDxaxn |
2C | 002C0784 | SPDSoax |
2D | 002D060A | PSDnox |
2E | 002E064A | PSDPxox |
2F | 002F0E2A | PSDnoan |
30 | 0030032A | PSna |
31 | 00310B28 | SDPnaon |
32 | 00320688 | SDPSoox |
33 | 00330008 | Sn | NOTSRCCOPY
34 | 003406C4 | SPDSaox |
35 | 00351864 | SPDSxnox |
36 | 003601A8 | SDPox |
37 | 00370388 | SDPoan |
38 | 0038078A | PSDPoax |
39 | 00390604 | SPDnox |
3A | 003A0644 | SPDSxox |
3B | 003B0E24 | SPDnoan |
3C | 003C004A | PSx |
3D | 003D18A4 | SPDSonox |
3E | 003E1B24 | SPDSnaox |
3F | 003F00EA | PSan |
40 | 00400F0A | PSDnaa |
41 | 00410249 | DPSxon |
42 | 00420D5D | SDxPDxa |
43 | 00431CC4 | SPDSanaxn |
44 | 00440328 | SDna | SRCERASE
45 | 00450B29 | DPSnaon |
46 | 004606C6 | DSPDaox |
47 | 0047076A | PSDPxaxn |
48 | 00480368 | SDPxa |
49 | 004916C5 | PDSPDaoxxn |
4A | 004A0789 | DPSDoax |
4B | 004B0605 | PDSnox |
4C | 004C0CC8 | SDPana |
4D | 004D1954 | SSPxDSxoxn |
4E | 004E0645 | PDSPxox |
4F | 004F0E25 | PDSnoan |
50 | 00500325 | PDna |
51 | 00510B26 | DSPnaon |
52 | 005206C9 | DPSDaox |
53 | 00530764 | SPDSxaxn |
54 | 005408A9 | DPSonon |
55 | 00550009 | Dn | DSTINVERT
56 | 005601A9 | DPSox |
57 | 00570389 | DPSoan |
58 | 00580785 | PDSPoax |
59 | 00590609 | DPSnox |
5A | 005A0049 | DPx | PATINVERT
5B | 005B18A9 | DPSDonox |
5C | 005C0649 | DPSDxox |
5D | 005D0E29 | DPSnoan |
5E | 005E1B29 | DPSDnaox |
5F | 005F00E9 | DPan |
60 | 00600365 | PDSxa |
61 | 006116C6 | DSPDSaoxxn |
62 | 00620786 | DSPDoax |
63 | 00630608 | SDPnox |
64 | 00640788 | SDPSoax |
65 | 00650606 | DSPnox |
66 | 00660046 | DSx | SRCINVERT
67 | 006718A8 | SDPSonox |
68 | 006858A6 | DSPDSonoxxn |
69 | 00690145 | PDSxxn |
6A | 006A01E9 | DPSax |
6B | 006B178A | PSDPSoaxxn |
6C | 006C01E8 | SDPax |
6D | 006D1785 | PDSPDoaxxn |
6E | 006E1E28 | SDPSnoax |
6F | 006F0C65 | PDSxnan |
70 | 00700CC5 | PDSana |
71 | 00711D5C | SSDxPDxaxn |
72 | 00720648 | SDPSxox |
73 | 00730E28 | SDPnoan |
74 | 00740646 | DSPDxox |
75 | 00750E26 | DSPnoan |
76 | 00761B28 | SDPSnaox |
77 | 007700E6 | DSan |
78 | 007801E5 | PDSax |
79 | 00791786 | DSPDSoaxxn |
7A | 007A1E29 | DPSDnoax |
7B | 007B0C68 | SDPxnan |
7C | 007C1E24 | SPDSnoax |
7D | 007D0C69 | DPSxnan |
7E | 007E0955 | SPxDSxo |
7F | 007F03C9 | DPSaan |
80 | 008003E9 | DPSaa |
81 | 00810975 | SPxDSxon |
82 | 00820C49 | DPSxna |
83 | 00831E04 | SPDSnoaxn |
84 | 00840C48 | SDPxna |
85 | 00851E05 | PDSPnoaxn |
86 | 008617A6 | DSPDSoaxx |
87 | 008701C5 | PDSaxn |
88 | 008800C6 | DSa | SRCAND
89 | 00891B08 | SDPSnaoxn |
8A | 008A0E06 | DSPnoa |
8B | 008B0666 | DSPDxoxn |
8C | 008C0E08 | SDPnoa |
8D | 008D0668 | SDPSxoxn |
8E | 008E1D7C | SSDxPDxax |
8F | 008F0CE5 | PDSanan |
90 | 00900C45 | PDSxna |
91 | 00911E08 | SDPSnoaxn |
92 | 009217A9 | DPSDPoaxx |
93 | 009301C4 | SPDaxn |
94 | 009417AA | PSDPSoaxx |
95 | 009501C9 | DPSaxn |
96 | 00960169 | DPSxx |
97 | 0097588A | PSDPSonoxx |
98 | 00981888 | SDPSonoxn |
99 | 00990066 | DSxn |
9A | 009A0709 | DPSnax |
9B | 009B07A8 | SDPSoaxn |
9C | 009C0704 | SPDnax |
9D | 009D07A6 | DSPDoaxn |
9E | 009E16E6 | DSPDSaoxx |
9F | 009F0345 | PDSxan |
A0 | 00A000C9 | DPa |
A1 | 00A11B05 | PDSPnaoxn |
A2 | 00A20E09 | DPSnoa |
A3 | 00A30669 | DPSDxoxn |
A4 | 00A41885 | PDSPonoxn |
A5 | 00A50065 | PDxn |
A6 | 00A60706 | DSPnax |
A7 | 00A707A5 | PDSPoaxn |
A8 | 00A803A9 | DPSoa |
A9 | 00A90189 | DPSoxn |
AA | 00AA0029 | D |
AB | 00AB0889 | DPSono |
AC | 00AC0744 | SPDSxax |
AD | 00AD06E9 | DPSDaoxn |
AE | 00AE0B06 | DSPnao |
AF | 00AF0229 | DPno |
B0 | 00B00E05 | PDSnoa |
B1 | 00B10665 | PDSPxoxn |
B2 | 00B21974 | SSPxDSxox |
B3 | 00B30CE8 | SDPanan |
B4 | 00B4070A | PSDnax |
B5 | 00B507A9 | DPSDoaxn |
B6 | 00B616E9 | DPSDPaoxx |
B7 | 00B70348 | SDPxan |
B8 | 00B8074A | PSDPxax |
B9 | 00B906E6 | DSPDaoxn |
BA | 00BA0B09 | DPSnao |
BB | 00BB0226 | DSno | MERGEPAINT
BC | 00BC1CE4 | SPDSanax |
BD | 00BD0D7D | SDxPDxan |
BE | 00BE0269 | DPSxo |
BF | 00BF08C9 | DPSano |
C0 | 00C000CA | PSa | MERGECOPY
C1 | 00C11B04 | SPDSnaoxn |
C2 | 00C21884 | SPDSonoxn |
C3 | 00C3006A | PSxn |
C4 | 00C40E04 | SPDnoa |
C5 | 00C50664 | SPDSxoxn |
C6 | 00C60708 | SDPnax |
C7 | 00C707AA | PSDPoaxn |
C8 | 00C803A8 | SDPoa |
C9 | 00C90184 | SPDoxn |
CA | 00CA0749 | DPSDxax |
CB | 00CB06E4 | SPDSaoxn |
CC | 00CC0020 | S | SRCCOPY
CD | 00CD0888 | SDPono |
CE | 00CE0B08 | SDPnao |
CF | 00CF0224 | SPno |
D0 | 00D00E0A | PSDnoa |
D1 | 00D1066A | PSDPxoxn |
D2 | 00D20705 | PDSnax |
D3 | 00D307A4 | SPDSoaxn |
D4 | 00D41D78 | SSPxPDxax |
D5 | 00D50CE9 | DPSanan |
D6 | 00D616EA | PSDPSaoxx |
D7 | 00D70349 | DPSxan |
D8 | 00D80745 | PDSPxax |
D9 | 00D906E8 | SDPSaoxn |
DA | 00DA1CE9 | DPSDanax |
DB | 00DB0D75 | SPxDSxan |
DC | 00DC0B04 | SPDnao |
DD | 00DD0228 | SDno |
DE | 00DE0268 | SDPxo |
DF | 00DF08C8 | SDPano |
E0 | 00E003A5 | PDSoa |
E1 | 00E10185 | PDSoxn |
E2 | 00E20746 | DSPDxax |
E3 | 00E306EA | PSDPaoxn |
E4 | 00E40748 | SDPSxax |
E5 | 00E506E5 | PDSPaoxn |
E6 | 00E61CE8 | SDPSanax |
E7 | 00E70D79 | SPxPDxan |
E8 | 00E81D74 | SSPxDSxax |
E9 | 00E95CE6 | DSPDSanaxxn |
EA | 00EA02E9 | DPSao |
EB | 00EB0849 | DPSxno |
EC | 00EC02E8 | SDPao |
ED | 00ED0848 | SDPxno |
EE | 00EE0086 | DSo | SRCPAINT
EF | 00EF0A08 | SDPnoo |
F0 | 00F00021 | P | PATCOPY
F1 | 00F10885 | PDSono |
F2 | 00F20B05 | PDSnao |
F3 | 00F3022A | PSno |
F4 | 00F40B0A | PSDnao |
F5 | 00F50225 | PDno |
F6 | 00F60265 | PDSxo |
F7 | 00F708C5 | PDSano |
F8 | 00F802E5 | PDSao |
F9 | 00F90845 | PDSxno |
FA | 00FA0089 | DPo |
FB | 00FB0A09 | DPSnoo | PATPAINT
FC | 00FC008A | PSo |
FD | 00FD0A0A | PSDnoo |
FE | 00FE02A9 | DPSoo |
FF | 00FF0062 | 1 | WHITENESS


消息处理相关函数

消息缓冲区可以缓冲 63 个未处理的消息。每次获取消息时，将从消息缓冲区取出一个最早发生的消息。消息缓冲区满了之后，不再接收任何消息。

相关函数如下：

函数或数据类型 | 描述
ExMessage | 消息结构体。
flushmessage | 清空消息缓冲区。
getmessage | 获取一个消息。如果当前消息缓冲区中没有，就一直等待。
peekmessage | 获取一个消息，并立即返回。


ExMessage

这个结构体用于保存鼠标消息，定义如下：

struct ExMessage
{
    USHORT message;					// 消息标识
    union
    {
        // 鼠标消息的数据
        struct
        {
            bool ctrl		:1;		// Ctrl 键是否按下
            bool shift		:1;		// Shift 键是否按下
            bool lbutton	:1;		// 鼠标左键是否按下
            bool mbutton	:1;		// 鼠标中键是否按下
            bool rbutton	:1;		// 鼠标右键
            short x;				// 鼠标的 x 坐标
            short y;				// 鼠标的 y 坐标
            short wheel;			// 鼠标滚轮滚动值，为 120 的倍数
        };

        // 按键消息的数据
        struct
        {
            BYTE vkcode;			// 按键的虚拟键码
            BYTE scancode;			// 按键的扫描码（依赖于 OEM）
            bool extended	:1;		// 按键是否是扩展键
            bool prevdown	:1;		// 按键的前一个状态是否按下
        };

        // 字符消息的数据
        TCHAR ch;

        // 窗口消息的数据
        struct
        {
            WPARAM wParam;
            LPARAM lParam;
        };
    };
};

成员

message

消息标识，可为以下值：

消息标识 | 消息类别 | 描述
WM_MOUSEMOVE | EM_MOUSE | 鼠标移动消息。
WM_MOUSEWHEEL |  | 鼠标滚轮拨动消息。
WM_LBUTTONDOWN |  | 左键按下消息。
WM_LBUTTONUP |  | 左键弹起消息。
WM_LBUTTONDBLCLK |  | 左键双击消息。
WM_MBUTTONDOWN |  | 中键按下消息。
WM_MBUTTONUP |  | 中键弹起消息。
WM_MBUTTONDBLCLK |  | 中键双击消息。
WM_RBUTTONDOWN |  | 右键按下消息。
WM_RBUTTONUP |  | 右键弹起消息。
WM_RBUTTONDBLCLK |  | 右键双击消息。
WM_KEYDOWN | EM_KEY | 按键按下消息
WM_KEYUP |  | 按键弹起消息。
WM_CHAR | EM_CHAR | 字符消息。
WM_ACTIVATE | EM_WINDOW | 窗口激活状态改变消息。
WM_MOVE |  | 窗口移动消息。
WM_SIZE |  | 窗口大小改变消息。

ctrl

Ctrl 键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。

shift

Shift 键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。

lbutton

鼠标左键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。

mbutton

鼠标中键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。

rbutton

鼠标右键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。

x

当前鼠标 x 坐标（物理坐标）。仅当消息所属类别为 EM_MOUSE 时有效。

y

当前鼠标 y 坐标（物理坐标）。仅当消息所属类别为 EM_MOUSE 时有效。

wheel

鼠标滚轮滚动值，为 120 的倍数。仅当消息所属类别为 EM_MOUSE 时有效。

vkcode

按键的虚拟键码。仅当消息所属类别为 EM_KEY 时有效。

在微软网站上列出有所有的虚拟键码：https://docs.microsoft.com/windows/win32/inputdev/virtual-key-codes

scancode

按键的扫描码（依赖于 OEM）。仅当消息所属类别为 EM_KEY 时有效。

extended

按键是否为扩展按键，例如功能键和数字键盘。仅当消息所属类别为 EM_KEY 时有效。

prevdown

按键的前一个状态是否为按下。仅当消息所属类别为 EM_KEY 时有效。

ch

收到的字符。仅当消息所属类别为 EM_CHAR 时有效。

wParam

消息对应的 wParam 参数。仅当消息所属类别为 EM_WINDOW 时有效。

lParam

消息对应的 lParam 参数。仅当消息所属类别为 EM_WINDOW 时有效。

示例

无


flushmessage

这个函数用于清空消息缓冲区。

void flushmessage(BYTE filter = -1);

参数

filter

指定要清空的消息范围，默认 -1 清空所有类别的消息。可以用以下值或值的组合清空指定类别的消息：

标志 | 描述
EM_MOUSE | 鼠标消息。
EM_KEY | 按键消息。
EM_CHAR | 字符消息。
EM_WINDOW | 窗口消息。

返回值

无

示例

无


getmessage

这个函数用于获取一个消息。如果当前消息队列中没有，就一直等待。

ExMessage getmessage(BYTE filter = -1);
void getmessage(ExMessage *msg, BYTE filter = -1);

参数

msg

指向消息结构体 ExMessage 的指针，用来保存获取到的消息。

filter

指定要获取的消息范围，默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息：

标志 | 描述
EM_MOUSE | 鼠标消息。
EM_KEY | 按键消息。
EM_CHAR | 字符消息。
EM_WINDOW | 窗口消息。

返回值

重载 1 返回保存有消息 ExMessage 的结构体。

重载 2 没有返回值。

备注

默认情况下，连续的鼠标单击会被识别为一系列的单击事件。如果希望两个连续的鼠标单击识别为双击事件，请在创建绘图窗口的时候指定标志位 EW_DBLCLKS。

示例

请参见 示例程序 中的“鼠标操作范例”。


peekmessage

这个函数用于获取一个消息，并立即返回。

bool peekmessage(ExMessage *msg, BYTE filter = -1, bool removemsg = true);

参数

msg

指向消息结构体 ExMessage 的指针，用来保存获取到的消息。

filter

指定要获取的消息范围，默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息：

标志 | 描述
EM_MOUSE | 鼠标消息。
EM_KEY | 按键消息。
EM_CHAR | 字符消息。
EM_WINDOW | 窗口消息。

removemsg

在 peekmessage 处理完消息后，是否将其从消息队列中移除。

返回值

如果获取到了消息，返回 true。

如果当前没有消息，返回 flase。

备注

默认情况下，连续的鼠标单击会被识别为一系列的单击事件。如果希望两个连续的鼠标单击识别为双击事件，请在创建绘图窗口的时候指定标志位 EW_DBLCLKS。

示例

无


其它函数

相关函数如下：

函数或数据类型 | 描述
BeginBatchDraw | 开始批量绘图。
EndBatchDraw | 结束批量绘制，并执行未完成的绘制任务。
FlushBatchDraw | 执行未完成的绘制任务。
GetEasyXVer | 获取当前 EasyX 库的版本信息。
GetHWnd | 获取绘图窗口句柄。
InputBox | 以对话框形式获取用户输入。


BeginBatchDraw

这个函数用于开始批量绘图。执行后，任何绘图操作都将暂时不输出到绘图窗口上，直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。

void BeginBatchDraw();

参数

无

返回值

无

示例

以下代码实现一个圆从左向右移动，会有比较明显的闪烁。
请取消 main 函数中的三个注释，以实现批绘图功能，可以消除闪烁。

#include <graphics.h>

int main()
{
    initgraph(640,480);
    // BeginBatchDraw();

    setlinecolor(WHITE);
    setfillcolor(RED);

    for(int i=50; i<600; i++)
    {
        circle(i, 100, 40);
        floodfill(i, 100, WHITE);
        // FlushBatchDraw();
        Sleep(10);
        cleardevice();
    }

    // EndBatchDraw();
    closegraph();
}


EndBatchDraw

这个函数用于结束批量绘制，并执行未完成的绘制任务。

// 结束批量绘制，并执行未完成的绘制任务
void EndBatchDraw();
// 结束批量绘制，并执行指定区域内未完成的绘制任务
void EndBatchDraw(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

指定区域的左部 x 坐标。

top

指定区域的上部 y 坐标。

right

指定区域的右部 x 坐标。

bottom

指定区域的下部 y 坐标。

返回值

无

示例

请参见 BeginBatchDraw 的示例。


FlushBatchDraw

这个函数用于执行未完成的绘制任务。

// 执行未完成的绘制任务
void FlushBatchDraw();
// 执行指定区域内未完成的绘制任务
void FlushBatchDraw(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

指定区域的左部 x 坐标。

top

指定区域的上部 y 坐标。

right

指定区域的右部 x 坐标。

bottom

指定区域的下部 y 坐标。

返回值

无

示例

请参见 BeginBatchDraw 的示例。


GetEasyXVer

这个函数用于获取当前 EasyX 库的版本信息。

TCHAR* GetEasyXVer();

参数

无

返回值

返回当前 EasyX 库的版本信息。

示例

以下代码实现输出当前 EasyX 版本号：

#include <stdio.h>
#include <graphics.h>

int main()
{
    TCHAR* s = GetEasyXVer();
    _tprintf("EasyX 当前版本：%s\n", s);
}


GetHWnd

这个函数用于获取绘图窗口句柄。

HWND GetHWnd();

参数

无

返回值

返回绘图窗口句柄。

备注

在 Windows 下，句柄是一个窗口的标识，得到句柄后，可以使用 Windows API 中的函数实现对窗口的控制。

注意，请不要通过该窗口句柄获取窗口的 DC 然后利用 GDI 函数实现对窗口的绘图操作。由于实现机制的问题，获取窗口的 DC 请使用 GetImageHDC 函数。

示例

// 获得窗口句柄
HWND hWnd = GetHWnd();
// 使用 Windows API 修改窗口名称
SetWindowText(hWnd, "Hello!");


InputBox

这个函数用于以对话框形式获取用户输入。

bool InputBox(
    LPTSTR	pString,
    int		nMaxCount,
    LPCTSTR	pPrompt = NULL,
    LPCTSTR	pTitle = NULL,
    LPCTSTR	pDefault = NULL,
    int		width = 0,
    int		height = 0,
    bool	bHideCancelBtn = true
);

参数

pString

指定接收用户输入字符串的指针。

nMaxCount

指定 pString 指向的缓冲区的大小，该值会限制用户输入内容的长度。缓冲区的大小包括表示字符串结尾的 '\0' 字符。当允许多行输入时，用户键入的回车占两个字符位置。

pPrompt

指定显示在对话框中的提示信息。提示信息中可以用“\n”分行。InputBox 的高度会随着提示信息内容的多少自动扩充。如果该值为 NULL，则不显示提示信息。

pTitle

指定 InputBox 的标题栏。如果为 NULL，将显示应用程序的名称。

pDefault

指定显示在用户输入区的默认值。

width

指定 InputBox 的宽度（不包括边框），最小为 200 像素。如果为 0，则使用默认宽度。

height

指定 InputBox 的高度（不包括边框）。如果为 0，表示自动计算高度，用户输入框只允许输入一行内容，按“回车”确认输入信息；如果大于 0，用户输入框的高度会自动拓展，同时允许输入多行内容，按“Ctrl+回车”确认输入信息。

bHideCancelBtn

指定是否隐藏取消按钮禁止用户取消输入。如果为 true(默认)，InputBox 只有一个“确定”按钮，没有“X”关闭按钮，按 ESC 无效；如果为 false，InputBox 有“确定”和“取消”按钮，允许点“X”和按 ESC 关闭窗口。

返回值

返回用户是否输入信息。如果用户按“确定”，返回 true；如果用户按“取消”，返回 false。

示例

以下示例提示用户输入圆的半径，并画圆：

// 编译环境：VC2008 及以上版本，Unicode 字符集
//
#include <graphics.h>
#include <conio.h>

int main()
{
    // 初始化绘图窗口
    initgraph(640, 480);

    // 定义字符串缓冲区，并接收用户输入
    wchar_t s[10];
    InputBox(s, 10, L"请输入半径");

    // 将用户输入转换为数字
    int r = _wtoi(s);

    // 画圆
    circle(320, 240, r);

    // 按任意键退出
    _getch();
    closegraph();

    return 0;
}


graphics.h 暂留函数

在 easyx.h 的基础上，graphics.h 暂时保留了若干已经废弃的函数，以提高对旧程序的兼容性。

在 graphics.h 里面额外提供的相关函数如下：

函数或数据类型 | 描述
bar | 画无边框填充矩形。
bar3d | 画有边框三维填充矩形。
drawpoly | 画无填充的多边形。
fillpoly | 画有边框的填充多边形。
getcolor | 获取当前绘图前景色。
getmaxx | 获取绘图窗口的物理坐标中的最大 x 坐标。
getmaxy | 获取绘图窗口的物理坐标中的最大 y 坐标。
getx | 获取当前 x 坐标。
gety | 获取当前 y 坐标。
linerel | 画直线。
lineto | 画直线。
moverel | 移动当前点。
moveto | 移动当前点。
outtext | 在当前位置输出字符串。
setcolor | 设置当前绘图前景色。
setwritemode | 设置前景的二元光栅操作模式。


bar

这个函数用于画无边框填充矩形。

void bar(
    int left,
    int top,
    int right,
    int bottom
);

参数

left

矩形左部 x 坐标。

top

矩形顶部 y 坐标。

right

矩形右部 x 坐标。

bottom

矩形底部 y 坐标。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，推荐使用 solidrectangle 替代该函数。

示例

无


bar3d

这个函数用于画有边框三维填充矩形。

void bar3d(
    int left,
    int top,
    int right,
    int bottom,
    int depth,
    bool topflag
);

参数

left

矩形左部 x 坐标。

top

矩形顶部 y 坐标。

right

矩形右部 x 坐标。

bottom

矩形底部 y 坐标。

depth

矩形深度。

topflag

为 false 时，将不画矩形的三维顶部。该选项可用来画堆叠的三维矩形。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


drawpoly

这个函数用于画无填充的多边形。

void drawpoly(
    int numpoints,
    const int *polypoints
);

参数

numpoints

多边形顶点的个数。

polypoints

每个点的坐标，数组元素个数为 numpoints * 2。
该函数会自动连接多边形首尾。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，推荐使用 polygon 替代该函数。

示例

以下代码片段绘制一个封闭的三角形：

int points[] = {50, 200,  200, 200,  200, 50};
drawpoly(3, points);


fillpoly

这个函数用于画有边框的填充多边形。

void fillpoly(
    int numpoints,
    const int *polypoints
);

参数

numpoints

多边形顶点的个数。

polypoints

每个点的坐标，数组元素个数为 numpoints * 2。
该函数会自动连接多边形首尾。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，推荐使用 fillpolygon 替代该函数。

示例

以下代码片段绘制一个封闭的填充三角形：

int points[] = {50, 200,  200, 200,  200, 50};
fillpoly(3, points);


getcolor

这个函数用于获取当前绘图前景色。

COLORREF getcolor();

参数

无

返回值

返回当前的前景颜色。

备注

该函数已废弃，仅在 graphics.h 中声明，推荐使用 getlinecolor 或 gettextcolor 替代该函数。

由于该函数设置的前景色同时包括画线和文字颜色，因此不完全等效于 easyx.h 中的 getlinecolor 或 gettextcolor 函数，请根据实际情况选择替代函数。

示例

无


getmaxx

该函数用于获取绘图窗口的物理坐标中的最大 x 坐标。

int getmaxx();

参数

无

返回值

返回绘图窗口的物理坐标中的最大 x 坐标。

备注

该函数已废弃，仅在 graphics.h 中声明，推荐使用 getwidth() - 1 替代该函数。

getmaxx() 总是返回绘图窗口的物理坐标中的最大 x 坐标，与缩放设置无关。等价于 getwidth() - 1。例如，初始化为 640 x 480 的绘图窗口，getwidth() 返回 640，getmaxx() 返回 639。

示例

无


getmaxy

这个函数用于获取绘图窗口的物理坐标中的最大 y 坐标。

int getmaxy();

参数

无

返回值

返回绘图窗口的物理坐标中的最大 y 坐标。

备注

该函数已废弃，仅在 graphics.h 中声明，推荐使用 getheight() - 1 替代该函数。

getmaxy() 总是返回绘图窗口的物理坐标中的最大 y 坐标，与缩放设置无关。等价于 getheight() - 1。例如，初始化为 640 x 480 的绘图窗口，getheight() 返回 480，getmaxy() 返回 479。

示例

无


getx

这个函数用于获取当前 x 坐标。

int getx();

参数

无

返回值

返回当前 x 坐标。

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


gety

这个函数用于获取当前 y 坐标。

int gety();

参数

无

返回值

返回当前 y 坐标。

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


linerel

这个函数用于画直线。还可以用 line 和 lineto 画直线。

void linerel(
    int dx,
    int dy
);

参数

dx

从“当前点”开始画直线，沿 x 轴偏移 dx。

dy

从“当前点”开始画直线，沿 y 轴偏移 dy。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


lineto

这个函数用于画直线。还可以用 line 和 linerel 画直线。

void lineto(
    int x,
    int y
);

参数

x

目标点的 x 坐标（从“当前点”开始画直线）。

y

目标点的 y 坐标（从“当前点”开始画直线）。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


moverel

这个函数用于移动当前点。 有些绘图操作会从“当前点”开始，这个函数可以设置该点。还可以用 moveto 设置当前点。

void moverel(
    int dx,
    int dy
);

参数

dx

将当前点沿 x 轴移动 dx。

dy

将当前点沿 y 轴移动 dy。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


moveto

这个函数用于移动当前点。 有些绘图操作会从“当前点”开始，这个函数可以设置该点。还可以用 moverel 设置当前点。

void moveto(
    int x,
    int y
);

参数

x

新的当前点 x 坐标。

y

新的当前点 y 坐标。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

示例

无


outtext

这个函数用于在当前位置输出字符串。

void outtext(LPCTSTR str);
void outtext(TCHAR c);

参数

str

待输出的字符串的指针。

c

待输出的字符。

返回值

无

备注

该函数已废弃，仅在 graphics.h 中声明，不推荐使用。

该函数会改变当前位置至字符串末尾。可以连续使用该函数使输出的字符串保持连续。

示例

// 输出字符串（MBCS 字符集）
char s[] = "Hello World";
outtext(s);
// 输出字符串（Unicode 字符集）
wchar_t s[] = L"Hello World";
outtext(s);

// 输出字符串 (项目字符集)
TCHAR s[] = _T("Hello World");
outtext(s);
// 输出字符（MBCS 字符集）
char c = 'A';
outtext(c);
// 输出数值，先将数字格式化输出为字符串（MBCS 字符集）
char s[5];
sprintf(s, "%d", 1024);
outtext(s);


setcolor

这个函数用于设置当前绘图前景色。

void setcolor(COLORREF color);

参数

color

要设置的前景颜色。

返回值

无

备注

该函数在 graphics.h 中声明，用于兼容 Turbo C 中的同名函数，等效于连续执行 easyx.h 中的 setlinecolor 和 settextcolor 函数。

建议根据需求使用 setlinecolor 或 settextcolor 代替该函数。

示例

无


setwritemode

这个函数用于设置前景的二元光栅操作模式。

void setwritemode(int mode);

参数

mode

二元光栅操作码，详见 setrop2 函数。

返回值

无

备注

该函数在 graphics.h 中声明，用于兼容 Turbo C 中的同名函数，等效于 easyx.h 中的 setrop2 函数。

建议使用 setrop2 替代该函数。

示例

无


鼠标相关函数

鼠标消息缓冲区可以缓冲 63 个未处理的鼠标消息。每次获取鼠标消息时，将从鼠标消息缓冲区取出一个最早发生的鼠标消息。鼠标消息缓冲区满了之后，不再接收任何鼠标消息。

相关函数如下：

函数或数据类型 | 描述
FlushMouseMsgBuffer | 清空鼠标消息缓冲区。
GetMouseMsg | 获取一个鼠标消息。如果当前鼠标消息队列中没有，就一直等待。
PeekMouseMsg | 获取一个鼠标消息，并立即返回。
MouseHit | 检测当前是否有鼠标消息。
MOUSEMSG | 保存鼠标消息的结构体。


FlushMouseMsgBuffer

这个函数用于清空鼠标消息缓冲区。

void FlushMouseMsgBuffer();

参数

无

返回值

无

备注

该结构体已废弃，仅在 graphics.h 中声明。建议使用 flushmessage 替代。

示例

无


GetMouseMsg

这个函数用于获取一个鼠标消息。如果当前鼠标消息队列中没有，就一直等待。

MOUSEMSG GetMouseMsg();

参数

无

返回值

返回保存有鼠标消息的结构体。

备注

默认情况下，连续的鼠标单击会被识别为一系列的单击事件。如果希望两个连续的鼠标单击识别为双击事件，请在创建绘图窗口的时候指定标志位 EW_DBLCLKS。

该结构体已废弃，仅在 graphics.h 中声明。建议使用 getmessage 替代。

示例

请参见 示例程序 中的“鼠标操作范例”。


MouseHit

这个函数用于检测当前是否有鼠标消息。

bool MouseHit();

参数

无

返回值

如果存在鼠标消息，返回 true；否则返回 false。

备注

该结构体已废弃，仅在 graphics.h 中声明。建议使用 peekmessage 替代。

示例

无


PeekMouseMsg

这个函数用于获取一个鼠标消息，并立即返回。

bool PeekMouseMsg(MOUSEMSG *pMsg, bool bRemoveMsg);

参数

pMsg

指向 MOUSEMSG 结构体的指针，用来保存接收到的鼠标消息。

bRemoveMsg

在 PeekMouseMsg 处理完消息后，是否将其从消息队列中移除。

返回值

如果有鼠标消息，返回 true。

如果当前没有鼠标消息，返回 flase。

备注

默认情况下，连续的鼠标单击会被识别为一系列的单击事件。如果希望两个连续的鼠标单击识别为双击事件，请在创建绘图窗口的时候指定标志位 EW_DBLCLKS。

该结构体已废弃，仅在 graphics.h 中声明。建议使用 peekmessage 替代。

示例

无


MOUSEMSG

这个结构体用于保存鼠标消息，定义如下：

struct MOUSEMSG
{
    UINT uMsg;			// 当前鼠标消息
    bool mkCtrl;		// Ctrl 键是否按下
    bool mkShift;		// Shift 键是否按下
    bool mkLButton;		// 鼠标左键是否按下
    bool mkMButton;		// 鼠标中键是否按下
    bool mkRButton;		// 鼠标右键是否按下
    int x;				// 当前鼠标 x 坐标（物理坐标）
    int y;				// 当前鼠标 y 坐标（物理坐标）
    int wheel;			// 鼠标滚轮滚动值
};

成员

uMsg

指定鼠标消息类型，可为以下值：

值 | 含义
WM_MOUSEMOVE | 鼠标移动消息。
WM_MOUSEWHEEL | 鼠标滚轮拨动消息。
WM_LBUTTONDOWN | 左键按下消息。
WM_LBUTTONUP | 左键弹起消息。
WM_LBUTTONDBLCLK | 左键双击消息。
WM_MBUTTONDOWN | 中键按下消息。
WM_MBUTTONUP | 中键弹起消息。
WM_MBUTTONDBLCLK | 中键双击消息。
WM_RBUTTONDOWN | 右键按下消息。
WM_RBUTTONUP | 右键弹起消息。
WM_RBUTTONDBLCLK | 右键双击消息。

mkCtrl

Ctrl 键是否按下

mkShift

Shift 键是否按下

mkLButton

鼠标左键是否按下

mkMButton

鼠标中键是否按下

mkRButton

鼠标右键是否按下

x

当前鼠标 x 坐标（物理坐标）

y

当前鼠标 y 坐标（物理坐标）

wheel

鼠标滚轮滚动值，为 120 的倍数。

备注

该结构体已废弃，仅在 graphics.h 中声明。建议使用 EASYXMSG 替代。

示例

无


示例程序

更多示例程序，请访问 https://codebus.cn

示例名称 | 描述
字符阵 | 该程序示范了常见的绘图操作，包括设置字体、画线等。
星空 | 该程序实现了二维星空的动态效果。
鼠标操作 | 该程序示范了常见的鼠标操作，程序执行后会在鼠标的移动轨迹上画红点，按左键画小方块，按 Ctrl + 左键画大方块，按右键退出程序。
彩虹 | 该程序是 HSL 色彩模型的应用范例，程序通过调节 HSL 模型的亮度绘制渐变的天空，调节色相绘制七色彩虹。


字符阵

该程序示范了常见的绘图操作，包括设置字体、画线等。

// 编译环境：Visual C++ 6.0~2019，EasyX_20210730
// https://easyx.cn
//
#include <graphics.h>
#include <time.h>
#include <conio.h>

int main()
{
    // 设置随机种子
    srand((unsigned) time(NULL));

    // 初始化图形模式
    initgraph(640, 480);

    int  x, y;
    char c;

    settextstyle(16, 8, _T("Courier"));	// 设置字体

    // 设置颜色
    settextcolor(GREEN);
    setlinecolor(BLACK);

    for (int i = 0; i <= 479; i++)
    {
        // 在随机位置显示三个随机字母
        for (int j = 0; j < 3; j++)
        {
            x = (rand() % 80) * 8;
            y = (rand() % 20) * 24;
            c = (rand() % 26) + 65;
            outtextxy(x, y, c);
        }

        // 画线擦掉一个像素行
        line(0, i, 639, i);

        Sleep(10);					// 延时
        if (i >= 479)	i = -1;
        if (_kbhit())	break;		// 按任意键退出
    }

    // 关闭图形模式
    closegraph();
    return 0;
}

更多示例程序，请访问 https://codebus.cn


星空

该程序实现了二维星空的动态效果。

// 编译环境：Visual C++ 6.0~2019，EasyX_20210730
// https://easyx.cn
//
#include <graphics.h>
#include <time.h>
#include <conio.h>

#define MAXSTAR 200	// 星星总数

struct STAR
{
    double	x;
    int		y;
    double	step;
    int		color;
};

STAR star[MAXSTAR];

// 初始化星星
void InitStar(int i)
{
    star[i].x = 0;
    star[i].y = rand() % 480;
    star[i].step = (rand() % 5000) / 1000.0 + 1;
    star[i].color = (int)(star[i].step * 255 / 6.0 + 0.5);	// 速度越快，颜色越亮
    star[i].color = RGB(star[i].color, star[i].color, star[i].color);
}

// 移动星星
void MoveStar(int i)
{
    // 擦掉原来的星星
    putpixel((int)star[i].x, star[i].y, 0);

    // 计算新位置
    star[i].x += star[i].step;
    if (star[i].x > 640)	InitStar(i);

    // 画新星星
    putpixel((int)star[i].x, star[i].y, star[i].color);
}

// 主函数
int main()
{
    srand((unsigned)time(NULL));	// 随机种子
    initgraph(640, 480);			// 创建绘图窗口

    // 初始化所有星星
    for(int i = 0; i < MAXSTAR; i++)
    {
        InitStar(i);
        star[i].x = rand() % 640;
    }

    // 绘制星空，按任意键退出
    while(!_kbhit())
    {
        for(int i = 0; i < MAXSTAR; i++)
            MoveStar(i);
        Sleep(20);
    }

    closegraph();					// 关闭绘图窗口
    return 0;
}

更多示例程序，请访问 https://codebus.cn


鼠标操作

该程序示范了常见的鼠标操作，程序执行后会在鼠标的移动轨迹上画红点，按左键画小方块，按 Ctrl + 左键画大方块，按右键退出程序。

// 编译环境：Visual C++ 6.0~2019，EasyX_20210730
// https://easyx.cn
//
#include <graphics.h>

int main()
{
    // 初始化图形窗口
    initgraph(640, 480);

    ExMessage m;		// 定义消息变量

    while(true)
    {
        // 获取一条鼠标或按键消息
        m = getmessage(EM_MOUSE | EM_KEY);

        switch(m.message)
        {
            case WM_MOUSEMOVE:
                // 鼠标移动的时候画红色的小点
                putpixel(m.x, m.y, RED);
                break;

            case WM_LBUTTONDOWN:
                // 如果点左键的同时按下了 Ctrl 键
                if (m.ctrl)
                    // 画一个大方块
                    rectangle(m.x - 10, m.y - 10, m.x + 10, m.y + 10);
                else
                    // 画一个小方块
                    rectangle(m.x - 5, m.y - 5, m.x + 5, m.y + 5);
                break;

            case WM_KEYDOWN:
                if (m.vkcode == VK_ESCAPE)
                    return 0;	// 按 ESC 键退出程序
        }
    }

    // 关闭图形窗口
    closegraph();
    return 0;
}

更多示例程序，请访问 https://codebus.cn


彩虹

该程序是 HSL 色彩模型的应用范例，程序通过调节 HSL 模型的亮度绘制渐变的天空，调节色相绘制七色彩虹。

// 编译环境：Visual C++ 6.0~2019，EasyX_20210730
// https://easyx.cn
//
#include <graphics.h>
#include <conio.h>

int main()
{
    // 创建绘图窗口
    initgraph(640, 480);

    // 画渐变的天空(通过亮度逐渐增加)
    float H = 190;		// 色相
    float S = 1;		// 饱和度
    float L = 0.7f;		// 亮度
    for(int y = 0; y < 480; y++)
    {
        L += 0.0005f;
        setlinecolor( HSLtoRGB(H, S, L) );
        line(0, y, 639, y);
    }

    // 画彩虹(通过色相逐渐增加)
    H = 0;
    S = 1;
    L = 0.5f;
    setlinestyle(PS_SOLID, 2);		// 设置线宽为 2
    for(int r = 400; r > 344; r--)
    {
        H += 5;
        setlinecolor( HSLtoRGB(H, S, L) );
        circle(500, 480, r);
    }

    // 按任意键退出
    _getch();
    closegraph();
    return 0;
}

更多示例程序，请访问 https://codebus.cn


常见问题

这里列举出了使用 EasyX 的一些常见问题：

  • 编译错误：“2 个重载中没有一个可以转换所有参数类型”
  • 编译错误：“EasyX is only for C++”

更多的常见问题，请访问 EasyX 官方网站，以及 EasyX 社区。

还可以到 EasyX 社区进行更多编程问题的讨论。


编译错误：2 个重载中没有一个可以转换所有参数类型

错误描述：

一些程序在 VC6 下运行好好地，但是放到 VC2008 及更高版本 VC 下编译却报错误（以下仅以 VC2008 举例，高版本 VC 类似），例如使用如下语句：

outtextxy(10, 20, "Hello World");

在 VC6 下可以成功编译，但在 VC2008 下编译后会有错误。

错误提示如下：

error C2665: “outtextxy”: 2 个重载中没有一个可以转换所有参数类型

同样的，对于其他一些包含字符串调用的函数，例如 loadimage、drawtext 等，也会遇到类似问题。

错误原因：

简单来说，这是由于字符编码问题引起的。

VC6 默认使用的 MBCS 编码，而 VC2008 及高版本 VC 默认使用的 Unicode 编码。以下详细解释这个问题：

用 char 表示字符时，英文占用一个字节，中文占用两个字节。这样有一个严重的问题：两个连续字节，究竟是两个英文字符，还是一个中文字符？为了解决这个问题，Unicode 编码诞生了。Unicode 编码不管中文英文都用两个字节表示。

对于 MBCS 编码，字符变量用 char 定义。
对于 Unicode 编码中，字符变量用 wchar_t 定义。

为了提高代码的自适应性，微软在 tchar.h 里面定义了 TCHAR，而 TCHAR 会根据项目定义的编码，自动展开为 char 或 wchar_t。

在 Windows API 和 EasyX 里面的大多数字符串指针都用的 LPCTSTR 或 LPTSTR 类型，LPCTSTR / LPTSTR 就是“Long Point (Const) Tchar STRing”的缩写。所以可以认为，LPCTSTR 就是 const TCHAR *，LPTSTR 就是 TCHAR * 。

于是，在 VS2008 里面，给函数传递 char 字符串时，就会提示前述错误。

解决方案：

解决方法有多个，目的一样，都是让字符编码相匹配。

方法一：将所有字符串都修改为 TCHAR 版本。

简单来说需要注意以下几点：

1. 在程序中使用 #include 添加对 TCHAR 的支持。

2. 对于字符串，例如 "abc" 用 _T("abc") 表示。就是加上 _T("")。

3. 定义字符变量时，将 char 换成 TCHAR。

4. 操作字符串的函数也要换成相应的 TCHAR 版本，例如 strcpy 要换成 _tcscpy。（详见 MSDN）

方法二：在代码中取消 Unicode 编码的宏定义，让后续编译都以 MBCS 编码进行。

方法很简单，只需要在代码文件的顶部增加以下代码：

#undef UNICODE
#undef _UNICODE

这样就可以取消 Unicode 编码的宏定义，让整个项目以 MBCS 编码编译。

方法三：在 VC2008 里面，将项目属性中的字符编码修改为 MBCS。

操作步骤：点菜单“项目-> xxx 属性...”，点左侧的“配置属性”，在右侧的设置中找到“字符集”，修改默认的“使用 Unicode 字符集”为“使用多字节字符集”。

设置完毕后，再次编译就可以看到问题已经解决。


编译错误：EasyX is only for C++

错误描述：

在 Visual C++ 中编译引用 graphics.h 头文件后，编译产生错误：

fatal error C1189: #error :  EasyX is only for C++

错误原因：

为了降低学习编程的干扰，EasyX 库在很大程度上简化了图形函数的使用。由于在简化图形函数的过程中使用了部分 c++ 的特性，因此，当代码是 .c 扩展名时，Visual C++ 会调用 c 编译器而不是 c++ 编译器，以至于产生这个编译错误。

解决方案：

不用修改任何程序代码，只需要将代码文件的扩展名由 .c 修改为 .cpp，就能解决这个编译问题。

对于学习编程而言，通常可以认为 c 语言是 c++ 语言的一个子集，因此，在 .cpp 文件中学习 c 语言编程是没有什么问题的。


联系我们

官方网站：https://easyx.cn

社区讨论：https://go.easyx.cn/forum

QQ 群列表：https://go.easyx.cn/qqgroup

________________________________________________________________

EasyX_20210730
https://easyx.cn