huidong

靖康恥,猶未雪;臣子恨,何時滅!

HiEasyX——窗口、绘图、UI 的全面升级 银牌收录

声明

感谢大家对 HiEasyX 的厚爱,截止 2023.2.18,HiEasyX 已经更新到了 Ver 0.3.1,也有了一些用户。但是 CodeBus 上的这篇教程仍然只适用于 HiEasyX Ver2.x 的远古版本,难以和 Github 上的最新版同步。所以如果可以访问 github,请尽量看 github 上的最新教程:https://github.com/zouhuidong/HiEasyX

如果你在使用 HiEasyX 的过程中遇到了问题,可以在 github 发 issue 问我,或者在此文章评论区留言,也可以加我 QQ(1442701429),但是因为学业繁忙,所以可能不会立即回复你(一般不会超过一个月)。

2024.01.01 更新:

许多朋友表示希望有一个 HiEasyX 讨论群,故现建立了 QQ 群【C 语言革命:HiEasyX 讨论小组(761990769)】,欢迎大家加入讨论。

HiEasyX

HiEasyX 基于 EasyX 实现了在窗口、绘图、UI 等诸多方面的全面升级。

HiEasyX 只有一个目的——让 EasyX 更易用。

GIthub

Why HiEasyX

EasyX 从设计之初,它就仅仅是一个图形库,不涉及其它方面的功能。
当我们用 EasyX 制作软件或游戏时经常会遇到下列问题:

  • 创建多个绘图窗口
  • 完整的控件库
  • 透明通道
  • 图层
  • 声音
  • 播放 gif 动画

等等……

您是否曾经为它们苦恼?HiEasyX 可能是一个更完美的解决方案。

HiEasyX 支持创建多绘图窗口,拥有相对完善的控件库,支持透明通道,封装了画布、图层和场景。

您想用 EasyX 更高效地制作软件或游戏吗?HiEasyX 或许是适合您的选择。HiEasyX 不是独立的一个库,它是 EasyX 的充分扩展。它使用 C++,或许不适合 EasyX 的初学者。

支持功能

