EasyX实现按钮效果

利用EasyX绘制按钮,实现按钮的鼠标悬浮、按下、弹起效果。

效果展示

实现原理

在EasyX现有基础上,实现了widget窗口元素,并用C语言的方式,从widget派生出button(按钮)、label(文本框)等窗口控件,利用container窗口容器进行管理,并封装了鼠标和键盘按键,实现了简易的消息派发机制,使得程序逻辑只需关心按钮被按下的消息事件,而无需做鼠标坐标和图形区域判断。

  • 消息机制的封装(部分代码)
/*********************
* 框架 - 消息派发
**********************/#define TASK_QUEUE_SIZE 10typedef struct _tTaskInfo {int type;void* data;
} TaskInfo;typedef struct _tTaskQueue {TaskInfo* data;int front;int rear;int capacity;
} TaskQueue;//创建事件
typedef void* (*CallCreate)();
//销毁事件
typedef void (*CallDestroy)(void* context);
//键盘事件
typedef int (*CallKeyBoard)(int key, TaskQueue* queue, void* context);
//鼠标事件
typedef int (*CallMouse)(MOUSEMSG* msg, TaskQueue* queue, void* context);
//任务事件
typedef int (*CallTask)(TaskQueue* queue, void* context);
//空闲事件
typedef int (*CallIdle)(void* context);//运行环境
typedef struct _tRuntime {void* context;CallCreate create;CallDestroy destroy;CallKeyBoard keyboard;CallMouse mouse;CallTask task;CallIdle idle;
} Runtime;TaskQueue* createTaskQueue(int capacity) {TaskQueue* queue = (TaskQueue*)malloc(sizeof(TaskQueue));memset(queue, 0, sizeof(TaskQueue));queue->capacity = capacity;queue->data = (TaskInfo*)malloc(sizeof(queue->data[0]) * capacity);memset(queue->data, 0, sizeof(sizeof(queue->data[0]) * capacity));return queue;
}void destroyTaskQueue(TaskQueue* queue) {if (queue) {free(queue->data);free(queue);}
}int emptyTaskQueue(TaskQueue* queue) {return (queue && queue->front == queue->rear);
}int fullTaskQueue(TaskQueue* queue) {return (queue && queue->front == ((queue->rear + 1) % queue->capacity));
}void enqueueTaskQueue(TaskQueue* queue, int type, void* data) {if (queue) {if (!fullTaskQueue(queue)) {int pos = queue->rear;TaskInfo* task = &queue->data[pos];queue->rear = (pos + 1) % queue->capacity;task->type = type;task->data = data;}}
}void dequeueTaskQueue(TaskQueue* queue, TaskInfo* task) {if (queue) {if (!emptyTaskQueue(queue)) {int pos = queue->front;queue->front = (pos + 1) % queue->capacity;*task = queue->data[pos];}}
}Runtime createRuntime(CallCreate create, CallDestroy destroy, CallKeyBoard keyboard, CallMouse mouse, CallTask task, CallIdle idle) {Runtime runtime = { NULL, create, destroy, keyboard, mouse, task, idle };return runtime;
}int dispatchMessage(Runtime* runtime) {void* context = runtime->create();TaskQueue* queue = createTaskQueue(TASK_QUEUE_SIZE);int ret = 0;FlushMouseMsgBuffer();while (1) {if (runtime->keyboard && _kbhit()) {int key = _getch();ret = runtime->keyboard(key, queue, context);if (ret != 0) {break;}} else if (runtime->mouse && MouseHit()) {MOUSEMSG msg = GetMouseMsg();ret = runtime->mouse(&msg, queue, context);if (ret != 0) {break;}} else if (runtime->task && !emptyTaskQueue(queue)) {ret = runtime->task(queue, context);if (ret != 0) {break;}} else if (runtime->idle) {ret = runtime->idle(context);if (ret != 0) {break;}}}destroyTaskQueue(queue);runtime->destroy(context);return ret;
}
  • 窗体控件的封装(部分代码)
