# win32_gui **Repository Path**: style7en/win32_gui ## Basic Information - **Project Name**: win32_gui - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-13 - **Last Updated**: 2026-06-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Win32 GUI Library — Header-Only 版本 **单头文件 · 单窗口 · 纯 Win32 API 实现** 轻量级 Windows GUI 库,单文件 `win32_gui.h` 即可使用,无需编译静态库。基于单一 `HWND` 主窗口,所有控件自绘,不依赖 MFC / Qt / DirectUI。 ## 快速开始 ### 1. 复制文件 将 `win32_gui.h` 复制到项目中。 ### 2. 编写代码 ```c // main.c #define GUI_IMPLEMENTATION #include "win32_gui.h" int main(void) { GUI_Init(GetModuleHandle(NULL)); GUI_SetTitle(L"My App"); GUI_SetSize(400, 300); Button* btn = GUI_CreateButton(150, 130, 100, 36, L"Click Me"); (void)btn; GUI_Run(); GUI_Shutdown(); return 0; } ``` ### 3. 编译 ```bash gcc -Wall -DUNICODE -D_UNICODE -mwindows -o app.exe main.c \ -lgdi32 -luser32 -lcomdlg32 -limm32 -lshell32 -lole32 ``` > **链接库**:`-limm32` 用于 IME,`-lshell32 -lole32` 用于目录选择对话框。 ## 使用规则 1. **恰好一个 .c 文件** 定义 `GUI_IMPLEMENTATION` 并 include: ```c #define GUI_IMPLEMENTATION #include "win32_gui.h" ``` 2. **其他 .c 文件** 直接 include 即可使用 API: ```c #include "win32_gui.h" ``` 3. **编译选项** 必须包含 `-DUNICODE -D_UNICODE` 4. **链接库** 需要 `-lgdi32 -luser32 -lcomdlg32 -limm32 -lshell32 -lole32` ### 注意事项 - 本函数库使用 `SetWindowTextW` 设置窗口标题,这依赖 `-luser32`。 - 使用 `ChooseFontW` / `ChooseColorW` / `GetOpenFileNameW` 时链接 `-lcomdlg32`。 - `GUI_FolderDialog` 使用 `SHBrowseForFolderW`,依赖 `-lshell32 -lole32`。 - IME 合成窗口定位使用 `ImmSetCompositionWindow`,依赖 `-limm32`。 ## 运行演示 ```bash make # 编译所有示例 make run # 运行 demo.exe ./mdbrowser.exe # 运行 Markdown 浏览器 ``` ## 已知限制 | 限制 | 说明 | |------|------| | 单窗口 | 仅支持一个主窗口,不支持多窗口或多文档界面 | | 主线程 | 所有控件操作必须在创建窗口的同一线程执行 | | 全局状态 | 使用全局 `g_gui` 上下文,不支持多实例并行 | | 阶段 4 跳过 | 不支持多上下文 (`GUIContext*`),全局状态是设计限制 | | TabControl 溢出 | 标签页过多时不提供滚动,可能溢出 | | Label 字体 | `Label_Draw` 每帧重建字体对象,高频重绘场景有性能开销 | ## 控件列表 | 控件 | 说明 | |------|------| | Button | 按钮,支持默认按钮 (`GUI_SetDefaultButton`) | | Label | 静态文本标签 | | Input | 单行文本输入,支持选区、复制/粘贴 | | TextArea | 多行文本编辑,支持选区、拖拽滚动条 | | CheckBox | 复选框 | | RadioButton | 单选按钮(按 group_id 分组) | | Slider | 滑块(水平/垂直) | | ProgressBar | 进度条 | | ComboBox | 下拉列表 | | TabControl | 选项卡 | | GroupBox | 分组框 | | TextView | 只读多行文本(支持 Markdown 渲染) | | ImageView | 图片显示(支持 Fit/Center/Stretch) | | Separator | 分隔线 | ## 布局 | 布局 | 说明 | |------|------| | VBoxLayout | 垂直布局 | | HBoxLayout | 水平布局 | | GridLayout | 网格布局 | ```c GUI_LayoutAdd(layout, widget, stretch); // stretch=0 自然大小, >0 弹性 GUI_GridAdd(layout, widget, row, col, stretch); GUI_SetLayoutPadding(layout, padding); GUI_SetLayoutSpacing(layout, spacing); GUI_SetWidgetAnchor(widget, GUI_ANCHOR_LEFT | GUI_ANCHOR_RIGHT); // 锚点随窗口缩放 ``` ## API 参考 ### 核心 | 函数 | 说明 | |------|------| | `GUI_Init(hInstance)` | 初始化库并创建主窗口 | | `GUI_InitEx()` | 使用默认 hInstance 初始化 | | `GUI_Run()` | 进入消息循环 | | `GUI_Shutdown()` | 释放所有资源 | | `GUI_SetTitle(title)` | 设置窗口标题 | | `GUI_SetSize(w, h)` | 设置客户区大小 | | `GUI_SetStyle(style)` | 切换风格:`GUI_STYLE_FLAT` / `GUI_STYLE_CLASSIC` | | `GUI_GetStyle()` | 获取当前风格 | | `GUI_GetHWND()` | 获取主窗口 HWND | | `GUI_Redraw()` | 重绘所有控件 | | `GUI_Maximize()` / `GUI_Minimize()` / `GUI_Restore()` | 窗口状态 | | `GUI_IsMaximized()` / `GUI_IsMinimized()` | 查询窗口状态 | ### 通用控件操作 | 函数 | 说明 | |------|------| | `GUI_DestroyWidget(widget)` | 安全销毁控件(延迟到消息循环间隙) | | `GUI_ShowWidget(widget, show)` | 显示/隐藏 | | `GUI_EnableWidget(widget, enable)` | 启用/禁用 | | `GUI_SetWidgetPos(widget, x, y)` | 设置位置 | | `GUI_SetWidgetSize(widget, w, h)` | 设置尺寸 | | `GUI_SetWidgetAnchor(widget, flags)` | 设置缩放锚点 | | `GUI_GetWidgetID(widget)` | 获取 ID | | `GUI_RedrawWidget(widget)` | 仅重绘指定控件 | ### Label | 函数 | 说明 | |------|------| | `GUI_CreateLabel(x, y, w, h, text)` | 创建标签 | | `GUI_SetLabelText(lbl, text)` | 设置文本 | | `GUI_SetLabelColor(lbl, color)` | 设置颜色 | | `GUI_SetLabelAlign(lbl, align)` | 对齐:`GUI_ALIGN_LEFT/CENTER/RIGHT` | | `GUI_SetLabelFontSize(lbl, size)` | 设置字体大小 | ### Input(单行输入) | 函数 | 说明 | |------|------| | `GUI_CreateInput(x, y, w, h)` | 创建输入框 | | `GUI_SetInputText(inp, text)` | 设置文本(截断超长部分) | | `GUI_GetInputText(inp)` | 获取文本 | | `GUI_SetInputChangeCallback(inp, cb)` | 内容变化回调 `void(*)(Input*)` | | `GUI_SetInputMaxLength(inp, max)` | 最大字符数 | 支持:鼠标选区、Shift+方向键、Ctrl+A/C/X/V、IME 输入法。 ### TextArea(多行编辑) | 函数 | 说明 | |------|------| | `GUI_CreateTextArea(x, y, w, h)` | 创建多行编辑器 | | `GUI_SetTextAreaText(ta, text)` | 设置文本 | | `GUI_GetTextAreaText(ta)` | 获取文本 | | `GUI_SetTextAreaReadOnly(ta, ro)` | 只读模式 | | `GUI_SetTextAreaCallback(ta, cb)` | 内容变化回调 `void(*)(Input*)` | 支持:多行选区、复制/粘贴、拖拽滚动条、Shift+方向键、Ctrl+A/C/X/V、IME。 ### Button | 函数 | 说明 | |------|------| | `GUI_CreateButton(x, y, w, h, text)` | 创建按钮 | | `GUI_SetButtonText(btn, text)` | 设置文本 | | `GUI_SetButtonCallback(btn, cb)` | 点击回调 `void(*)(Button*)` | | `GUI_SetDefaultButton(btn)` | 设为默认按钮(Enter 触发) | ### CheckBox / RadioButton | 函数 | 说明 | |------|------| | `GUI_CreateCheckBox(x, y, w, h, text, checked)` | 创建复选框 | | `GUI_SetCheckBoxChecked(cb, val)` | 设置选中状态 | | `GUI_GetCheckBoxChecked(cb)` | 获取选中状态 | | `GUI_SetCheckBoxCallback(cb, cb_fn)` | 变化回调 `void(*)(Widget*)` | | `GUI_CreateRadioButton(x, y, w, h, text, group, checked)` | 创建单选按钮 | | `GUI_SetRadioButtonChecked(rb, val)` | 设置选中 | | `GUI_GetRadioButtonChecked(rb)` | 获取选中 | ### Slider / ProgressBar | 函数 | 说明 | |------|------| | `GUI_CreateSlider(x, y, w, h, horizontal)` | 创建滑块 | | `GUI_SetSliderValue(sl, val)` / `GUI_GetSliderValue(sl)` | 值 | | `GUI_SetSliderRange(sl, min, max)` | 范围 | | `GUI_SetSliderCallback(sl, cb)` | 变化回调 | | `GUI_CreateProgressBar(x, y, w, h)` | 创建进度条 | | `GUI_SetProgressBarValue(pb, val)` / `GUI_GetProgressBarValue(pb)` | 值 | | `GUI_SetProgressBarRange(pb, min, max)` | 范围 | | `GUI_SetProgressBarColor(pb, color)` | 颜色 | ### ComboBox | 函数 | 说明 | |------|------| | `GUI_CreateComboBox(x, y, w, h)` | 创建下拉列表 | | `GUI_ComboBoxAddItem(cb, text)` | 添加条目 | | `GUI_SetComboBoxSelected(cb, idx)` | 选中条目 | | `GUI_GetComboBoxSelected(cb)` | 获取选中索引 | | `GUI_GetComboBoxText(cb)` | 获取选中文本 | | `GUI_SetComboBoxCallback(cb, cb_fn)` | 选择变化回调 | ### TabControl | 函数 | 说明 | |------|------| | `GUI_CreateTabControl(x, y, w, h)` | 创建选项卡 | | `GUI_AddTabPage(tc, title)` | 添加页面,返回索引 | | `GUI_AddToTabPage(tc, idx, child)` | 向页面添加子控件 | | `GUI_SetActiveTab(tc, idx)` | 切换当前页 | | `GUI_GetActiveTab(tc)` | 获取当前页索引 | | `GUI_GetTabPageCount(tc)` | 页面总数 | | `GUI_SetTabCallback(tc, cb)` | 页面切换回调 | ### TextView / TextArea / ImageView | 函数 | 说明 | |------|------| | `GUI_CreateTextView(x, y, w, h)` | 创建只读文本视图 | | `GUI_SetTextViewText(tv, text)` | 设置文本 | | `GUI_SetTextViewMarkdown(tv, enable)` | 启用 Markdown 渲染 | | `GUI_CreateImageView(x, y, w, h)` | 创建图片视图 | | `GUI_SetImageViewBitmap(iv, hBmp)` | 设置位图 | | `GUI_SetImageViewScaleMode(iv, mode)` | 缩放模式:`GUI_IMAGE_NONE/FIT/CENTER/STRETCH` | ### GroupBox / Separator | 函数 | 说明 | |------|------| | `GUI_CreateGroupBox(x, y, w, h, title)` | 创建分组框 | | `GUI_SetGroupBoxTitle(gb, title)` | 设置标题 | | `GUI_GroupBoxAdd(gb, child, stretch)` | 添加子控件 | | `GUI_CreateSeparator(x, y, w, h, horizontal)` | 创建分隔线 | ### 对话框 所有对话框采用「调用方提供 buffer」的设计:返回值 `1` 表示成功,`0` 表示用户取消或失败,输出参数永远不需要 `free()`。 | 函数 | 说明 | |------|------| | `GUI_MessageBox(text, caption, flags)` | 消息框,`flags` 接受 `GUI_MB_*` 或 Win32 `MB_*` 常量;返回 `GUI_ID_OK/CANCEL/YES/NO/...` | | `GUI_OpenFileDialog(out, cap, title, filter)` | 打开文件,写入 `out`(建议 `MAX_PATH`),`title`/`filter` 可为 `NULL` | | `GUI_SaveFileDialog(out, cap, title, filter, default_ext)` | 保存文件;`out` 入参可作为建议文件名 | | `GUI_FolderDialog(out, cap, title)` | 选择目录 | | `GUI_ColorDialog(&color)` | 颜色选择,`color` 入参为初始色,成功时被覆写 | `filter` 是 Win32 风格的双 NUL 结尾字符串,例如: ```c L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0" ``` 示例: ```c wchar_t path[MAX_PATH]; if (GUI_OpenFileDialog(path, MAX_PATH, L"Open File", NULL)) { /* use path - no free needed */ } ``` ## 项目结构 ``` ├── win32_gui.h # Header-only 库(单文件,包含所有实现) ├── examples/ │ ├── demo.c # 演示程序(覆盖所有控件) │ ├── mdbrowser.c # Markdown 文件浏览器 │ ├── notepad.c # 简易记事本(演示文件对话框 + 错误提示) │ └── cagent.c # 调用 LLM API 的极简 AI Agent(演示后台线程 + WinHTTP) ├── Makefile # 编译脚本 ├── Doxyfile # Doxygen 文档配置 ├── .gitignore └── README.md # 本文档 ``` ## 特性 - 单文件,无外部依赖 - 16 种控件 - 3 种布局管理器(VBox / HBox / Grid) - 双风格(Flat / Classic 3D) - 文本选择 & 剪贴板(Input / TextArea) - IME 输入法支持 - DPI 感知(`WM_DPICHANGED`) - 延迟销毁(避免 use-after-free) - 编译后 exe 约 70KB ## 许可证 MIT License