mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-05-10 02:09:46 +08:00
feat(ui): 统一管理IUP控件名称常量,增强可维护性
refactor(core): 移除未使用的get_app_context函数 refactor(os_env): 修改backup_registry函数以返回错误码并备份到指定目录 refactor(path_manager): 增强路径管理函数的错误处理
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
#define APP_CONTEXT_H
|
||||
|
||||
#include "utils/string_ext.h"
|
||||
#include <iup.h>
|
||||
|
||||
// 应用上下文结构体,用于存储应用运行时的状态
|
||||
typedef struct {
|
||||
@@ -16,7 +15,4 @@ AppContext* create_app_context(void);
|
||||
// 销毁应用上下文
|
||||
void destroy_app_context(AppContext* ctx);
|
||||
|
||||
// 获取应用上下文
|
||||
AppContext* get_app_context(Ihandle *ih);
|
||||
|
||||
#endif // APP_CONTEXT_H
|
||||
|
||||
@@ -5,9 +5,16 @@
|
||||
#include "utils/string_ext.h"
|
||||
|
||||
// 刷新单个列表框样式
|
||||
// 功能说明:
|
||||
// 1. 路径有效性检查:无效路径显示红色前景色 (255 0 0)
|
||||
// 2. 重复检查:重复路径显示橙色前景色 (255 128 0),只检查当前项之前的项
|
||||
// 3. 斑马纹背景:奇偶行交替显示不同背景色 (白/灰)
|
||||
// 注意: 该函数需要IUP控件已设置NAME属性
|
||||
void refresh_single_list_style(Ihandle *list);
|
||||
|
||||
// 同步字符串列表到 UI 列表框
|
||||
// 将StringList中的所有项同步到IUP FlatList控件中
|
||||
// 会先清空列表然后重新添加所有项,最后刷新样式
|
||||
void sync_string_list_to_ui(Ihandle *list_ui, const StringList *str_list);
|
||||
|
||||
#endif // UI_UTILS_H
|
||||
|
||||
@@ -11,7 +11,8 @@ typedef enum {
|
||||
ERR_INVALID_FORMAT = -6, // 无效格式
|
||||
ERR_REGISTRY_FAILED = -7, // 注册表操作失败
|
||||
ERR_NOT_FOUND = -8, // 未找到
|
||||
ERR_EXISTS = -9 // 已存在
|
||||
ERR_EXISTS = -9, // 已存在
|
||||
ERR_INVALID_INDEX = -10 // 无效索引
|
||||
} ErrorCode;
|
||||
|
||||
const char* error_code_to_string(ErrorCode code);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef OS_ENV_H
|
||||
#define OS_ENV_H
|
||||
|
||||
#include "utils/error_code.h"
|
||||
|
||||
// 检查是否以管理员权限运行
|
||||
int check_admin(void);
|
||||
|
||||
@@ -8,6 +10,6 @@ int check_admin(void);
|
||||
int is_path_valid(const char *path);
|
||||
|
||||
// 备份注册表
|
||||
void backup_registry(void);
|
||||
ErrorCode backup_registry(void);
|
||||
|
||||
#endif // OS_ENV_H
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef UI_CONSTANTS_H
|
||||
#define UI_CONSTANTS_H
|
||||
|
||||
// 缓冲区大小常量
|
||||
#define PATH_BUFFER_SIZE 4096
|
||||
|
||||
// 控件名称常量 - 统一管理所有IUP控件名称字符串
|
||||
// 使用这些常量替代硬编码字符串,便于维护和减少拼写错误
|
||||
|
||||
// 列表控件
|
||||
#define CTRL_LIST_SYS "LIST_SYS"
|
||||
#define CTRL_LIST_USER "LIST_USER"
|
||||
|
||||
// 选项卡
|
||||
#define CTRL_TABS_MAIN "TABS_MAIN"
|
||||
|
||||
// 搜索框
|
||||
#define CTRL_TXT_SEARCH "TXT_SEARCH"
|
||||
|
||||
// 状态标签
|
||||
#define CTRL_LBL_STATUS "LBL_STATUS"
|
||||
|
||||
// 操作按钮
|
||||
#define CTRL_BTN_NEW "BTN_NEW"
|
||||
#define CTRL_BTN_EDIT "BTN_EDIT"
|
||||
#define CTRL_BTN_BROWSE "BTN_BROWSE"
|
||||
#define CTRL_BTN_DEL "BTN_DEL"
|
||||
#define CTRL_BTN_UP "BTN_UP"
|
||||
#define CTRL_BTN_DOWN "BTN_DOWN"
|
||||
#define CTRL_BTN_CLEAN "BTN_CLEAN"
|
||||
#define CTRL_BTN_IMPORT "BTN_IMPORT"
|
||||
#define CTRL_BTN_EXPORT "BTN_EXPORT"
|
||||
#define CTRL_BTN_OK "BTN_OK"
|
||||
#define CTRL_BTN_CANCEL "BTN_CANCEL"
|
||||
#define CTRL_BTN_HELP "BTN_HELP"
|
||||
#define CTRL_BTN_LANG "BTN_LANG"
|
||||
|
||||
#endif // UI_CONSTANTS_H
|
||||
+34
-27
@@ -10,6 +10,7 @@
|
||||
#include "utils/safe_string.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/i18n.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include "ui/dialogs.h"
|
||||
#include "ui/main_window.h"
|
||||
@@ -21,19 +22,25 @@
|
||||
// 辅助函数:获取主对话框
|
||||
static Ihandle *get_main_dlg()
|
||||
{
|
||||
// 在实际情况中,可以通过 IupGetHandle 注册名字,或者通过某个全局/静态缓存
|
||||
// 但如果想彻底不用全局,我们可以在 IupSetHandle 里面把主窗口存下来
|
||||
return IupGetHandle("MAIN_DIALOG");
|
||||
}
|
||||
|
||||
// 辅助函数:从对话框获取应用上下文(core层不依赖IUP,因此在此实现)
|
||||
static AppContext *get_app_context_from_dlg(Ihandle *dlg)
|
||||
{
|
||||
if (!dlg)
|
||||
return NULL;
|
||||
return (AppContext *)IupGetAttribute(dlg, "APP_CONTEXT");
|
||||
}
|
||||
|
||||
// 获取当前的缓存数据列表
|
||||
static StringList *get_current_raw_data(Ihandle *dlg)
|
||||
{
|
||||
AppContext *ctx = get_app_context(dlg);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
Ihandle *tabs_main = IupGetDialogChild(dlg, "TABS_MAIN");
|
||||
Ihandle *tabs_main = IupGetDialogChild(dlg, CTRL_TABS_MAIN);
|
||||
int pos = IupGetInt(tabs_main, "VALUEPOS");
|
||||
if (pos == 0)
|
||||
return &ctx->sys_paths;
|
||||
@@ -45,20 +52,20 @@ static StringList *get_current_raw_data(Ihandle *dlg)
|
||||
// 辅助函数:获取当前选中的列表UI控件
|
||||
static Ihandle *get_current_list(Ihandle *dlg)
|
||||
{
|
||||
Ihandle *tabs_main = IupGetDialogChild(dlg, "TABS_MAIN");
|
||||
Ihandle *tabs_main = IupGetDialogChild(dlg, CTRL_TABS_MAIN);
|
||||
int pos = IupGetInt(tabs_main, "VALUEPOS");
|
||||
if (pos == 0)
|
||||
return IupGetDialogChild(dlg, "LIST_SYS");
|
||||
return IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
if (pos == 1)
|
||||
return IupGetDialogChild(dlg, "LIST_USER");
|
||||
return IupGetDialogChild(dlg, "LIST_SYS");
|
||||
return IupGetDialogChild(dlg, CTRL_LIST_USER);
|
||||
return IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
}
|
||||
|
||||
// 按钮回调:新建
|
||||
int btn_new_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
char buffer[1024] = "";
|
||||
char buffer[PATH_BUFFER_SIZE] = "";
|
||||
if (custom_input_dialog("新建环境变量", "请输入路径:", buffer, sizeof(buffer)))
|
||||
{
|
||||
if (strlen(buffer) > 0)
|
||||
@@ -89,7 +96,7 @@ int btn_edit_cb(Ihandle *self)
|
||||
if (selected - 1 >= raw_data->count)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
char buffer[4096];
|
||||
char buffer[PATH_BUFFER_SIZE];
|
||||
safe_strcpy(buffer, sizeof(buffer), raw_data->items[selected - 1]);
|
||||
|
||||
if (custom_input_dialog("编辑环境变量", "编辑路径:", buffer, sizeof(buffer)))
|
||||
@@ -168,7 +175,7 @@ int btn_del_cb(Ihandle *self)
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, "LBL_STATUS");
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "deleted"));
|
||||
|
||||
@@ -280,14 +287,14 @@ int list_dropfiles_cb(Ihandle *self, const char *filename, int num, int x, int y
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = self;
|
||||
AppContext *ctx = get_app_context(dlg);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = NULL;
|
||||
if (self == IupGetDialogChild(dlg, "LIST_SYS"))
|
||||
if (self == IupGetDialogChild(dlg, CTRL_LIST_SYS))
|
||||
raw_data = &ctx->sys_paths;
|
||||
else if (self == IupGetDialogChild(dlg, "LIST_USER"))
|
||||
else if (self == IupGetDialogChild(dlg, CTRL_LIST_USER))
|
||||
raw_data = &ctx->user_paths;
|
||||
else
|
||||
return IUP_DEFAULT;
|
||||
@@ -295,7 +302,7 @@ int list_dropfiles_cb(Ihandle *self, const char *filename, int num, int x, int y
|
||||
DWORD attr = GetFileAttributesA(filename);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
Ihandle *txt_search = IupGetDialogChild(dlg, "TXT_SEARCH");
|
||||
Ihandle *txt_search = IupGetDialogChild(dlg, CTRL_TXT_SEARCH);
|
||||
if (txt_search)
|
||||
IupSetAttribute(txt_search, "VALUE", "");
|
||||
|
||||
@@ -306,7 +313,7 @@ int list_dropfiles_cb(Ihandle *self, const char *filename, int num, int x, int y
|
||||
}
|
||||
else
|
||||
{
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, "LBL_STATUS");
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "drag_folder_only"));
|
||||
}
|
||||
@@ -329,7 +336,7 @@ int list_k_any_cb(Ihandle *self, int c)
|
||||
int btn_ok_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context(dlg);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
@@ -344,7 +351,7 @@ int btn_ok_cb(Ihandle *self)
|
||||
ErrorCode sys_ok = save_system_paths(&ctx->sys_paths);
|
||||
ErrorCode user_ok = save_user_paths(&ctx->user_paths);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, "LBL_STATUS");
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
|
||||
if (sys_ok == ERR_OK && user_ok == ERR_OK)
|
||||
{
|
||||
@@ -383,7 +390,7 @@ int btn_cancel_cb(Ihandle *self)
|
||||
int btn_import_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context(dlg);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
@@ -443,7 +450,7 @@ int btn_import_cb(Ihandle *self)
|
||||
{
|
||||
add_string_list(&ctx->sys_paths, imported.system.items[i]);
|
||||
}
|
||||
Ihandle *list_sys = IupGetDialogChild(dlg, "LIST_SYS");
|
||||
Ihandle *list_sys = IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
sync_string_list_to_ui(list_sys, &ctx->sys_paths);
|
||||
total_imported += imported.system.count;
|
||||
}
|
||||
@@ -455,7 +462,7 @@ int btn_import_cb(Ihandle *self)
|
||||
{
|
||||
add_string_list(&ctx->user_paths, imported.user.items[i]);
|
||||
}
|
||||
Ihandle *list_user = IupGetDialogChild(dlg, "LIST_USER");
|
||||
Ihandle *list_user = IupGetDialogChild(dlg, CTRL_LIST_USER);
|
||||
sync_string_list_to_ui(list_user, &ctx->user_paths);
|
||||
total_imported += imported.user.count;
|
||||
}
|
||||
@@ -464,7 +471,7 @@ int btn_import_cb(Ihandle *self)
|
||||
snprintf(msg, sizeof(msg), "成功导入 %d 个路径!", total_imported);
|
||||
IupMessage("导入成功", msg);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, "LBL_STATUS");
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "loaded"));
|
||||
}
|
||||
@@ -483,7 +490,7 @@ int btn_import_cb(Ihandle *self)
|
||||
int btn_export_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context(dlg);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
@@ -545,7 +552,7 @@ void load_all_paths(void)
|
||||
Ihandle *dlg = get_main_dlg();
|
||||
if (!dlg)
|
||||
return;
|
||||
AppContext *ctx = get_app_context(dlg);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
@@ -565,13 +572,13 @@ void load_all_paths(void)
|
||||
log_info("Loaded user paths: %d", ctx->user_paths.count);
|
||||
}
|
||||
|
||||
Ihandle *list_sys = IupGetDialogChild(dlg, "LIST_SYS");
|
||||
Ihandle *list_user = IupGetDialogChild(dlg, "LIST_USER");
|
||||
Ihandle *list_sys = IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
Ihandle *list_user = IupGetDialogChild(dlg, CTRL_LIST_USER);
|
||||
|
||||
sync_string_list_to_ui(list_sys, &ctx->sys_paths);
|
||||
sync_string_list_to_ui(list_user, &ctx->user_paths);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, "LBL_STATUS");
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "loaded"));
|
||||
}
|
||||
|
||||
@@ -23,14 +23,3 @@ void destroy_app_context(AppContext *ctx)
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取应用上下文
|
||||
AppContext *get_app_context(Ihandle *ih)
|
||||
{
|
||||
if (!ih)
|
||||
return NULL;
|
||||
Ihandle *dlg = IupGetDialog(ih);
|
||||
if (!dlg)
|
||||
return NULL;
|
||||
return (AppContext *)IupGetAttribute(dlg, "APP_CONTEXT");
|
||||
}
|
||||
@@ -8,8 +8,10 @@
|
||||
// 删除指定索引的路径项
|
||||
ErrorCode path_manager_remove_at(StringList *list, int index)
|
||||
{
|
||||
if (!list || index < 0 || index >= list->count)
|
||||
if (!list)
|
||||
return ERR_NULL_PTR;
|
||||
if (index < 0 || index >= list->count)
|
||||
return ERR_INVALID_INDEX;
|
||||
|
||||
free(list->items[index]);
|
||||
for (int i = index; i < list->count - 1; i++)
|
||||
@@ -24,8 +26,10 @@ ErrorCode path_manager_remove_at(StringList *list, int index)
|
||||
// 向上移动路径项
|
||||
ErrorCode path_manager_move_up(StringList *list, int index)
|
||||
{
|
||||
if (!list || index <= 0 || index >= list->count)
|
||||
if (!list)
|
||||
return ERR_NULL_PTR;
|
||||
if (index <= 0 || index >= list->count)
|
||||
return ERR_INVALID_INDEX;
|
||||
|
||||
char *temp = list->items[index];
|
||||
list->items[index] = list->items[index - 1];
|
||||
@@ -36,8 +40,10 @@ ErrorCode path_manager_move_up(StringList *list, int index)
|
||||
// 向下移动路径项
|
||||
ErrorCode path_manager_move_down(StringList *list, int index)
|
||||
{
|
||||
if (!list || index < 0 || index >= list->count - 1)
|
||||
if (!list)
|
||||
return ERR_NULL_PTR;
|
||||
if (index < 0 || index >= list->count - 1)
|
||||
return ERR_INVALID_INDEX;
|
||||
|
||||
char *temp = list->items[index];
|
||||
list->items[index] = list->items[index + 1];
|
||||
|
||||
+18
-33
@@ -5,7 +5,16 @@
|
||||
#include <wchar.h>
|
||||
#include <libintl.h>
|
||||
#include "core/app_context.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "core/lua_config.h"
|
||||
|
||||
// 需要在非管理员模式禁用的按钮列表
|
||||
#define ADMIN_DISABLE_COUNT 10
|
||||
static const char* ADMIN_DISABLE_BUTTONS[] = {
|
||||
CTRL_BTN_NEW, CTRL_BTN_EDIT, CTRL_BTN_BROWSE, CTRL_BTN_DEL,
|
||||
CTRL_BTN_UP, CTRL_BTN_DOWN, CTRL_BTN_CLEAN, CTRL_BTN_OK,
|
||||
CTRL_BTN_IMPORT, CTRL_BTN_EXPORT
|
||||
};
|
||||
#include "utils/string_ext.h"
|
||||
#include "utils/os_env.h"
|
||||
#include "utils/logger.h"
|
||||
@@ -98,42 +107,18 @@ int main(int argc, char **argv)
|
||||
{
|
||||
IupMessage(_("Warning"), _(lua_config_get_string("status", "admin_warning")));
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, "LBL_STATUS");
|
||||
// 设置只读状态提示
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", _(lua_config_get_string("status", "readonly")));
|
||||
|
||||
Ihandle *btn_new = IupGetDialogChild(dlg, "BTN_NEW");
|
||||
Ihandle *btn_edit = IupGetDialogChild(dlg, "BTN_EDIT");
|
||||
Ihandle *btn_browse = IupGetDialogChild(dlg, "BTN_BROWSE");
|
||||
Ihandle *btn_del = IupGetDialogChild(dlg, "BTN_DEL");
|
||||
Ihandle *btn_up = IupGetDialogChild(dlg, "BTN_UP");
|
||||
Ihandle *btn_down = IupGetDialogChild(dlg, "BTN_DOWN");
|
||||
Ihandle *btn_clean = IupGetDialogChild(dlg, "BTN_CLEAN");
|
||||
Ihandle *btn_ok = IupGetDialogChild(dlg, "BTN_OK");
|
||||
|
||||
if (btn_new)
|
||||
IupSetAttribute(btn_new, "ACTIVE", "NO");
|
||||
if (btn_edit)
|
||||
IupSetAttribute(btn_edit, "ACTIVE", "NO");
|
||||
if (btn_browse)
|
||||
IupSetAttribute(btn_browse, "ACTIVE", "NO");
|
||||
if (btn_del)
|
||||
IupSetAttribute(btn_del, "ACTIVE", "NO");
|
||||
if (btn_up)
|
||||
IupSetAttribute(btn_up, "ACTIVE", "NO");
|
||||
if (btn_down)
|
||||
IupSetAttribute(btn_down, "ACTIVE", "NO");
|
||||
if (btn_clean)
|
||||
IupSetAttribute(btn_clean, "ACTIVE", "NO");
|
||||
if (btn_ok)
|
||||
IupSetAttribute(btn_ok, "ACTIVE", "NO");
|
||||
|
||||
Ihandle *btn_import = IupGetDialogChild(dlg, "BTN_IMPORT");
|
||||
Ihandle *btn_export = IupGetDialogChild(dlg, "BTN_EXPORT");
|
||||
if (btn_import)
|
||||
IupSetAttribute(btn_import, "ACTIVE", "NO");
|
||||
if (btn_export)
|
||||
IupSetAttribute(btn_export, "ACTIVE", "NO");
|
||||
// 禁用所有需要管理员权限的按钮
|
||||
for (int i = 0; i < ADMIN_DISABLE_COUNT; i++)
|
||||
{
|
||||
Ihandle *btn = IupGetDialogChild(dlg, ADMIN_DISABLE_BUTTONS[i]);
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "ACTIVE", "NO");
|
||||
}
|
||||
}
|
||||
|
||||
IupShowXY(dlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
+44
-66
@@ -2,6 +2,7 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "utils/i18n.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -26,13 +27,13 @@ static Ihandle *create_path_list(const char *name)
|
||||
Ihandle *create_main_window(void)
|
||||
{
|
||||
// 创建系统路径列表
|
||||
Ihandle *list_sys = create_path_list("LIST_SYS");
|
||||
Ihandle *list_sys = create_path_list(CTRL_LIST_SYS);
|
||||
// 创建用户路径列表
|
||||
Ihandle *list_user = create_path_list("LIST_USER");
|
||||
Ihandle *list_user = create_path_list(CTRL_LIST_USER);
|
||||
|
||||
// 创建搜索框
|
||||
Ihandle *txt_search = IupText(NULL);
|
||||
IupSetAttribute(txt_search, "NAME", "TXT_SEARCH");
|
||||
IupSetAttribute(txt_search, "NAME", CTRL_TXT_SEARCH);
|
||||
IupSetAttribute(txt_search, "EXPAND", "HORIZONTAL");
|
||||
IupSetAttribute(txt_search, "CUEBANNER", lua_config_get_string("label", "search_placeholder"));
|
||||
IupSetCallback(txt_search, "VALUECHANGED_CB", (Icallback)txt_search_cb);
|
||||
@@ -42,42 +43,42 @@ Ihandle *create_main_window(void)
|
||||
IupVbox(list_sys, NULL),
|
||||
IupVbox(list_user, NULL),
|
||||
NULL);
|
||||
IupSetAttribute(tabs_main, "NAME", "TABS_MAIN");
|
||||
IupSetAttribute(tabs_main, "NAME", CTRL_TABS_MAIN);
|
||||
IupSetAttribute(tabs_main, "TABTITLE0", _(lua_config_get_string("label", "tab_sys")));
|
||||
IupSetAttribute(tabs_main, "TABTITLE1", _(lua_config_get_string("label", "tab_user")));
|
||||
IupSetAttribute(tabs_main, "TABTYPE", "TOP");
|
||||
|
||||
// 创建操作按钮
|
||||
Ihandle *btn_new = IupButton(_(lua_config_get_string("button", "new")), NULL);
|
||||
IupSetAttribute(btn_new, "NAME", "BTN_NEW");
|
||||
IupSetAttribute(btn_new, "NAME", CTRL_BTN_NEW);
|
||||
|
||||
Ihandle *btn_edit = IupButton(_(lua_config_get_string("button", "edit")), NULL);
|
||||
IupSetAttribute(btn_edit, "NAME", "BTN_EDIT");
|
||||
IupSetAttribute(btn_edit, "NAME", CTRL_BTN_EDIT);
|
||||
|
||||
Ihandle *btn_browse = IupButton(_(lua_config_get_string("button", "browse")), NULL);
|
||||
IupSetAttribute(btn_browse, "NAME", "BTN_BROWSE");
|
||||
IupSetAttribute(btn_browse, "NAME", CTRL_BTN_BROWSE);
|
||||
|
||||
Ihandle *btn_del = IupButton(_(lua_config_get_string("button", "del")), NULL);
|
||||
IupSetAttribute(btn_del, "NAME", "BTN_DEL");
|
||||
IupSetAttribute(btn_del, "NAME", CTRL_BTN_DEL);
|
||||
|
||||
Ihandle *btn_up = IupButton(_(lua_config_get_string("button", "up")), NULL);
|
||||
IupSetAttribute(btn_up, "NAME", "BTN_UP");
|
||||
IupSetAttribute(btn_up, "NAME", CTRL_BTN_UP);
|
||||
|
||||
Ihandle *btn_down = IupButton(_(lua_config_get_string("button", "down")), NULL);
|
||||
IupSetAttribute(btn_down, "NAME", "BTN_DOWN");
|
||||
IupSetAttribute(btn_down, "NAME", CTRL_BTN_DOWN);
|
||||
|
||||
Ihandle *btn_clean = IupButton(_(lua_config_get_string("button", "clean")), NULL);
|
||||
IupSetAttribute(btn_clean, "NAME", "BTN_CLEAN");
|
||||
IupSetAttribute(btn_clean, "NAME", CTRL_BTN_CLEAN);
|
||||
|
||||
Ihandle *btn_import = IupButton(_(lua_config_get_string("button", "import")), NULL);
|
||||
IupSetAttribute(btn_import, "NAME", "BTN_IMPORT");
|
||||
IupSetAttribute(btn_import, "NAME", CTRL_BTN_IMPORT);
|
||||
|
||||
Ihandle *btn_export = IupButton(_(lua_config_get_string("button", "export")), NULL);
|
||||
IupSetAttribute(btn_export, "NAME", "BTN_EXPORT");
|
||||
IupSetAttribute(btn_export, "NAME", CTRL_BTN_EXPORT);
|
||||
|
||||
// 创建语言切换按钮
|
||||
Ihandle *btn_lang = IupButton(_("Language"), NULL);
|
||||
IupSetAttribute(btn_lang, "NAME", "BTN_LANG");
|
||||
IupSetAttribute(btn_lang, "NAME", CTRL_BTN_LANG);
|
||||
IupSetCallback(btn_lang, "ACTION", (Icallback)btn_lang_cb);
|
||||
|
||||
// 设置按钮回调
|
||||
@@ -123,16 +124,16 @@ Ihandle *create_main_window(void)
|
||||
|
||||
// 创建状态标签
|
||||
Ihandle *lbl_status = IupLabel(lua_config_get_string("status", "normal"));
|
||||
IupSetAttribute(lbl_status, "NAME", "LBL_STATUS");
|
||||
IupSetAttribute(lbl_status, "NAME", CTRL_LBL_STATUS);
|
||||
IupSetAttribute(lbl_status, "EXPAND", "HORIZONTAL");
|
||||
|
||||
// 创建底部按钮
|
||||
Ihandle *btn_ok = IupButton(_(lua_config_get_string("button", "ok")), NULL);
|
||||
IupSetAttribute(btn_ok, "NAME", "BTN_OK");
|
||||
IupSetAttribute(btn_ok, "NAME", CTRL_BTN_OK);
|
||||
Ihandle *btn_cancel = IupButton(_(lua_config_get_string("button", "cancel")), NULL);
|
||||
IupSetAttribute(btn_cancel, "NAME", "BTN_CANCEL");
|
||||
IupSetAttribute(btn_cancel, "NAME", CTRL_BTN_CANCEL);
|
||||
Ihandle *btn_help = IupButton(_(lua_config_get_string("button", "help")), NULL);
|
||||
IupSetAttribute(btn_help, "NAME", "BTN_HELP");
|
||||
IupSetAttribute(btn_help, "NAME", CTRL_BTN_HELP);
|
||||
|
||||
// 设置底部按钮回调
|
||||
IupSetCallback(btn_ok, "ACTION", (Icallback)btn_ok_cb);
|
||||
@@ -176,60 +177,37 @@ void refresh_main_window_ui(Ihandle *main_dlg)
|
||||
if (!main_dlg)
|
||||
return;
|
||||
|
||||
// 设置窗口标题
|
||||
IupSetAttribute(main_dlg, "TITLE", _(lua_config_get_string("app", "name")));
|
||||
|
||||
// 设置选项卡标题
|
||||
IupSetAttribute(main_dlg, "TABTITLE0", _(lua_config_get_string("label", "tab_sys")));
|
||||
IupSetAttribute(main_dlg, "TABTITLE1", _(lua_config_get_string("label", "tab_user")));
|
||||
|
||||
Ihandle *btn = IupGetDialogChild(main_dlg, "BTN_NEW");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "new")));
|
||||
// 辅助函数:设置子控件标题
|
||||
#define SET_CHILD_TITLE(btn_name, text_key) \
|
||||
do { \
|
||||
Ihandle *btn = IupGetDialogChild(main_dlg, btn_name); \
|
||||
if (btn) IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", text_key))); \
|
||||
} while(0)
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_EDIT");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "edit")));
|
||||
SET_CHILD_TITLE(CTRL_BTN_NEW, "new");
|
||||
SET_CHILD_TITLE(CTRL_BTN_EDIT, "edit");
|
||||
SET_CHILD_TITLE(CTRL_BTN_BROWSE, "browse");
|
||||
SET_CHILD_TITLE(CTRL_BTN_DEL, "del");
|
||||
SET_CHILD_TITLE(CTRL_BTN_UP, "up");
|
||||
SET_CHILD_TITLE(CTRL_BTN_DOWN, "down");
|
||||
SET_CHILD_TITLE(CTRL_BTN_CLEAN, "clean");
|
||||
SET_CHILD_TITLE(CTRL_BTN_IMPORT, "import");
|
||||
SET_CHILD_TITLE(CTRL_BTN_EXPORT, "export");
|
||||
SET_CHILD_TITLE(CTRL_BTN_OK, "ok");
|
||||
SET_CHILD_TITLE(CTRL_BTN_CANCEL, "cancel");
|
||||
SET_CHILD_TITLE(CTRL_BTN_HELP, "help");
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_BROWSE");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "browse")));
|
||||
#undef SET_CHILD_TITLE
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_DEL");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "del")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_UP");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "up")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_DOWN");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "down")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_CLEAN");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "clean")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_IMPORT");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "import")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_EXPORT");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "export")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_LANG");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _("Language"));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_OK");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "ok")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_CANCEL");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "cancel")));
|
||||
|
||||
btn = IupGetDialogChild(main_dlg, "BTN_HELP");
|
||||
if (btn)
|
||||
IupSetAttribute(btn, "TITLE", _(lua_config_get_string("button", "help")));
|
||||
// 语言切换按钮标题单独处理(不是从配置读取)
|
||||
Ihandle *btn_lang = IupGetDialogChild(main_dlg, CTRL_BTN_LANG);
|
||||
if (btn_lang)
|
||||
IupSetAttribute(btn_lang, "TITLE", _("Language"));
|
||||
}
|
||||
+71
-29
@@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <direct.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
// 检查管理员权限
|
||||
int check_admin(void)
|
||||
@@ -45,46 +46,87 @@ int is_path_valid(const char *path)
|
||||
}
|
||||
|
||||
// 备份注册表
|
||||
void backup_registry(void)
|
||||
// 备份到 %APPDATA%/PathEditor/backups/ 目录下
|
||||
ErrorCode backup_registry(void)
|
||||
{
|
||||
// 创建 records 目录
|
||||
if (_mkdir("records") == -1)
|
||||
// 获取 AppData 路径
|
||||
wchar_t appdata_path[MAX_PATH];
|
||||
if (SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, appdata_path) != S_OK)
|
||||
{
|
||||
// 目录可能已存在,忽略错误
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
// 获取当前时间
|
||||
// 创建备份目录
|
||||
wchar_t backup_dir[MAX_PATH];
|
||||
swprintf(backup_dir, MAX_PATH, L"%s\\PathEditor\\backups", appdata_path);
|
||||
CreateDirectoryW(backup_dir, NULL);
|
||||
|
||||
// 生成时间戳
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm_info = localtime(&t);
|
||||
char time_str[64];
|
||||
strftime(time_str, sizeof(time_str), "%Y%m%d_%H%M%S", tm_info);
|
||||
wchar_t timestamp[64];
|
||||
wcsftime(timestamp, sizeof(timestamp), L"%Y%m%d_%H%M%S", tm_info);
|
||||
|
||||
// 构造备份文件名
|
||||
char filename[256];
|
||||
snprintf(filename, sizeof(filename), "records\\backup_%s.reg", time_str);
|
||||
wchar_t backup_file[MAX_PATH];
|
||||
swprintf(backup_file, MAX_PATH, L"%s\\path_backup_%s.txt", backup_dir, timestamp);
|
||||
|
||||
// 构造 reg export 命令
|
||||
char full_cmd[1024];
|
||||
snprintf(full_cmd, sizeof(full_cmd), "reg.exe export \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\" \"%s\" /y", filename);
|
||||
// 打开文件
|
||||
FILE *fp = _wfopen(backup_file, L"w, ccs=UTF-8");
|
||||
if (!fp)
|
||||
return ERR_FAILED;
|
||||
|
||||
// 使用 CreateProcess 隐藏窗口执行
|
||||
STARTUPINFOA si;
|
||||
PROCESS_INFORMATION pi;
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE; // 隐藏窗口
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
// 备份系统 PATH
|
||||
HKEY hKey;
|
||||
int success = 0;
|
||||
|
||||
if (CreateProcessA(NULL, full_cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
// 等待进程结束
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
DWORD exit_code = 0;
|
||||
GetExitCodeProcess(pi.hProcess, &exit_code);
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
DWORD type, size;
|
||||
if (RegQueryValueExW(hKey, L"Path", NULL, &type, NULL, &size) == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t *buffer = (wchar_t *)malloc(size + 2);
|
||||
if (buffer)
|
||||
{
|
||||
memset(buffer, 0, size + 2);
|
||||
if (RegQueryValueExW(hKey, L"Path", NULL, &type, (LPBYTE)buffer, &size) == ERROR_SUCCESS)
|
||||
{
|
||||
fwprintf(fp, L"# System PATH Backup\n");
|
||||
fwprintf(fp, L"%s\n\n", buffer);
|
||||
success = 1;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
// 备份用户 PATH
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER,
|
||||
L"Environment",
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD type, size;
|
||||
if (RegQueryValueExW(hKey, L"Path", NULL, &type, NULL, &size) == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t *buffer = (wchar_t *)malloc(size + 2);
|
||||
if (buffer)
|
||||
{
|
||||
memset(buffer, 0, size + 2);
|
||||
if (RegQueryValueExW(hKey, L"Path", NULL, &type, (LPBYTE)buffer, &size) == ERROR_SUCCESS)
|
||||
{
|
||||
fwprintf(fp, L"# User PATH Backup\n");
|
||||
fwprintf(fp, L"%s\n", buffer);
|
||||
success = 1;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return success ? ERR_OK : ERR_FAILED;
|
||||
}
|
||||
Reference in New Issue
Block a user