/*********************
* 框架 - 窗体控件
**********************/#define STYLE_BK_COLOR 0xFFFFFF
#define STYLE_WIDGET_BUTTON_COLOR_LINE 0x808080
#define STYLE_WIDGET_BUTTON_COLOR_FILL 0x808080
#define STYLE_WIDGET_BUTTON_COLOR_TEXT 0xFFFFFF
#define STYLE_WIDGET_BUTTON_COLOR_FOCUS 0x404040
#define STYLE_WIDGET_BUTTON_SHADOW_COLOR 0xC0C0C0
#define STYLE_WIDGET_BUTTON_SHADOW_OFFSET_X 3
#define STYLE_WIDGET_BUTTON_SHADOW_OFFSET_Y 3
#define STYLE_WIDGET_BUTTON_FONT_HEIGHT 16enum {WIDGET_TYPE_NULL,WIDGET_TYPE_CONTAINER,WIDGET_TYPE_BUTTON,WIDGET_TYPE_LABEL,
};enum {WIDGET_LABEL_ALIGN_LEFT,WIDGET_LABEL_ALIGN_CENTER,
};enum {WIDGET_FLAG_NULL = 0,WIDGET_FLAG_FOCUS = 1 << 0,WIDGET_FLAG_CLICK = 1 << 1
};typedef struct _tPoint {int x;int y;
} Point;typedef struct _tRect {Point point;int width;int height;
} Rect;typedef struct _tWidget {int type;int id;int flag;Rect rect;
} Widget;typedef struct _tWidgetList {Widget** data;int size;int capacity;
} WidgetList;typedef struct _tWidgetContainer {Widget widget;WidgetList* list;
} WidgetContainer;typedef struct _tWidgetButton {Widget widget;wchar_t* text;
} WidgetButton;typedef struct _tWidgetLabel {Widget widget;int font_height;int align;COLORREF fill_color;COLORREF line_color;COLORREF text_color;COLORREF focus_color;wchar_t* text;
} WidgetLabel;wchar_t* convertCharToWchar(const char* input);
WidgetList* createWidgetList(int capacity);
void destroyWidgetList(WidgetList* list);
void appendWidgetList(WidgetList* list, Widget* widget);
WidgetContainer* createWidgetContainer(int id, int x, int y, int width, int height);
void appendWidgetContainer(WidgetContainer* container, Widget* widget);
void destroyWidgetContainer(WidgetContainer* container);
WidgetButton* createWidgetButton(int id, int x, int y, int width, int height, const char* text);
void destroyWidgetButton(WidgetButton* button);
void drawWidgetButton(WidgetButton* button);
WidgetLabel* createWidgetLabel(int id, int x, int y, int width, int height, int font_height, COLORREF fill_color, COLORREF line_color, COLORREF text_color, COLORREF focus_color, int align, const char* text);
void destroyWidgetLabel(WidgetLabel* label);
void drawWidgetLabel(WidgetLabel* label);
void drawWidgetContainer(WidgetContainer* container);
int hitWidget(Widget* widget, MOUSEMSG* msg);
Widget* hitWidgetContainer(WidgetContainer* container, MOUSEMSG* msg);wchar_t* convertCharToWchar(const char* input) {int input_len = (int)strlen(input);int output_len = MultiByteToWideChar(CP_ACP, 0, input, input_len, NULL, 0);wchar_t* output = new wchar_t[output_len + 1];MultiByteToWideChar(CP_ACP, 0, input, input_len, output, output_len);output[output_len] = '\0';return output;
}char* convertWcharToChar(const wchar_t* input) {int nLen = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL);if (nLen == 0) {return NULL;}char* output = new char[nLen];WideCharToMultiByte(CP_ACP, 0, input, -1, output, nLen, NULL, NULL);return output;
}char* inputEditBox(const char* title, const char* prompt, const char* defaul, int width, int height) {wchar_t buffer[1024] = { 0 };wchar_t* _title = title ? convertCharToWchar(title) : NULL;wchar_t* _prompt = prompt ? convertCharToWchar(prompt) : NULL;wchar_t* _defaul = defaul ? convertCharToWchar(defaul) : NULL;if (InputBox(buffer, sizeof(buffer) / sizeof(buffer[0]), _prompt, _title, _defaul, width, height)) {return convertWcharToChar(buffer);}return NULL;
}WidgetList* createWidgetList(int capacity) {WidgetList* list = (WidgetList*)malloc(sizeof(WidgetList));memset(list, 0, sizeof(WidgetList));list->capacity = capacity;list->data = (Widget**)malloc(sizeof(Widget*) * list->capacity);memset(list->data, 0, sizeof(Widget*) * list->capacity);return list;
}void destroyWidgetList(WidgetList* list) {if (list) {for (int index = 0; index < list->size; ++index) {Widget* widget = list->data[index];switch (widget->type) {case WIDGET_TYPE_CONTAINER:destroyWidgetContainer((WidgetContainer*)widget);break;case WIDGET_TYPE_BUTTON:destroyWidgetButton((WidgetButton*)widget);break;case WIDGET_TYPE_LABEL:destroyWidgetLabel((WidgetLabel*)widget);break;}}free(list);}
}
  • 功能实现(部分)
int main() {Runtime runtime = createRuntime((CallCreate)callEditorCreate, \(CallDestroy)callEditorDestroy, \(CallKeyBoard)callEditorKeyBoard, \(CallMouse)callEditorMouse, \(CallTask)callEditorTask, \(CallIdle)callEditorIdle);dispatchMessage(&runtime);return 0;
}
  • 利用实现的简易框架实现的一个文本编辑器效果

源码下载

链接:程序源码下载链接
提取码:1111

