• 【C++】基于Easyx的UI库


    简介

    实现语言:C++

    项目名称:UI.h

    项目类型:控制台应用

    项目版本:2022-8-14

    开发环境:Visual Studio 2022 Community 17.3.0  &  Easyx 2022-6-10


    项目介绍

    前段时间我研究了C#,就想把C#窗体应用中的控件搬到C++上,于是就有了这篇文章。


    更新历史

    • 2022-8-14 优化已有的控件,将init()初始化函数改为构造函数;增加复选框(Checked List Box)
    • 2022-8-13 增加单选框(Check Box),优化按钮(Button)和文本(Label)
    • 2022-8-7 完成按钮(Button)和文本(Label)
    • 2022-8-5 创建UI.h

    代码

    这个代码只要是懂一点Easyx的应该都看得懂(因为Easyx本身并不难),并且我还在里面加了一些注释,应该大部分人阅读起来都是没问题的。

    UI.h

    1. /***************************************************************
    2. * *
    3. * UI.h *
    4. * UI Library for C++ Base on Easyx. *
    5. * Version : 2022-8-14 *
    6. * https://easyx.cn *
    7. * https://blog.csdn.net/qq_43546083?spm=1000.2115.3001.5343 *
    8. * *
    9. ***************************************************************/
    10. #pragma once
    11. #if __has_include()
    12. #include
    13. namespace UI {
    14. /**** 按钮 ****/
    15. class Button {
    16. public:
    17. /**** 控件左上角的x坐标 ****/
    18. int x = -1,
    19. /**** 控件左上角的y坐标 ****/
    20. y = -1;
    21. /**** 控件的宽度 ****/
    22. int width = -1,
    23. /**** 控件的高度 ****/
    24. height = -1;
    25. /**** 控件所显示的文本 ****/
    26. LPCTSTR text = L"";
    27. /**** 控件显示的文本高度 ****/
    28. int size = 16;
    29. /**** 控件是否可见,可见为true,否则为false ****/
    30. bool visible = false;
    31. /**** 构造函数,初始化控件左上角的坐标、宽度、高度、显示的文本与文本的高度(默认为16) ****/
    32. Button(int x, int y, int width, int height, LPCTSTR text, int size = 16) {
    33. this->x = x;
    34. this->y = y;
    35. this->width = width;
    36. this->height = height;
    37. this->text = text;
    38. this->size = size;
    39. return;
    40. }
    41. /**** 显示控件,成功返回true,出现异常返回false ****/
    42. bool show() {
    43. if (visible) {
    44. //当前控件可见
    45. return false;
    46. }
    47. int temp = getbkmode();
    48. setbkmode(TRANSPARENT);
    49. LOGFONT* temp1 = new LOGFONT();
    50. LOGFONT* temp2 = new LOGFONT();
    51. gettextstyle(temp1);
    52. gettextstyle(temp2);
    53. temp2->lfHeight = size;
    54. settextstyle(temp2);
    55. if (width - textwidth(text) <= 0 || height - textheight(text) <= 0) {
    56. //文字过大
    57. settextstyle(temp1);
    58. return false;
    59. }
    60. fillrectangle(x, y, x + width - 1, y + height - 1);
    61. outtextxy(x + (width - textwidth(text)) / 2, y + (height - textheight(text)) / 2, text);
    62. settextstyle(temp1);
    63. setbkmode(temp);
    64. delete temp1;
    65. delete temp2;
    66. visible = true;
    67. return true;
    68. }
    69. /**** 隐藏控件 ****/
    70. void hide() {
    71. COLORREF temp = getfillcolor();
    72. setfillcolor(getbkcolor());
    73. solidrectangle(x, y, x + width - 1, y + height - 1);
    74. setfillcolor(temp);
    75. visible = false;
    76. return;
    77. }
    78. /**** 判断按钮是否被按下,被按下返回true,没有按下或出现异常返回false ****/
    79. bool click(ExMessage m) {
    80. if ((x == -1 || y == -1 || width == -1 || height == -1) || !visible) {
    81. //未初始化控件或当前控件不可见
    82. return false;
    83. }
    84. return m.message == WM_LBUTTONUP && (m.x >= x && m.x <= x + width - 1) && (m.y >= y && m.y <= y + height - 1);
    85. }
    86. /**** 刷新插件(显示状态下) ****/
    87. void reload() {
    88. visible = false;
    89. show();
    90. }
    91. };
    92. /**** 文本(该控件为自动调整大小) ****/
    93. class Label {
    94. private:
    95. int width, height;
    96. public:
    97. /**** 控件左上角的x坐标 ****/
    98. int x = -1,
    99. /**** 控件左上角的y坐标 ****/
    100. y = -1;
    101. /**** 控件所显示的文本 ****/
    102. LPCTSTR text = L"";
    103. /**** 控件显示的文本高度 ****/
    104. int size = 16;
    105. /**** 控件是否可见,可见为true,否则为false ****/
    106. bool visible = false;
    107. /**** 构造函数,初始化控件左上角的坐标、显示的文本与文本的高度(默认为16) ****/
    108. Label(int x, int y, LPCTSTR text, int size = 16) {
    109. this->x = x;
    110. this->y = y;
    111. this->text = text;
    112. this->size = size;
    113. width = 0;
    114. height = 0;
    115. return;
    116. }
    117. /**** 显示控件,成功返回true,出现异常返回false ****/
    118. bool show() {
    119. if (visible) {
    120. //当前控件可见
    121. return false;
    122. }
    123. int temp = getbkmode();
    124. setbkmode(TRANSPARENT);
    125. LOGFONT* temp1 = new LOGFONT();
    126. LOGFONT* temp2 = new LOGFONT();
    127. gettextstyle(temp1);
    128. gettextstyle(temp2);
    129. temp2->lfHeight = size;
    130. settextstyle(temp2);
    131. outtextxy(x, y, text);
    132. width = textwidth(text);
    133. height = textheight(text);
    134. settextstyle(temp1);
    135. delete temp1;
    136. delete temp2;
    137. setbkmode(temp);
    138. visible = true;
    139. return true;
    140. }
    141. /**** 隐藏控件 ****/
    142. void hide() {
    143. COLORREF temp = getfillcolor();
    144. setfillcolor(getbkcolor());
    145. solidrectangle(x, y, x + width - 1, y + height - 1);
    146. setfillcolor(temp);
    147. visible = false;
    148. return;
    149. }
    150. /**** 刷新插件(显示状态下) ****/
    151. void reload() {
    152. visible = false;
    153. show();
    154. }
    155. };
    156. /**** 勾选框(该控件为自动大小) ****/
    157. class CheckBox {
    158. private:
    159. //勾选框=按钮+文本
    160. Button* button;
    161. Label* label;
    162. public:
    163. /**** 控件左上角的x坐标 ****/
    164. int x = -1,
    165. /**** 控件左上角的y坐标 ****/
    166. y = -1;
    167. /**** 控件所显示的文本 ****/
    168. LPCTSTR text = L"";
    169. /**** 是否已被勾选 ****/
    170. bool state = false;
    171. /**** 构造函数,初始化控件左上角的坐标与显示的文本 ****/
    172. CheckBox(int x, int y, LPCTSTR text) {
    173. this->x = x;
    174. this->y = y;
    175. this->text = text;
    176. button = new Button(x, y, 18, 18, L"");
    177. label = new Label(x + 20, y, text, 18);
    178. return;
    179. }
    180. /**** 显示控件,成功返回true,出现异常返回false ****/
    181. bool show() {
    182. if (!button->show() || !label->show()) {
    183. hide();
    184. return false;
    185. }
    186. return true;
    187. }
    188. /**** 隐藏控件 ****/
    189. void hide() {
    190. button->hide();
    191. label->hide();
    192. return;
    193. }
    194. /**** 控件是否被勾选,按下则切换效果,出现异常返回false ****/
    195. bool check(ExMessage m) {
    196. if ((button->x == -1 || button->y == -1 || button->width == -1 || button->height == -1) || (label->x == -1 || label->y == -1) || !(button->visible && label->visible)) {
    197. //未初始化控件或当前控件不可见
    198. return false;
    199. }
    200. if (button->click(m)) {
    201. state = !state;
    202. button->text = state ? L"√" : L"";
    203. reload();
    204. }
    205. return true;
    206. }
    207. /**** 刷新插件(显示状态下) ****/
    208. void reload() {
    209. button->reload();
    210. label->reload();
    211. }
    212. ~CheckBox()
    213. {
    214. delete button;
    215. delete label;
    216. }
    217. };
    218. /**** 复式勾选框(最多15项,该控件为自动大小) ****/
    219. class CheckedListBox {
    220. public:
    221. //复式勾选框=多个勾选框
    222. CheckBox* checkbox[15] = { nullptr };
    223. /**** 项数 ****/
    224. int num = 0;
    225. /**** 构造函数,初始化控件左上角的坐标与显示的文本 ****/
    226. CheckedListBox(int x, int y, int num, LPCTSTR text[]) {
    227. if (num > 15) {
    228. MessageBox(0, L"项数过多!", L"UI.h", MB_OK | MB_ICONSTOP);
    229. return;
    230. }
    231. this->num = num;
    232. for (int i = 0; i < num; i++) {
    233. checkbox[i] = new CheckBox(x + 5, y + i * 20, text[i]);
    234. }
    235. }
    236. CheckedListBox(int num, CheckBox checkbox[]) {
    237. if (num > 15) {
    238. MessageBox(0, L"项数过多!", L"UI.h", MB_OK | MB_ICONSTOP);
    239. return;
    240. }
    241. this->num = num;
    242. for (int i = 0; i < num; i++) {
    243. this->checkbox[i] = &checkbox[i];
    244. }
    245. }
    246. /**** 显示控件,成功返回true,出现异常返回false ****/
    247. bool show() {
    248. int maxlen = -1;
    249. for (int i = 0; i < num; i++) {
    250. maxlen = max(maxlen, textwidth(checkbox[i]->text));
    251. if (!checkbox[i]->show()) {
    252. for (int j = 0; j < i; j++) {
    253. checkbox[j]->hide();
    254. return false;
    255. }
    256. }
    257. }
    258. rectangle(checkbox[0]->x - 5, checkbox[0]->y - 5, checkbox[0]->x + maxlen + 25, checkbox[0]->y + num * 20 + 3);
    259. return true;
    260. }
    261. /**** 隐藏控件 ****/
    262. void hide() {
    263. for (int i = 0; i < num; i++) checkbox[i]->hide();
    264. }
    265. /**** 控件是否被勾选,按下则切换效果,出现异常返回false ****/
    266. bool check(ExMessage m) {
    267. for (int i = 0; i < num; i++) {
    268. if (!checkbox[i]->check(m))return false;
    269. }
    270. return true;
    271. }
    272. /**** 刷新插件(显示状态下) ****/
    273. void relad() {
    274. for (int i = 0; i < num; i++)checkbox[i]->reload();
    275. return;
    276. }
    277. ~CheckedListBox()
    278. {
    279. delete[] &checkbox;
    280. }
    281. };
    282. }
    283. #else
    284. #error 请先安装Easyx库,下载地址:https://easyx.cn
    285. #endif

    在这里,为了让大家简单了解一下这些类使用的方法,给了一段参考代码:

    text.cpp

    1. #include "UI.h"
    2. int main() {
    3. initgraph(640,480);
    4. settextcolor(BLACK);
    5. setbkcolor(RGB(240, 240, 240));
    6. setlinecolor(BLACK);
    7. setfillcolor(RGB(230, 230, 230));
    8. cleardevice();
    9. LPCTSTR text[3] = { L"这是",L"一个",L"Checked List Box" };
    10. UI::Button button(5, 5, 200, 60, L"这是一个Button");
    11. UI::CheckBox checkbox(5, 70, L"这是一个Check Box");
    12. UI::CheckedListBox checkedlistbox(5, 155, 3, text);
    13. UI::Label label1(5, 95, L"这是一个Label"), label2(5, 115, L"这是一个彩蛋", 32);
    14. button.show();
    15. checkbox.show();
    16. checkedlistbox.show();
    17. label1.show();
    18. ExMessage m;
    19. while (true) {
    20. m = getmessage(EM_MOUSE);
    21. checkbox.check(m);
    22. checkedlistbox.check(m);
    23. if (checkbox.state == true)label2.show();
    24. else label2.hide();
    25. if (button.click(m)){
    26. if (label1.visible)label1.hide();
    27. else label1.show();
    28. }
    29. }
    30. return 0;
    31. }

     运行效果:

    UI.h 2022-8-14版本 效果


    好了,今天就到这里了。如果大家有对这篇文章有不懂或有建议可以告诉我。拜拜!

  • 相关阅读:
    刷题错题录2-向上取整、三角形条件、字符串拼接匹配、三数排序思路
    【华为机试真题 JAVA】5键键盘的输出-100
    CEC2013(MATLAB):狐猴优化算法(Lemurs Optimizer,LO)求解CEC2013(提供MATLAB代码及参考文献)
    【云原生】Secret敏感信息存储
    SD中的VAE,你不能不懂
    MCS:离散随机变量——Poisson分布
    含文档+PPT+源码等]精品基于Uniapp+Springboot实现的Android的学习生活交流APP[包运行成功]Nodejs毕业设计计算机项目源码
    Linux基本指令笔记
    C基础练习(学生管理系统)
    题目 1065: 二级C语言-最小绝对值
  • 原文地址:https://blog.csdn.net/qq_43546083/article/details/126322083