xuiWidgetCreate / CreateTyped / Destroy 管理控件生命周期,类型系统支持继承与自定义控件注册。
XUI 控件以树形结构组织:
• 根控件:由 context 隐式管理
• 父子关系:AddChild / RemoveChild / InsertChild
• 类型系统:每种控件有 xui_widget_type,支持继承链
• 生命周期:Create → 使用 → Destroy(父销毁时子自动销毁)
| 函数 | 说明 |
|---|---|
int xuiWidgetCreate(xui_context pContext, xui_widget* ppWidget) | 创建基础控件 |
int xuiWidgetCreateTyped(xui_context pContext, xui_widget_type pType, xui_widget* ppWidget, const void* pCreateData) | 创建指定类型控件 |
void xuiWidgetDestroy(xui_widget pWidget) | 销毁控件(含子树) |
xui_context xuiWidgetGetContext(xui_widget pWidget) | 获取所属上下文 |
xui_widget_type xuiWidgetGetType(xui_widget pWidget) | 获取控件类型 |
int xuiWidgetIsType(xui_widget pWidget, xui_widget_type pType) | 类型检查(含继承) |
int xuiWidgetRegisterType(xui_context pContext, xui_widget_type* ppType, const xui_widget_type_desc_t* pDesc) | 注册自定义类型 |
xui_widget_type xuiWidgetFindType(xui_context pContext, const char* sName) | 按名称查找类型 |
gcc -O2 -I. -o ch123.exe ch123_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch123.exe
// 创建面板容器
xui_widget pPanel;
xuiWidgetCreateTyped(pCtx,
xuiPanelGetType(), &pPanel, &panelDesc);
// 创建子控件:标签 + 按钮
xui_widget pLabel, pBtn;
xuiWidgetCreateTyped(pCtx,
xuiLabelGetType(), &pLabel, &labelDesc);
xuiWidgetCreateTyped(pCtx,
xuiButtonGetType(), &pBtn, &btnDesc);
// 组装树:Panel → Label, Button
xuiWidgetAddChild(pPanel, pLabel);
xuiWidgetAddChild(pPanel, pBtn);
// 类型检查
if (xuiWidgetIsType(pBtn,
xuiWidgetGetBaseType())) {
// Button 继承自 Widget 基类
}
// 销毁面板(子控件自动销毁)
xuiWidgetDestroy(pPanel);将以下代码保存为 ch123_main.c,编译后运行即可看到控件树的创建与销毁:
#include "xge.h"
#include "xui.h"
#include <stdio.h>
static xui_context g_pCtx;
static xui_widget g_pPanel;
static int g_nFrame = 0;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
xuiUpdate(g_pCtx, xgeGetDelta());
xuiLayout(g_pCtx);
xuiRender(g_pCtx, NULL, NULL, 0);
// 第 180 帧时销毁面板(子控件自动释放)
if (++g_nFrame == 180) {
printf("Destroying panel tree...\n");
xuiWidgetDestroy(g_pPanel);
g_pPanel = NULL;
}
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch123 - Widget Tree";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xuiCreate(&g_pCtx);
extern const xui_proxy_t tXgeProxy;
xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
xuiSetViewportSize(g_pCtx, 800, 600);
// 创建面板 + 标签 + 按钮
xuiWidgetCreate(g_pCtx, &g_pPanel);
xui_widget pLabel, pBtn;
xuiWidgetCreate(g_pCtx, &pLabel);
xuiWidgetCreate(g_pCtx, &pBtn);
// 组装控件树
xuiWidgetAddChild(g_pPanel, pLabel);
xuiWidgetAddChild(g_pPanel, pBtn);
// 类型检查
printf("Label is Widget base: %d\n",
xuiWidgetIsType(pLabel,
xuiWidgetGetBaseType()));
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}