EasyX实现按钮效果相关推荐

  1. c/c++游戏编程之用Easyx封装按钮

    c/c++游戏编程之Easyx图形库基础(一) EasyX基础 c/c++游戏编程之Easyx图形库基础(二) 绘制图片 c/c++游戏编程之Easyx图形库基础(三) 用Easyx封装按钮 文章目录 ...

  2. php手绘功能,基于纯CSS3的6种手绘涂鸦按钮效果

    简要教程 这是一组非常有趣的纯CSS3手绘风格卡通按钮设计效果.这组手绘风格按钮共6种不同的效果,它们以手绘涂鸦的方式,以不同的按钮边框线条宽度和虚线来构成按钮,效果非常不错. 使用方法 HTML结构 ...

  3. php3d按钮,CSS实现3D按钮效果

    这次给大家带来CSS实现3D按钮效果,CSS实现3D按钮效果的注意事项有哪些,下面就是实战案例,一起来看一下. css巧妙利用了box-shadow来实现3D物体的立体感,当按钮按下的时候再去修改bo ...

  4. 使用VC++2015 实现XP按钮效果

    VC++2015,新建一个对话框工程: 添加4个按钮: 添加对话框类成员变量: 把变量类型由CButton改为CXPButton:为变量起一个名字:一般为m_xxxx: 运行一下:XP按钮效果有了: ...

  5. 山寨“饿了么”应用中添加菜品数量按钮效果

    山寨"饿了么"应用中添加菜品数量按钮效果 本人视频教程系类   iOS中CALayer的使用 最终效果: 山寨源头: 源码:(此源码解决了重用问题,可以放心的放在cell中使用) ...

  6. html涟漪动画效果,CSS+JS实现水滴涟漪动画按钮效果的示例代码

    代码如下所示: Document .btn{ display: block; width: 300px; height: 100px; margin: 50px; outline: 0; overfl ...

  7. 【第3版emWin教程】第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

    教程不断更新中:链接 第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 本章节为大家讲解按钮控件自定义回调函数,通过其回调函数就可以实现各种按钮效果.这方面的 ...

  8. php3d按钮,css3实现3D按钮效果的文章推荐

    使用css3代码来制作3D按钮效果,这是一个系列的3D按钮制作效果,制作方法是老套(万变不离其中),但其中色彩的调各非常不错,因为很多效果在PS中制作是容易,特别对于设计师来说更容易,但对于一名cod ...

  9. QT程序按钮效果制作

    QT程序按钮效果制作 QT Creator下,建空GUI项目,添加一个Widget,然后设计界面: 最下面的是Widget,上一层放一个frame,用lineEdit,pushButton排列成这效果 ...

  10. uniapp 仿支付宝首页流光按钮效果 流光动画实现

    支付宝流光按钮效果 效果动效: 按钮从小到大并出现弹跳效果 流光自左向右滑过 最终实现效果如下图所示: 代码如下: <view class="ceshi">12点开抢 ...

最新文章

  1. 在普通PC上安装XENSERVER 6.2
  2. 还能开发搜索引擎吗?
  3. Android P(3)---Android P 功能和 API
  4. ORCALE SYNONYM SEQUENCE
  5. 2019春运大幕即将开启 西安动车列车员整装迎春运
  6. 如何在PowerShell中连接字符串和变量?
  7. oracle das系统,分布式声波传感系统DAS
  8. time(null)的用法
  9. ⟅UNIX网络编程⟆⦔目录
  10. 202206-2 寻宝!大冒险! CCF认证真题
  11. npm批量更新package.json中的依赖, 升级 npm 全局依赖
  12. jQuery幻灯片插件Skippr
  13. Win系统 - 两个固态硬盘能不能分配到同一个分区?
  14. Win11如何关闭自动更新?Win11更新服务关闭教程
  15. DKN: Deep Knowledge-Aware Network for News Recommendation简析
  16. Qt利用QGraphicsScene编写Word排版工具导出PDF
  17. Windows 7 中文版命令行如何修改字符编码为UTF-8?
  18. 星系炸弹 在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。 每个炸弹都可以设定多少天之后爆炸。 比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16
  19. Jmeter阶梯式压测与普通压测区别
  20. Shell脚本是什么?

热门文章

  1. 如何解决“配置系统未能初始化“ 错误的解决方案?
  2. sin的傅里叶变换公式_傅里叶变换的由来及复数下的傅里叶变换公式证明
  3. Linux驱动认知简明导论③ —— 修改树莓派引脚文件pin4Driver.c操作IO口
  4. m3u8手机批量转码_M3U8批量转换app-M3U8批量转换MP4软件下载v1.0 安卓版-西西软件下载...
  5. NB-IoT未来发展,主要是靠什么驱动的?
  6. Mujoco雅克比-逆运动-传感器
  7. geek卸载界的天花板
  8. [算法]px4位置估计-inav (2017/10/26更新)
  9. JNi调用过程(转载)
  10. 腾讯QQ空间登录的方法实现方式与验证过程分析