eduwin 控件 API

辅助函数

以下函数适用于多种控件类型。

文本内容

void set_text(HWND hwnd, const WCHAR *text);
const WCHAR *get_text(HWND hwnd);

设置/获取控件的文本内容。适用于按钮、标签、文本框、输入框、状态栏等。

get_text 内部为每个控件独立分配缓冲区,多次调用返回不同指针,互不干扰。缓冲区在下次对同一控件调用 get_text 时自动释放。

只读控制

void set_readonly(HWND hwnd, int readonly);

将文本框、多行文本框、密码框设为只读或可编辑。readonly 为 1 时只读,为 0 时可编辑。

HWND text = create_text(win, L"只读内容", 10, 10, 200, 24);
set_readonly(text, 1);   // 设为只读
set_readonly(text, 0);   // 恢复可编辑

启用禁用

void set_enable(HWND hwnd, int enable);

启用或禁用控件。enable 为 1 时可用,为 0 时禁用(灰显且不可操作)。

set_enable(btn_delete, 0);  // 禁用删除按钮
set_enable(btn_delete, 1);  // 启用删除按钮

显隐

void show(HWND hwnd);
void hide(HWND hwnd);
int  is_visible(HWND hwnd);

显示或隐藏控件。is_visible 返回 1 表示可见,0 表示隐藏。

布局

void move(HWND hwnd, int x, int y);

移动控件到指定位置(仅改变位置,不改变尺寸)。

void set_size(HWND hwnd, int w, int h);
void get_size(HWND hwnd, int *w, int *h);

设置或获取控件的客户区尺寸。wh 可传 NULL 跳过读取。

int cw, ch;
get_size(win, &cw, &ch);    // 获取窗口客户区宽高
set_size(btn, 120, 30);     // 调整按钮尺寸

窗口样式与扩展属性

