# Hello eduwin —— 第一个 GUI 程序

本教程将带你从零开始，编写并运行第一个 eduwin 程序。

---

## 1. 准备工作

### 1.1 下载与解压

eduwin 只需两个条件：

- **Windows 7/8/10/11** 操作系统
- **MSVC 编译器**（Visual Studio 2022 Build Tools，安装教程见[下载页面](/download)）

从下载页面获取 `eduwin_pub.zip`，解压后目录结构如下（**请先看清这个结构，后面所有路径都与此相关**）：

```
eduwin_pub/                  ← 下载包根目录
├── eduwin/                  ← eduwin 库文件
│   ├── include/             #   头文件（eduwin.h 在这里）
│   ├── lib/                 #   静态库（eduwin.lib 在这里）
│   └── eduwin.manifest      #   Windows 视觉样式清单文件
├── samples/                 ← 示例项目
│   ├── hello_demo/          #   本教程对应的示例
│   ├── sqlite_demo/
│   └── ...
└── ...
```

> 本文中，我们假设 `eduwin_pub/` 解压到了 `D:\XTU\c-train\eduwin_pub\`，后文以此为例。

### 1.2 关于编译器

eduwin **仅官方支持 MSVC**（Visual Studio 编译器）。MinGW（GCC 的 Windows 移植版）理论上可以编译 C 代码，但因为 eduwin 使用了 MSVC 特有的资源编译（`.rc` 文件）和链接器配置，用 MinGW 需要额外写大量的兼容脚本，非常繁琐，不推荐。**请直接使用 MSVC。**

## 2. 创建项目

有两种方式，推荐初学者使用方式一。

### 方式一：直接复制 samples（推荐）

`samples/` 目录下有多个可直接编译运行的示例项目。以 `hello_demo` 为例：

1. 把 `samples/hello_demo/` **整个文件夹**复制出来
2. 放到你的工作目录，可重命名为你的项目名（比如 `my_project/`）
3. 修改里面的 `.c` 文件开始编程

### 方式二：从零搭建

你也可以在工作目录下手动创建项目文件：

```
my_project/
├── app.ico           # 程序图标（可以从 samples 复制）
├── app.rc            # 资源文件（从 samples 复制并修改）
├── build.bat         # 编译脚本（从 samples 复制并修改）
├── hello.c           # 我们的代码
```

接下来的讲解以方式二为例（两种方式的原理完全一样，方式一只是省去了文件复制步骤）。

## 3. 编写代码

创建 `hello.c`，写入以下内容：

```c
#include "eduwin.h"

static HWND text;   /* 文本框 */
static HWND label;  /* 标签 */

/* 点击按钮时，把文本框内容显示到标签上 */
static void on_click(void *data)
{
    const WCHAR *s = get_text(text);
    set_text(label, s);
    set_text(text, L"");
}

int main(void)
{
    if (init_app() != 0)
    {
        alert(L"错误", L"eduwin 初始化失败");
        return 1;
    }

    HWND win = create_window(L"Hello eduwin", 400, 200);
    if (!win)
    {
        alert(L"错误", L"创建窗口失败");
        return 1;
    }

    /* 文本框 */
    text = create_text(win, L"请输入文字", 20, 20, 250, 24);

    /* 按钮 */
    HWND btn = create_button(win, L"显示", 280, 20, 80, 24);

    /* 标签（用来显示输入的文字） */
    label = create_label(win, L"", 20, 60, 340, 80);

    on_button_click(btn, on_click, NULL);

    show_window(win);
    run_app();
    return 0;
}
```

## 4. 编译运行

打开 `build.bat`（从 `samples/hello_demo/build.bat` 复制而来），其中有 4 个地方需要你理解和修改。

### 4.1 修改 VCVARS 路径

`build.bat` 中有这样一行：

```bat
set "VCVARS=C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
```

你需要根据自己安装的 VS 版本，把路径中 `\18\` 那一段换成对应的文件夹名。下表列出了常见版本：

| 你安装的版本        | 对应的路径（复制后替换即可）                                                                     |
| ------------------- | ------------------------------------------------------------------------------------------------ |
| VS 2026 Build Tools | `C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\VC\Auxiliary\Build\vcvars64.bat`   |
| VS 2022 Build Tools | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat` |
| VS 2022 Community   | `C:\Program Files (x86)\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat`  |
| VS 2019 Build Tools | `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat` |
| VS 2019 Community   | `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat`  |

找到自己对应的那一行，复制整条路径，粘贴替换掉 `VCVARS=` 后面的内容即可。**即使你直接用 `samples/` 里的例子，也必须先改这里。**

#### 找不到 vcvars64.bat 怎么办？

