C语言UI框架

在 C 语言中,结构体的成员在内存中是按顺序排列的。
规则: 如果一个结构体的第一个成员是另一个结构体,那么这两个结构体的起始内存地址是完全相同的

第一步:定义父类 (通用属性)

cpp 复制代码
typedef struct {
    int16_t x, y, w, h; // 所有控件都有坐标
    uint8_t type;       // 身份证:用来识别它是按钮还是标签
    void (*event_cb)(void* obj, int msg);//不同的对象使用不同触发函数
} UG_OBJECT;

第二步:定义子类 (特有属性)

cpp 复制代码
typedef struct {
    UG_OBJECT base;     // <--- 必须放在第一个!这是"继承"的关键
    char* text;         // 按钮才有的文字
    uint16_t color;     // 按钮才有的颜色
} UG_BUTTON;

第三步:向上转型 (Upcasting) ------ 子类变父类

这是最安全的操作,通常用于把不同类型的控件塞进同一个数组里管理。

cpp 复制代码
UG_BUTTON myBtn;
myBtn.base.x = 10;
myBtn.text = "OK";

// 此时,你可以把 &myBtn 仅仅看作一个普通 Object
UG_OBJECT* obj_ptr = (UG_OBJECT*)&myBtn; 

// 通过通用指针访问通用属性,完全合法
obj_ptr->x = 20; // 实际上修改了 myBtn.base.x

第四步:向下转型 (Downcasting) ------ 父类变子类

这是 GUI_HandleInput 函数里做的事情。这需要冒一点风险,所以必须先检查 type

cpp 复制代码
void GUI_HandleInput(UG_OBJECT* obj) {
    // 此时 obj 可能指向一个按钮,也可能指向一个文本框。
    // 编译器只知道它是一个 UG_OBJECT,只看得到 x, y, w, h。

    // 1. 查户口:你到底是谁?
    if (obj->type == TYPE_BUTTON) {
        
        // 2. 只有确认它是按钮,才能把它强转回按钮指针
        // 这就是"指针强转",告诉编译器:"把视窗扩大,我要访问后面的 text 和 color"
        UG_BUTTON* btn = (UG_BUTTON*)obj;
        
        // 3. 现在可以访问子类特有的成员了
        printf("Button Text: %s", btn->text); 
        
        // 注意:如果 obj 其实是一个 Label,而你强转成 Button,
        // 访问 btn->text 就会导致内存越界 (访问了 Label 不存在的区域或错误数据)。
    }
}
相关推荐
java干货4 分钟前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法
_F_y4 分钟前
C语言重点知识总结(含KMP详细讲解)
c语言·开发语言
毕设源码-郭学长6 分钟前
【开题答辩全过程】以 基于python的二手房数据分析与可视化为例,包含答辩的问题和答案
开发语言·python·数据分析
无小道29 分钟前
Qt——常用控件
开发语言·qt
aini_lovee1 小时前
MATLAB基于小波技术的图像融合实现
开发语言·人工智能·matlab
郝学胜-神的一滴1 小时前
深入解析C/S模型下的TCP通信流程:从握手到挥手的技术之旅
linux·服务器·c语言·网络·网络协议·tcp/ip
R1nG8631 小时前
多线程安全设计 CANN Runtime关键数据结构的锁优化
开发语言·cann
初次见面我叫泰隆1 小时前
Qt——5、Qt系统相关
开发语言·qt·客户端开发
亓才孓1 小时前
[Class的应用]获取类的信息
java·开发语言
开开心心就好1 小时前
AI人声伴奏分离工具,离线提取伴奏K歌用
java·linux·开发语言·网络·人工智能·电脑·blender