*(此文章可能更新不及时,最新更新在 Github
HiWindow:窗口支持

  • 支持创建多绘图窗口
  • 支持窗口拉伸
  • 支持 Win32 控件
  • 支持自定义窗口过程函数
  • 支持快速创建托盘

HiGUI:自绘控件(未完工)

  • Static
  • Button
  • ProgressCtrl
  • ScrollBar
  • Page

HiSysGUI:系统控件封装

  • SysStatic
  • SysButton
  • SysCheckBox
  • SysRadioButton
  • SysGroup
  • SysGroupBox
  • SysEdit
  • SysComboBox

HiCanvas:EasyX 绘图函数的 C++ 封装

  • 支持透明通道
  • 和 HiWindow 完美融合
  • 使用更加方便

HiGif:动图支持(改编自:依稀_yixy)

HiMusicMCI:声音 API 封装(原作者:悠远的苍穹 2237505658@qq.com)

HiMouseDrag:鼠标拖动消息封装

以上模块如非原创,均已特别标注。

鸣谢

依稀_yixy

悠远的苍穹

编译环境

  • Windows 10
  • VisualStudio 2022
  • EasyX_20220610

注意:
暂不支持 MinGW 编译器,请使用 Visual Studio 编译项目。

配置此库

您可以直接打开 Github 仓库中的项目并编译运行。下面是在您的项目中配置此库的方法:

  1. 下载仓库到本地
  2. 创建一个 Visual Studio 项目
  3. 复制仓库项目中的 ./HiEasyX/HiEasyX.h./HiEasyX/HiEasyX/ 整个文件夹到您的项目目录下
  4. 将刚才复制的文件和文件夹加入到您的 Visual Studio 项目中(拖入 Visual Studio 的项目资源管理器即可)
  5. 编写代码,编译运行

温馨提示
由于 HiEasyX 源码文件较多,故建议在 Visual Studio 项目资源管理器中创建 HiEasyX 筛选器,将上述文件和文件夹都拖入此筛选器中,这样可以使项目结构更整洁。第一次编译需要编译全部文件,所以耗时较长,后面就不会了。

测试代码:

#include "HiEasyX.h"		// 包含 HiEasyX 头文件

int main()
{
	initgraph();			// 初始化窗口

	BEGIN_TASK();			//(不同于 EasyX)启动任务,标识开始绘制

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

	END_TASK();				//(不同于 EasyX)完成绘制,结束任务

	FLUSH_DRAW();			//(不同于 EasyX)将绘制内容刷新到屏幕

	getmessage(EM_KEY);		// 任意键退出

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

示例程序截屏

以下的示例程序源码可以在 ./Samples/ 中找到:

透明通道

透明通道 2

多窗口 & Win32 控件 & Canvas 绘图效果

部分自绘控件

立即开始

在 Github 查看 完整教程

由于 Codebus 不支持 Markdown 排版,所以在此仅列举部分 HiEasyX 的编码示例。

创建多窗口

由于 HiEasyX 完全重写了 EasyX 的绘图窗口实现,所以可以支持创建多窗口、拉伸窗口,也支持自定义窗口过程函数。

在 HiEasyx 中,创建、管理窗口的模块名为 HiWindow

创建窗口的正确方式:

// 方法 1:直接使用 initgraph,它实际上被宏定义为 HiEasyX 的窗口创建函数
initgraph(640, 480);

// 方法 2:调用 HiEasyX 的窗口创建函数
hiex::initgraph_win32(640, 480);

// 方法 3:使用 HiEasyX 的窗口类创建窗口
hiex::Window wnd(640, 480);

// 也可以这样使用窗口类创建窗口
hiex::Window wnd;
wnd.Create(640, 480);

提示:
HiEasyX 在代码中使用 HiEasyX 命名空间,缩写 hiex,兼容旧版命名空间 EasyWin32

创建窗口时还有一些可选参数,例如窗口名称、窗口属性、过程函数、父窗口句柄,等等,此处不再展开。

如果想要创建多个窗口,再次调用创建窗口函数即可。

使用系统控件

HiEasyX 封装了常用 Win32 控件,这个控件模块被称为 HiSysGUI。
目前支持的控件类型 (此文档可能更新不及时)

  • 分组框
  • 静态文本(图像)
  • 按钮
  • 复选框
  • 单选框
  • 编辑框
  • 组合框

一般情况下,这些控件已经足够。而且,您也可以自定义窗口过程函数,直接调用其它 Win32 控件。
例如,创建一个按钮:

#include "HiEasyX.h"				// 包含 HiEasyX 头文件

int main()
{
	hiex::Window wnd(300, 200);		// 创建一个绘图窗口

	// 创建一个按钮
	hiex::SysButton btn(wnd.GetHandle(), 100, 85, 100, 30, L"Button");

	hiex::init_end();				// 阻塞等待窗口关闭
	return 0;
}

没错!使用按钮就是这么容易。

还可以在按钮中添加图片,像这样:

#include "HiEasyX.h"

int main()
{
	hiex::Window wnd(300, 200);
	hiex::SysButton btn(wnd.GetHandle(), 100, 85, 100, 30, L"Button");

	// 创建画布,绘制绿色填充圆
	hiex::Canvas canvas(30, 22);
	canvas.Clear(true, 0xe1e1e1);
	canvas.SolidCircle(15, 10, 10, true, GREEN);
	
	// 添加按钮图像
	btn.Image(true, &canvas, true);

	hiex::init_end();
	return 0;
}

提示:
代码中使用了 Canvas 绘制按钮图像,如果使用 IMAGE 同样可以。
Canvas 的使用在此文章中不会详细描述,如有兴趣,可以查看 Github 仓库

如果要响应按钮消息,可以使用 `RegisterMessage` 方法,或者使用 `GetClickCount` 函数获取按钮点击次数。

例如,使用 GetClickCount 函数获取按钮点击次数:

#include "HiEasyX.h"

int main()
{
	hiex::Window wnd(300, 200);
	hiex::SysButton btn(wnd.GetHandle(), 100, 85, 100, 30, L"Button");

	// 窗口存在时,程序才保持运行
	while (wnd.isAlive())
	{
		// 如果按钮的点击次数不为 0,说明用户已点击按钮
		if (btn.GetClickCount())
		{
			// 处理点击消息
		}

		Sleep(50);
	}

	return 0;
}

或者注册点击消息:

#include "HiEasyX.h"

void OnBtn()
{
	// 在此处理点击消息
}

int main()
{
	hiex::Window wnd(300, 200);
	hiex::SysButton btn(wnd.GetHandle(), 100, 85, 100, 30, L"Button");

	btn.RegisterMessage(OnBtn);	// 注册点击消息

	hiex::init_end();
	return 0;
}

其余控件的使用方式大同小异,可以看看相应的头文件介绍。此处再举一例,创建编辑框。

像这样:

#include "HiEasyX.h"

int main()
{
	hiex::Window wnd(300, 200);
	hiex::SysEdit edit;	// 编辑框

	// 预设样式为支持多行输入,因为有的控件样式必须在创建之前就指定
	edit.PreSetStyle(true, false, true, true, true, true);
	edit.Create(wnd.GetHandle(), 10, 10, 280, 180, L"Multiline Edit Box\r\n\r\nEdit here");

	// 设置编辑框字体
	edit.SetFont(24, 0, L"微软雅黑");

	hiex::init_end();
	return 0;
}

加上按钮,获取文本:

#include "HiEasyX.h"

int main()
{
	hiex::Window wnd(300, 200);

	// 编辑框
	hiex::SysEdit edit;
	edit.PreSetStyle(true, false, true, true);
	edit.Create(wnd.GetHandle(), 10, 10, 280, 140, L"Type here~");
	edit.SetFont(24, 0, L"微软雅黑");

	// 按钮
	hiex::SysButton btn;
	btn.Create(wnd.GetHandle(), 190, 160, 100, 30, L"Submit");

	while (wnd.isAlive())
	{
		// 按下按钮时,弹窗显示输入的文本
		if (btn.isClicked())
			MessageBox(wnd.GetHandle(), edit.GetText().c_str(), L"Submit", MB_OK);
		Sleep(50);
	}

	return 0;
}

此外,还可以设置文字颜色、背景颜色、密码框、左中右对齐方式、仅数字输入、禁用控件,等等,不一一列举。

下面这个示例用到的控件比较全面,可以帮您更深入地了解 HiSysGUI:

此示例的 源代码
Github 中的 完整教程

场景、图层、画布和透明通道

HiEasyX 的绘图模块名为 HiCanvas,封装了场景、图层和画布,且都支持透明通道。篇幅所限,这里就仅给出一个使用 HiCanvas 的示例:

示例中,透明小球在窗口中运动,在碰到边界时反弹。

此示例的 源代码

结语

HiEasyX 还有一些实用但零碎的功能,在此恐不能详述。

感谢您能看到这里,如有任何问题可以留言。

评论 (22) -

  • 所以说我可以用这个库绘制透明图片了吗,说实话用putimage绘制会将透明背景渲染成黑色,弄得我得另外写个函数,但这个函数坐标参数又不能为负
    • 你好,我是 HiEasyX 的开发者 Alan-CRL,HiEasyX 已于近期更新到了 Ver0.3.5r1 版本,新增 hiex::TransparentImage 函数:可绘制带有透明通道的图像(可叠加透明度绘制,可只绘制图像指定区域,可拉伸图像绘制),快去更新试试吧!详见 https://github.com/zouhuidong/HiEasyX/releases
  • 怎么把编辑框里输入的文本储存到字符数组
    • 【1】例如,你这样创建了一个文本框:hiex::SysEdit edit;
      【2】那么,你可以这样获得它的文本内容(wstring 类型的):std::wstring wstr = edit.GetText();
      【3】如果想要将 wstring 类型的字符串数据存储到数组中,可以使用 lstrcpy 等函数,可以自行搜索。
  • 请问一下怎么绘制图片呀,我的总是显示不出来

            IMAGE logo11 = canvas_main.Load_Image_Alpha(_T("sprites/logp_144px.png"));
            canvas_main.PutImageIn_Alpha(0, 0, &logo11);
    • 你这个代码太少了,看不出来问题,你可以加我 QQ 1442701429 发给我代码,或者在 github 提交 issue 也可以。
      • 感谢,我已经查出来问题了,在其他很远的地方一行代码导致的,但是我并没有理解为什么
  • 可以出个简单的示例说明一下ProgressCtrl控件怎么使用吗,我看不懂官方文档
    • ProgressCtrl 属于自绘控件模块,目前没有开发完成,建议先不要使用。

添加评论