LONG_PTR get_style(HWND hwnd);
void set_style(HWND hwnd, LONG_PTR style);
LONG_PTR get_attr(HWND hwnd);
void set_attr(HWND hwnd, LONG_PTR attr);
  • get_style / set_style 读取或设置窗口样式(GWL_STYLE,对应 WS_* 常量,如 WS_THICKFRAMEWS_BORDER
  • get_attr / set_attr 读取或设置窗口扩展样式(GWL_EXSTYLE,对应 WS_EX_* 常量,如 WS_EX_TOOLWINDOW

set_style / set_attr 调用后会自动刷新窗口的非客户区,确保样式变更立即生效。

// 为窗口添加可缩放边框和最大化按钮
set_style(win, get_style(win) | WS_THICKFRAME | WS_MAXIMIZEBOX);

控件参考

按钮

HWND create_button(HWND parent, const WCHAR *text, int x, int y, int w, int h);
void on_button_click(HWND btn, void (*callback)(void *), void *data);

创建一个按钮,通过 on_button_click 注册点击事件回调。

void btn_click(void *data) {
    set_text(label, L"按钮被点击");
}
HWND btn = create_button(win, L"点击我", 10, 10, 100, 30);
on_button_click(btn, btn_click, NULL);

标签

HWND create_label(HWND parent, const WCHAR *text, int x, int y, int w, int h);

创建一个标签(静态文本),用于显示文字。

提示: C 语言中,相邻的字符串字面量会被自动拼接。多行文本可以拆成多行写,提高可读性:

create_label(win, L"第一行\n"
                  L"第二行\n"
                  L"第三行",
             10, 40, 200, 80);

编译器会自动合并为 L"第一行\n第二行\n第三行"。这个技巧适用于所有接受 const WCHAR * 参数的函数。

HWND label = create_label(win, L"用户名:", 10, 40, 200, 24);
set_text(label, L"新文字");

文本框

HWND create_text(HWND parent, const WCHAR *text, int x, int y, int w, int h);

创建一个单行文本框,text 为初始文本。可通过 set_text / get_text 读写内容。


多行文本

HWND create_textarea(HWND parent, const WCHAR *text, int x, int y, int w, int h);

创建一个多行文本输入框,带垂直滚动条,支持换行和中文。可通过 set_text / get_text 读写内容。


密码框

HWND create_password(HWND parent, int x, int y, int w, int h);

创建一个密码输入框,输入内容显示为黑点(•)。可通过 set_text / get_text 读写密码文本。


复选框

HWND create_checkbox(HWND parent, const WCHAR *text, int x, int y, int w, int h);
int is_checked(HWND hwnd);
void set_checked(HWND hwnd, int checked);

创建一个复选框。点击时自动切换选中/未选状态。is_checked 返回 1 表示已选中;set_checked(1) 设选中,set_checked(0) 取消。


单选按钮

HWND create_radio(HWND parent, const WCHAR *text, int x, int y, int w, int h);
int is_checked(HWND hwnd);
void set_checked(HWND hwnd, int checked);

创建一个单选按钮。同一父窗口下的单选按钮自动互斥。通过 is_checkedset_checked 读取/设定状态。


分组框

HWND create_groupbox(HWND parent, const WCHAR *text, int x, int y, int w, int h);

创建一个分组框(视觉框线 + 标题),常用来包裹按钮、单选等控件。


下拉框

HWND create_combobox(HWND parent, int x, int y, int w, int h);
void combobox_add_text(HWND combobox, const WCHAR *text);
int combobox_selected_index(HWND combobox);
const WCHAR *combobox_selected_text(HWND combobox);

创建一个下拉选择框(不可编辑)。combobox_add_text 添加选项;combobox_selected_index 返回选中索引(-1 表示未选中);combobox_selected_text 返回选中项的文本。


列表框

HWND create_listbox(HWND parent, int x, int y, int w, int h);
void listbox_add_text(HWND listbox, const WCHAR *text);
int listbox_selected_index(HWND listbox);
int listbox_count(HWND listbox);
const WCHAR *listbox_selected_text(HWND listbox);

创建一个列表框。listbox_add_text 添加选项;listbox_selected_index 返回选中索引;listbox_count 返回总项数;listbox_selected_text 返回选中项的文本。


进度条

HWND create_progressbar(HWND parent, int x, int y, int w, int h);
void set_progress(HWND progress, int value);

创建一个进度条,默认范围 0–100,set_progress 设定当前进度值。


滑块

HWND create_slider(HWND parent, int x, int y, int w, int h);
int slider_get_pos(HWND slider);
void slider_set_pos(HWND slider, int value);

创建一个滑块(带刻度线),默认范围 0–100。slider_get_pos 读取位置,slider_set_pos 设定位置。


滚动条

HWND create_scrollbar(HWND parent, int x, int y, int w, int h);
int scrollbar_get_pos(HWND scrollbar);
void scrollbar_set_pos(HWND scrollbar, int pos);

创建一个滚动条。根据宽高比自动决定水平或垂直(宽 > 高为水平,高 > 宽为垂直)。scrollbar_get_pos / scrollbar_set_pos 读取/设定位置。


数值调节

HWND create_spin(HWND parent, int x, int y, int w, int h);
void spin_set_range(HWND spin, int min, int max);
int spin_get_pos(HWND spin);

创建一个数值调节按钮(Spin/Up-Down)。自动绑定前面的编辑框作为伙伴。spin_set_range 设定范围,spin_get_pos 读取当前数值。


状态栏

HWND create_statusbar(HWND parent);
void statusbar_set_text(HWND statusbar, const WCHAR *text);

创建一个底部状态栏,自动吸附在窗口底部。statusbar_set_text 设置显示文本。

HWND sb = create_statusbar(win);
statusbar_set_text(sb, L"就绪");

工具栏

HWND create_toolbar(HWND parent);
void toolbar_add_button(HWND toolbar, const WCHAR *text);

创建一个顶部工具栏。toolbar_add_button 添加文字按钮。


树状列表

HWND create_treeview(HWND parent, int x, int y, int w, int h);
HWND treeview_add_text(HWND treeview, const WCHAR *text);
HWND treeview_add_child(HWND treeview, HWND parent_item, const WCHAR *text);
HWND treeview_selected(HWND treeview);
const WCHAR *treeview_selected_text(HWND treeview);
void treeview_delete(HWND treeview, HWND item);
void treeview_set_text(HWND treeview, HWND item, const WCHAR *text);
void treeview_expand(HWND treeview, HWND item);
void treeview_collapse(HWND treeview, HWND item);

创建一个树状列表视图。

  • treeview_add_text 添加根节点,返回节点句柄
  • treeview_add_child 在指定父节点下添加子节点,返回节点句柄
  • treeview_selected 返回当前选中节点句柄(NULL 表示无选中)
  • treeview_selected_text 返回当前选中节点的文本
  • treeview_delete 删除指定节点及其所有子节点
  • treeview_set_text 修改指定节点的显示文本
  • treeview_expand / treeview_collapse 展开/折叠指定节点
HWND root  = treeview_add_text(tree, L"中国");
HWND city1 = treeview_add_child(tree, root, L"北京");
HWND city2 = treeview_add_child(tree, root, L"上海");
treeview_expand(tree, root);

详细列表

HWND create_listview(HWND parent, int x, int y, int w, int h);
void listview_add_column(HWND listview, const WCHAR *text, int width);
HWND listview_add_text(HWND listview, const WCHAR *text);
void listview_set_text(HWND listview, int row, int col, const WCHAR *text);
int listview_count(HWND listview);
int listview_selected_index(HWND listview);

创建一个详细列表视图(报表模式)。先 listview_add_column 添加列(指定列名和宽度),再 listview_add_text 添加行。

listview_set_text 设置指定行列的文本,用于在多列模式下填充第 2 列及之后的列:

listview_add_text(listview, L"北京");                    // 第 0 列(姓名)
listview_set_text(listview, 0, 1, L"beijing@test.com");  // 第 1 列(邮箱)
listview_set_text(listview, 0, 2, L"010-1234");          // 第 2 列(电话)

listview_count 返回当前总行数,listview_selected_index 返回选中行的索引(-1 表示未选中)。

void listview_delete_all(HWND listview);

清空列表视图的所有行。

void listview_get_text(HWND listview, int row, int col, WCHAR *buf, int size);

读取列表视图指定行列的文本到缓冲区。常用于获取选中行的某列数据(如 PID)。

void on_listview_dblclick(HWND listview, void (*callback)(void *), void *data);

注册列表视图的双击回调。双击某行时触发,配合 listview_selected_index 获取被双击的行。


标签页

HWND create_tabbar(HWND parent, int x, int y, int w, int h);
void tabbar_add_text(HWND tabbar, const WCHAR *text);
int tabbar_selected_index(HWND tabbar);
void on_tabbar_select(HWND tabbar, void (*callback)(void *), void *data);

创建一个标签页控件。tabbar_add_text 添加标签页,tabbar_selected_index 返回当前选中标签的索引。

on_tabbar_select 注册标签切换回调。用户点击不同标签页时触发,回调中通过 tabbar_selected_index 获取当前选中索引。

void on_tab_changed(void *d) {
    int idx = tabbar_selected_index(g_tab);
    // 切换到 idx 对应的面板
}
on_tabbar_select(g_tab, on_tab_changed, NULL);

日期选择

HWND create_datepicker(HWND parent, int x, int y, int w, int h);

创建一个日期选择器。


IP 输入

HWND create_ip_input(HWND parent, int x, int y, int w, int h);
void get_ip(HWND ip_input, int ip[4]);
void set_ip(HWND ip_input, int a, int b, int c, int d);

创建一个 IP 地址输入控件(4 段式)。get_ip 获取 4 个段,set_ip 设置 IP 地址。


动画

HWND create_animation(HWND parent, int x, int y, int w, int h);
void play_animation(HWND anim, int res_id);

创建一个 AVI 动画控件。play_animation 播放资源中指定 ID 的 AVI 文件。


富文本

HWND create_richedit(HWND parent, int x, int y, int w, int h);

创建一个富文本编辑框,支持多行文本、中文和换行。可通过 set_text / get_text 读写内容。


日志面板(LogView)

基于 ListView 的自定义日志面板组件。三列:时间 | 级别 | 消息,自动管理行数上限,新日志自动滚底。

HWND create_logview(HWND parent, int x, int y, int w, int h);

创建日志面板。返回 ListView 句柄,后续 logview_info/warn/error 通过该句柄写入日志。

void logview_info(HWND hwnd, const WCHAR *fmt, ...);
void logview_warn(HWND hwnd, const WCHAR *fmt, ...);
void logview_error(HWND hwnd, const WCHAR *fmt, ...);

添加日志行,支持 printf 风格变参格式化。自动附加时间戳,分别标记为 INFO / WARN / ERROR

void logview_clear(HWND hwnd);

清空面板所有日志行。

void logview_set_max_rows(HWND hwnd, int max_rows);

设置最大行数(默认 500)。超出时自动删除最旧行。

HWND lv = create_logview(win, 860, 10, 330, 780);
logview_info(lv, L"应用已启动,端口 %d", 9099);
logview_warn(lv, L"连接超时 (conn_id=%d)", 5);
logview_error(lv, L"无效 JSON: %s", raw);

注意: LogView 在非 GUI 线程(如后台工作线程)中调用 logview_info 等函数是安全的。但创建 create_logview 必须在 GUI 线程中执行。


对话框

打开文件对话框

int open_file_dialog(HWND parent, WCHAR *buf, int size, const WCHAR *filter);

弹出打开文件对话框。buf 接收选中文件的完整路径;filter 为筛选器字符串,格式如 L"文本文件\0*.txt\0所有文件\0*.*\0"(注意用 \0 分隔)。成功返回 1,取消返回 0。

保存文件对话框

int save_file_dialog(HWND parent, WCHAR *buf, int size, const WCHAR *filter);

弹出保存文件对话框。参数含义同 open_file_dialog,已选择的文件会提示覆盖确认。

浏览目录对话框

int browse_folder_dialog(HWND parent, WCHAR *buf, int size);

弹出选择目录对话框。buf 接收选中目录的完整路径。成功返回 1,取消返回 0。


消息框

alert

void alert(const WCHAR *title, const WCHAR *message);

弹出仅含"确定"按钮的消息框。

confirm

int confirm(const WCHAR *title, const WCHAR *message);

弹出"确定/取消"对话框,返回 1 表示确定。

ask

int ask(const WCHAR *title, const WCHAR *message);

弹出"是/否"对话框,返回 1 表示是。