如果用 Everything 搜索 `vcvars64.bat`，能直接找到真实路径，比对着表格猜更快。

### 4.2 修改 SOURCE 和 PROGRAM

```bat
set SOURCE=hello.c     ← 你的 C 源文件名
set PROGRAM=hello.exe  ← 编译后输出的 exe 文件名
```

- `SOURCE`：你写了哪个 `.c` 文件，这里就填哪个文件名
- `PROGRAM`：你想生成什么名字的 `.exe`，随便取

### 4.3 理解编译命令中的相对路径（重点）

`samples/hello_demo/build.bat` 中的编译命令如下：

```bat
cl /nologo /W3 /utf-8 /std:c17 /I..\..\eduwin\include /c "%SOURCE%"
link /nologo "%SOURCE:.c=.obj%" app.res ..\..\eduwin\lib\eduwin.lib ...
```

这里的 `..\..\eduwin\include` 和 `..\..\eduwin\lib\eduwin.lib` 是**相对路径**。

`..` 表示"退回上一级目录"。`build.bat` 在 `samples/hello_demo/` 里，`..\..\` 就是从那里往上退两级，到达 `eduwin_pub/` 根目录，然后再进 `eduwin\include\` 或 `eduwin\lib\`。所以：

- `/I..\..\eduwin\include` 告诉编译器去 `eduwin_pub/eduwin/include/` 找 `eduwin.h`
- `..\..\eduwin\lib\eduwin.lib` 告诉链接器去 `eduwin_pub/eduwin/lib/` 找 `eduwin.lib`

#### 如果项目位置变了呢？

假如你把项目复制到了 `D:\my_project\`，而 `eduwin_pub/` 在 `D:\XTU\c-train\eduwin_pub\`，那么相对路径就变了。你需要根据实际情况调整——核心原则是：**确保 `..\..\eduwin\include` 能正确指向 `eduwin/include/` 目录**。如果不确定，可以用绝对路径替代，比如：

```bat
cl /nologo /W3 /utf-8 /std:c17 /ID:\XTU\c-train\eduwin_pub\eduwin\include /c "%SOURCE%"
link /nologo "%SOURCE:.c=.obj%" app.res D:\XTU\c-train\eduwin_pub\eduwin\lib\eduwin.lib ...
```

> 绝对路径就是完整的路径（如 `D:\...\eduwin.lib`），不依赖于"当前在哪个目录"，不容易搞混。缺点是如果移动了 `eduwin_pub/` 的位置或换到别人电脑上，就需要重新改。

### 4.4 app.rc 中的路径

`app.rc` 是资源文件，用记事本打开会看到：

```
1 ICON "app.ico"
1 24 "..\\..\\eduwin\\eduwin.manifest"
```

- 第 1 行：指定程序图标为 `app.ico`（跟 `app.rc` 同目录）
- 第 2 行：引用 `eduwin.manifest`（Windows 视觉样式清单），这里的 `..\\..\\eduwin\\eduwin.manifest` 同样是相对路径，原理与上一节相同

> 注意：`.rc` 文件中路径使用双反斜杠 `\\`，这是资源编译器的语法要求，意思等同于单反斜杠 `\`。

如果 `eduwin_pub/` 的相对位置变了，这里也要同步修改。

### 4.5 编译

确认以上路径都正确后，双击 `build.bat`，等待编译完成。目录下会生成 `hello.exe`：

```
my_project/
├── hello.c
├── build.bat
├── hello.obj
└── hello.exe    ← 这就是我们的程序
```

双击 `hello.exe` 运行！

## 5. 效果展示

运行后会看到一个 400×200 的窗口：

- 上边是一个文本框，可以输入文字
- 右边是一个"显示"按钮
- 下边是一个标签区域

在文本框输入文字后点击"显示"，标签会显示你输入的内容，同时文本框清空。

## 6. 代码说明

| 函数                        | 说明                                 |
| --------------------------- | ------------------------------------ |
| `init_app()`                | 初始化 eduwin 框架，必须最先调用     |
| `create_window()`           | 创建一个窗口，返回窗口句柄           |
| `create_text()`             | 创建文本框控件                       |
| `create_button()`           | 创建按钮控件，最后一个参数是回调函数 |
| `on_button_click()`         | 注册按钮的点击事件回调               |
| `show_window()`             | 显示窗口                             |
| `run_app()`                 | 进入消息循环，阻塞运行               |
| `get_text()` / `set_text()` | 获取/设置控件的文字内容              |

---

现在你已经成功跑通了第一个 eduwin 程序！接下来可以查看更完整的[示例项目](#)，或阅读完整的 [API 参考](/docs/api/eduwin-app-api)。
