12 Commits

Author SHA1 Message Date
Serendipity 6509ef98e4 chore: 清理旧版IUP库文件并更新头文件路径
删除旧的iup-3.31_Win64_dllw6_lib目录下的所有DLL和静态库文件
将IUP头文件从旧目录迁移到新的libs/IUP/include统一路径
更新CMakeLists.txt中的包含路径和库链接配置
简化DLL复制逻辑,只复制核心iup.dll文件
2026-03-19 20:14:06 +08:00
Serendipity c928c271e8 chore: 移除构建安装程序前的DLL复制步骤
不再需要手动复制IUP DLL文件,因为安装脚本已直接引用库目录。
2026-03-19 13:23:03 +08:00
Serendipity 02e702b285 fix(构建): 修复IUP DLL复制命令的路径变量
将CMAKE_SOURCE_DIR更改为CMAKE_CURRENT_SOURCE_DIR以确保在子目录中也能正确找到DLL文件。
移除不必要的条件判断,使复制命令始终执行。
2026-03-19 12:40:01 +08:00
Serendipity af3138c146 build: 重构 CMakeLists.txt 以使用现代 CMake 最佳实践
- 将项目声明更新为包含版本和语言
- 启用 RC 语言以正确处理资源文件
- 使用 target_* 命令替代全局命令(如 include_directories、link_directories)
- 将资源文件直接加入源文件列表,简化构建定义
- 优化 DLL 复制逻辑,使用 file(GLOB) 和 copy_if_different
- 改进编译器选项的条件设置,增强跨编译器兼容性
2026-03-19 12:37:41 +08:00
Serendipity 6e6adf3b85 chore: 迁移构建系统并清理遗留的二进制文件
- 删除 bin/ 目录下遗留的 DLL 和可执行文件,它们现在由 CMake 构建过程自动复制
- 更新 CMakeLists.txt,明确设置 C17 标准并优化编译选项
- 更新 Inno Setup 安装脚本,使其从 build/ 目录获取构建产物
- 更新 main.c 中的编译说明,反映当前基于 CMake 的构建流程
2026-03-19 12:32:54 +08:00
Serendipity e84b33c5ca build: 迁移项目构建系统至 CMake
- 新增 CMakeLists.txt 文件,定义项目构建规则、依赖和编译选项。
- 更新 README.md 文档,推荐使用 CMake 进行构建,并说明新旧构建方式。
- 保留原有的 Makefile 支持以保持向后兼容。
2026-03-19 12:07:01 +08:00
Serendipity ac6b409f3a feat: 为只读模式添加专用应用程序标题
在非管理员权限下运行时,将对话框标题从硬编码字符串改为使用配置文件中定义的 APP_NAME_READONLY 宏。这提高了代码的可维护性和一致性,使标题文本集中管理,便于未来修改。
2026-03-18 22:37:33 +08:00
Serendipity 1bbe95582a refactor: 将应用程序名称提取为配置常量
- 在 config.h 中定义 APP_NAME 常量,提高可维护性
- 将 main.c 中的对话框标题硬编码替换为使用 APP_NAME
2026-03-18 22:33:25 +08:00
Serendipity 3ecf35963d feat(ui): 增加对话框最小尺寸并调整默认大小
- 将对话框默认大小从500x400调整为800x800
- 添加MINSIZE属性确保对话框不可缩小
- 清理ui.c中的多余空白字符
- 在main.c中添加编译和打包说明注释
2026-03-18 22:03:57 +08:00
Serendipity 276d2c5fe3 docs(config.h): 为UI配置常量添加注释说明 2026-03-18 21:09:13 +08:00
Serendipity a9339f9b9f style(config): 统一宏定义格式并更新文档
调整 config.h 中 UI_DLG_SIZE 宏定义的对齐格式以保持代码风格一致。
在 README.md 中新增“架构与二次开发”章节,说明项目的模块化设计和配置管理方式。
2026-03-18 21:06:55 +08:00
Serendipity 7fac2aab35 refactor: 重构代码以提取配置和全局变量
- 将 Windows 消息常量和 UI 配置常量分别提取到 globals.h 和 config.h 头文件中,提高可维护性
- 将全局变量和控件定义从 main.c 移至独立的 globals.c 源文件,实现关注点分离
- 更新 Makefile 以包含新的源文件 globals.c
- 在 ui.c 和 main.c 中引用 config.h,使用配置常量替代硬编码的 UI 参数
2026-03-18 21:01:50 +08:00
91 changed files with 192 additions and 57 deletions
+72
View File
@@ -0,0 +1,72 @@
cmake_minimum_required(VERSION 3.10)
project(PathEditor VERSION 3.0 LANGUAGES C)
# 启用资源编译器以处理 .rc 文件
enable_language(RC)
# 设置 C 标准
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF) # 禁用特定编译器的扩展(如 gnu17),强制使用标准 C17
# 定义源文件
set(SOURCES
src/main.c
src/utils.c
src/registry.c
src/callbacks.c
src/ui.c
src/globals.c
ico/resources.rc
)
# 创建 GUI 可执行文件(WIN32 属性会自动添加 -mwindows 参数)
add_executable(${PROJECT_NAME} WIN32 ${SOURCES})
# 添加宏定义
target_compile_definitions(${PROJECT_NAME} PRIVATE
_WIN32
UNICODE
_UNICODE
)
# 添加编译选项
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall
-O2
-fexec-charset=UTF-8
)
endif()
# 设置头文件搜索路径
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libs/IUP/include
)
# 设置库文件搜索路径
target_link_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/libs/IUP
)
# 链接所需库
target_link_libraries(${PROJECT_NAME} PRIVATE
iup
iupcd
gdi32
comdlg32
comctl32
uuid
ole32
advapi32
)
# 编译完成后,仅将程序实际需要的核心 DLL 文件复制到构建输出目录
set(IUP_REQUIRED_DLLS "${CMAKE_CURRENT_SOURCE_DIR}/libs/IUP/iup.dll")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${IUP_REQUIRED_DLLS}
"$<TARGET_FILE_DIR:${PROJECT_NAME}>"
COMMENT "Copying required DLLs to build directory..."
)
+5 -2
View File
@@ -18,9 +18,9 @@ CFLAGS = -Wall -O2 -I$(INCLUDE_DIR) -I$(LOCAL_INCLUDE_DIR) -D_WIN32 -DUNICODE -D
LDFLAGS = -L$(LIB_DIR) -liup -liupcd -lgdi32 -lcomdlg32 -lcomctl32 -luuid -lole32 -ladvapi32 -mwindows
# Source
SRC = src/main.c src/utils.c src/registry.c src/callbacks.c src/ui.c
SRC = src/main.c src/utils.c src/registry.c src/callbacks.c src/ui.c src/globals.c
RES = ico/resources.rc
OBJ = $(OBJ_DIR)/main.o $(OBJ_DIR)/utils.o $(OBJ_DIR)/registry.o $(OBJ_DIR)/callbacks.o $(OBJ_DIR)/ui.o $(OBJ_DIR)/resources.o
OBJ = $(OBJ_DIR)/main.o $(OBJ_DIR)/utils.o $(OBJ_DIR)/registry.o $(OBJ_DIR)/callbacks.o $(OBJ_DIR)/ui.o $(OBJ_DIR)/globals.o $(OBJ_DIR)/resources.o
EXE = $(BIN_DIR)/PathEditor.exe
all: $(BIN_DIR) $(OBJ_DIR) $(EXE)
@@ -49,6 +49,9 @@ $(OBJ_DIR)/callbacks.o: src/callbacks.c
$(OBJ_DIR)/ui.o: src/ui.c
$(CC) $(CFLAGS) -c -o $@ $<
$(OBJ_DIR)/globals.o: src/globals.c
$(CC) $(CFLAGS) -c -o $@ $<
$(OBJ_DIR)/resources.o: ico/resources.rc
$(WINDRES) -i $< -o $@
+20 -5
View File
@@ -33,6 +33,13 @@
* **轻量级**:原生 C 语言编写,无臃肿依赖,运行速度极快。
## 🏗️ 架构与二次开发
本项目注重代码的模块化和可维护性,非常适合作为 C 语言桌面程序开发的参考:
* **统一配置中心**:所有的 UI 尺寸、间距、颜色等常量配置均提取在 `include/config.h` 中,只需修改宏定义即可轻松定制属于你的专属界面风格。
* **清晰的全局状态**:全局变量和常量被独立分离在 `src/globals.c` / `include/globals.h` 中管理,使得核心业务逻辑更加整洁。
## 📦 下载与安装
您可以从 [Releases](https://github.com/LHY0125/PathEditor/releases) 页面下载最新的安装包 (`PathEditorSetup.exe`)。
@@ -47,11 +54,13 @@
* Windows 操作系统
* GCC 编译器 (推荐 MinGW-w64)
* Make 工具
* CMake 工具 (推荐使用 CMake 构建)
* IUP 库 (已包含在 `libs` 目录下)
* Inno Setup 6 (仅打包需要)
### 编译步骤
### 编译步骤 (推荐使用 CMake)
本项目已迁移至 CMake 构建系统,支持生成更标准的构建文件并集成到各大 IDE。
1. 克隆仓库:
@@ -60,14 +69,20 @@
cd PathEditor
```
2. 编译项目
2. 使用 CMake 配置和编译:
```bash
mingw32-make
# 生成构建系统 (以 MinGW 为例)
cmake -B build -G "MinGW Makefiles"
# 编译项目
cmake --build build
```
3. 运行:
编译成功后,可执行文件位于 `bin/PathEditor.exe`。
编译成功后,可执行文件位于 `build/PathEditor.exe`。
*(注:项目依然保留了传统的 `mingw32-make` 方式,您可以直接在根目录运行 `mingw32-make` 进行编译,产物位于 `bin/` 目录。)*
### 打包 (可选)
Binary file not shown.
-3
View File
@@ -1,7 +1,4 @@
@echo off
echo Copying DLLs...
if not exist bin mkdir bin
copy /Y "libs\iup-3.31_Win64_dllw6_lib\*.dll" bin\
echo Building Installer...
"D:\Program Files (x86)\Inno Setup 6\ISCC.exe" "dist\installer.iss"
+2 -2
View File
@@ -37,8 +37,8 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "d:\Code\doing_exercises\programs\PathEditor\bin\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\*.dll"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
+33
View File
@@ -0,0 +1,33 @@
#ifndef CONFIG_H
#define CONFIG_H
// ============================================================================
// UI的配置常量
// ============================================================================
// 应用程序名称
#define APP_NAME "PathEditor" // 编辑环境变量应用程序名称
#define APP_NAME_READONLY "PathEditor (只读模式)" // 编辑环境变量只读模式标题
// 对话框设置
#define UI_DLG_SIZE "800x800" // 对话框默认大小 (像素)
#define UI_DLG_MINSIZE "800x800" // 对话框最小大小 (像素)
// 列表控件设置
#define UI_LIST_ITEM_PADDING "5x5" // 列表项内边距
#define UI_LIST_BACKCOLOR "255 255 255" // 列表背景颜色
// 按钮设置
#define UI_BTN_RASTERSIZE "100x32" // 按钮默认大小
// 布局间隙和边距
#define UI_VBOX_GAP "5" // 垂直布局项间隙
#define UI_VBOX_MARGIN "0x0" // 垂直布局外边距
#define UI_VBOX_ALL_MARGIN "10x10" // 垂直布局总外边距
#define UI_VBOX_ALL_GAP "5" // 垂直布局总间隙
#define UI_HBOX_GAP "10" // 水平布局项间隙
#define UI_HBOX_MARGIN "10x10" // 水平布局外边距
#define UI_HBOX_ALIGNMENT "ACENTER" // 水平布局对齐方式
#endif // CONFIG_H
+10
View File
@@ -3,6 +3,16 @@
#include <iup.h>
// 定义 Windows 消息常量
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049
#endif
// 消息过滤器常量
#ifndef MSGFLT_ADD
#define MSGFLT_ADD 1
#endif
// 注册表路径常量
#define REG_PATH_SYS L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
#define REG_PATH_USER L"Environment"
View File
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
#include "globals.h"
#include <windows.h>
#include <iup.h>
// 全局变量定义
StringList raw_sys_paths = {0};
StringList raw_user_paths = {0};
// 全局控件定义
Ihandle *dlg, *tabs_main, *list_sys, *list_user, *lbl_status; // 主窗口、标签页、系统路径列表、用户路径列表、状态标签
Ihandle *btn_new, *btn_edit, *btn_browse, *btn_del, *btn_up, *btn_down; // 右侧按钮
Ihandle *btn_ok, *btn_cancel, *btn_help; // 确认取消帮助按钮
Ihandle *btn_clean; // 一键清理按钮
Ihandle *txt_search; // 搜索框
+16 -26
View File
@@ -8,26 +8,15 @@
#include "registry.h"
#include "callbacks.h"
#include "ui.h"
#include "config.h"
// 定义 Windows 消息常量
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049
#endif
#ifndef MSGFLT_ADD
#define MSGFLT_ADD 1
#endif
// 全局变量定义
StringList raw_sys_paths = {0};
StringList raw_user_paths = {0};
// 全局控件定义
Ihandle *dlg, *tabs_main, *list_sys, *list_user, *lbl_status; // 主窗口、标签页、系统路径列表、用户路径列表、状态标签
Ihandle *btn_new, *btn_edit, *btn_browse, *btn_del, *btn_up, *btn_down; // 右侧按钮
Ihandle *btn_ok, *btn_cancel, *btn_help; // 确认取消帮助按钮
Ihandle *btn_clean; // 一键清理按钮
Ihandle *txt_search; // 搜索框
/*
!编译命令:
cmake -B build -G "MinGW Makefiles"
cmake --build build
!打包命令:
build_installer.bat
*/
// 主函数
int main(int argc, char **argv)
@@ -80,8 +69,8 @@ int main(int argc, char **argv)
// 上部布局:Tabs + 按钮
Ihandle *hbox_main = IupHbox(tabs_main, vbox_btns, NULL);
IupSetAttribute(hbox_main, "GAP", "10");
IupSetAttribute(hbox_main, "MARGIN", "10x10");
IupSetAttribute(hbox_main, "GAP", UI_HBOX_GAP);
IupSetAttribute(hbox_main, "MARGIN", UI_HBOX_MARGIN);
// 状态标签
lbl_status = IupLabel("状态: 就绪");
@@ -97,13 +86,14 @@ int main(int argc, char **argv)
hbox_main,
hbox_bottom,
NULL);
IupSetAttribute(vbox_all, "MARGIN", "10x10");
IupSetAttribute(vbox_all, "GAP", "5");
IupSetAttribute(vbox_all, "MARGIN", UI_VBOX_ALL_MARGIN);
IupSetAttribute(vbox_all, "GAP", UI_VBOX_ALL_GAP);
// 创建对话框
dlg = IupDialog(vbox_all);
IupSetAttribute(dlg, "TITLE", "编辑环境变量 (IUP版)");
IupSetAttribute(dlg, "SIZE", "500x400"); // 稍微调大一点
IupSetAttribute(dlg, "TITLE", APP_NAME); // 对话框标题
IupSetAttribute(dlg, "RASTERSIZE", UI_DLG_SIZE); // 对话框初始大小 (像素)
IupSetAttribute(dlg, "MINSIZE", UI_DLG_MINSIZE); // 对话框最小大小 (像素)
IupSetAttribute(dlg, "MINBOX", "NO");
IupSetAttribute(dlg, "MAXBOX", "NO");
@@ -111,7 +101,7 @@ int main(int argc, char **argv)
if (!check_admin())
{
IupMessage("警告", "程序未以管理员身份运行,您只能查看,无法保存更改!");
IupSetAttribute(dlg, "TITLE", "编辑环境变量 (只读模式)");
IupSetAttribute(dlg, "TITLE", APP_NAME_READONLY); // 对话框标题 (只读模式)
IupSetAttribute(lbl_status, "TITLE", "状态: 只读模式 (权限不足)");
// 禁用修改类按钮
+19 -18
View File
@@ -1,6 +1,7 @@
#include "ui.h"
#include "globals.h"
#include "callbacks.h"
#include "config.h"
#include <stdlib.h>
// 创建列表控件
@@ -8,8 +9,8 @@ Ihandle *create_path_list()
{
Ihandle *list = IupFlatList();
IupSetAttribute(list, "EXPAND", "YES");
IupSetAttribute(list, "ITEMPADDING", "5x5");
IupSetAttribute(list, "BACKCOLOR", "255 255 255");
IupSetAttribute(list, "ITEMPADDING", UI_LIST_ITEM_PADDING);
IupSetAttribute(list, "BACKCOLOR", UI_LIST_BACKCOLOR);
IupSetAttribute(list, "BORDER", "YES");
IupSetAttribute(list, "CANFOCUS", "YES");
IupSetAttribute(list, "HLINE", "NO");
@@ -40,14 +41,14 @@ Ihandle *create_main_buttons()
IupSetCallback(btn_down, "ACTION", (Icallback)btn_down_cb);
IupSetCallback(btn_clean, "ACTION", (Icallback)btn_clean_cb);
// 设置按钮大小 (宽度和高度都增加约1/4)
IupSetAttribute(btn_new, "RASTERSIZE", "100x32");
IupSetAttribute(btn_edit, "RASTERSIZE", "100x32");
IupSetAttribute(btn_browse, "RASTERSIZE", "100x32");
IupSetAttribute(btn_del, "RASTERSIZE", "100x32");
IupSetAttribute(btn_up, "RASTERSIZE", "100x32");
IupSetAttribute(btn_down, "RASTERSIZE", "100x32");
IupSetAttribute(btn_clean, "RASTERSIZE", "100x32");
// 设置按钮大小
IupSetAttribute(btn_new, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_edit, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_browse, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_del, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_up, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_down, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_clean, "RASTERSIZE", UI_BTN_RASTERSIZE);
Ihandle *vbox_btns = IupVbox(
btn_new, btn_edit, btn_browse, btn_del,
@@ -56,8 +57,8 @@ Ihandle *create_main_buttons()
IupFill(),
btn_up, btn_down,
NULL);
IupSetAttribute(vbox_btns, "GAP", "5");
IupSetAttribute(vbox_btns, "MARGIN", "0x0");
IupSetAttribute(vbox_btns, "GAP", UI_VBOX_GAP);
IupSetAttribute(vbox_btns, "MARGIN", UI_VBOX_MARGIN);
return vbox_btns;
}
@@ -74,14 +75,14 @@ Ihandle *create_bottom_buttons()
IupSetCallback(btn_cancel, "ACTION", (Icallback)btn_cancel_cb);
IupSetCallback(btn_help, "ACTION", (Icallback)btn_help_cb);
IupSetAttribute(btn_ok, "RASTERSIZE", "100x32");
IupSetAttribute(btn_cancel, "RASTERSIZE", "100x32");
IupSetAttribute(btn_help, "RASTERSIZE", "100x32");
IupSetAttribute(btn_ok, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_cancel, "RASTERSIZE", UI_BTN_RASTERSIZE);
IupSetAttribute(btn_help, "RASTERSIZE", UI_BTN_RASTERSIZE);
Ihandle *hbox_bottom = IupHbox(lbl_status, IupFill(), btn_help, btn_ok, btn_cancel, NULL);
IupSetAttribute(hbox_bottom, "GAP", "10");
IupSetAttribute(hbox_bottom, "MARGIN", "10x10");
IupSetAttribute(hbox_bottom, "ALIGNMENT", "ACENTER");
IupSetAttribute(hbox_bottom, "GAP", UI_HBOX_GAP);
IupSetAttribute(hbox_bottom, "MARGIN", UI_HBOX_MARGIN);
IupSetAttribute(hbox_bottom, "ALIGNMENT", UI_HBOX_ALIGNMENT);
return hbox_bottom;
}