#include #include #include #include #define MAX_LINE_LEN 2048 #define MAX_PARAMS 16 #define MAX_NAME_LEN 64 typedef struct { char type[MAX_NAME_LEN]; char name[MAX_NAME_LEN]; } ParamInfo; // 辅助函数:去除两端空格 void trim(char *str) { char *end; while (isspace((unsigned char)*str)) str++; if (*str == 0) return; end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) end--; *(end + 1) = '\0'; memmove(str - (str - (str + (isspace((unsigned char)*str) ? 1 : 0))), str, strlen(str) + 1); } // 辅助函数:精准提取类型强转 // 例如:"(int)(short)LOWORD(lParam)" -> 提取出 "int" // 如果只是 "(hwnd)",由于 hwnd 是变量名而非合法类型,会通过 default_name 转换成 "HWND" void extract_first_type(const char *src, char *dest, const char *default_name) { dest[0] = '\0'; const char *p = src; // 跳过前面的空格 while (*p && isspace((unsigned char)*p)) p++; if (*p == '(') { p++; // 进入第一个左括号 int i = 0; while (*p && *p != ')') { dest[i++] = *p++; } dest[i] = '\0'; trim(dest); } // 关键修正:如果提取出来的“类型”和变量名一样(例如把 (hwnd) 误判为类型为 hwnd),或者为空 // 则通过名字来给它赋予 Windows 标准类型 if (strlen(dest) == 0 || strcmp(dest, default_name) == 0 || strcmp(dest, "fn") == 0) { if (strstr(default_name, "hwnd")) strcpy(dest, "HWND"); else if (strstr(default_name, "lParam")) strcpy(dest, "LPARAM"); else if (strstr(default_name, "wParam")) strcpy(dest, "WPARAM"); else if (strstr(default_name, "vk")) strcpy(dest, "UINT"); else strcpy(dest, "int"); // 默认兜底 } } // 核心解析函数 void process_macros(const char *handle_line, const char *forward_line) { char msg_name[MAX_NAME_LEN] = {0}; char return_type[MAX_NAME_LEN] = {0}; // 1. 提取 MsgName char *msg_pos = strstr(handle_line, "HANDLE_WM_"); if (!msg_pos) return; msg_pos += 10; int len = 0; while (isalnum((unsigned char)msg_pos[len]) || msg_pos[len] == '_') { msg_name[len] = msg_pos[len]; len++; } msg_name[len] = '\0'; // 2. 提取 FORWARD_WM_xxx 宏括号定义中的所有参数名 char forward_search[MAX_NAME_LEN + 20]; sprintf(forward_search, "FORWARD_WM_%s(", msg_name); char *f_param_start = strstr(forward_line, forward_search); if (!f_param_start) return; f_param_start += strlen(forward_search); char f_params_buf[MAX_LINE_LEN] = {0}; int f_len = 0; int f_depth = 1; // 严格按括号匹配提取参数声明区间,避免被后续宏体干扰 while (f_param_start[f_len] && f_depth > 0) { if (f_param_start[f_len] == '(') f_depth++; if (f_param_start[f_len] == ')') f_depth--; if (f_depth > 0) { f_params_buf[f_len] = f_param_start[f_len]; f_len++; } } f_params_buf[f_len] = '\0'; // 切分 FORWARD 宏头部的参数名 char f_param_names[MAX_PARAMS][MAX_NAME_LEN]; int f_param_count = 0; // 修正点:手动切分逗号,不使用会破坏内部状态的 strtok char *f_ptr = f_params_buf; char *f_comma; while ((f_comma = strchr(f_ptr, ',')) != NULL && f_param_count < MAX_PARAMS) { *f_comma = '\0'; trim(f_ptr); if (strcmp(f_ptr, "fn") != 0 && strlen(f_ptr) > 0) { strcpy(f_param_names[f_param_count++], f_ptr); } f_ptr = f_comma + 1; } trim(f_ptr); if (strcmp(f_ptr, "fn") != 0 && strlen(f_ptr) > 0) { strcpy(f_param_names[f_param_count++], f_ptr); } // 3. 解析 return_type char *fn_pos = strstr(forward_line, "(fn)"); if (fn_pos) { char *search_start = strstr(forward_line, forward_search); if (search_start) { char *body_start = strchr(search_start, ')'); if (body_start && body_start < fn_pos) { char return_buf[MAX_LINE_LEN] = {0}; strncpy(return_buf, body_start + 1, fn_pos - (body_start + 1)); return_buf[fn_pos - (body_start + 1)] = '\0'; extract_first_type(return_buf, return_type, ""); } } } if (strlen(return_type) == 0 || strcmp(return_type, "void") == 0) { strcpy(return_type, "void"); } // 4 & 5 & 6. 解析 HANDLE_WM_xxx 中 fn(...) 内部调用 char *fn_call = strstr(handle_line, "(fn)("); if (!fn_call) fn_call = strstr(handle_line, "fn("); ParamInfo final_params[MAX_PARAMS]; int final_param_count = 0; if (fn_call) { if (strncmp(fn_call, "(fn)(", 5) == 0) { fn_call += 5; // 移动到 (fn)( 之后的具体参数部分 } else { fn_call += 3; // 移动到 fn( 之后的具体参数部分 } // 匹配提取出整个括号内的参数段表达式 char h_body_buf[MAX_LINE_LEN] = {0}; int h_depth = 1; int h_idx = 0; while (fn_call[h_idx] && h_depth > 0) { if (fn_call[h_idx] == '(') h_depth++; if (fn_call[h_idx] == ')') h_depth--; if (h_depth > 0) { h_body_buf[h_idx] = fn_call[h_idx]; h_idx++; } } h_body_buf[h_idx] = '\0'; // 核心修正:按照外层零嵌套深度的逗号切分出各个独立的传参表达式 char *expressions[MAX_PARAMS]; int exp_count = 0; char *start = h_body_buf; int depth_count = 0; for (int i = 0; h_body_buf[i] != '\0'; i++) { if (h_body_buf[i] == '(') depth_count++; else if (h_body_buf[i] == ')') depth_count--; else if (h_body_buf[i] == ',' && depth_count == 0) { h_body_buf[i] = '\0'; expressions[exp_count++] = start; start = &h_body_buf[i + 1]; } } expressions[exp_count++] = start; // 根据表达式与 FORWARD 的名字进行最终映射与插入 int f_idx = 0; for (int i = 0; i < exp_count; i++) { trim(expressions[i]); if (strlen(expressions[i]) == 0) continue; // 4. 对 HANDLE_WM_xxx 中 TRUE 所在位置,直接生成 fBool 参数名插入 if (strcmp(expressions[i], "TRUE") == 0 || strcmp(expressions[i], "FALSE") == 0) { strcpy(final_params[final_param_count].name, "fBool"); strcpy(final_params[final_param_count].type, "WINBOOL"); final_param_count++; } else { if (f_idx < f_param_count) { strcpy(final_params[final_param_count].name, f_param_names[f_idx]); // 5 & 6. 提取每个参数对应的真实强转类型 char parsed_type[MAX_NAME_LEN] = {0}; extract_first_type(expressions[i], parsed_type, f_param_names[f_idx]); strcpy(final_params[final_param_count].type, parsed_type); final_param_count++; f_idx++; } } } } // 7. 生成格式化内容输出 printf("#define c_WinGUI_EventFn_WM_%s(fn) \\\n %s fn(", msg_name, return_type); for (int i = 0; i < final_param_count; i++) { printf("%s %s", final_params[i].type, final_params[i].name); if (i < final_param_count - 1) { printf(", "); } } printf(")\n\n"); } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "使用方法: %s \n", argv[0]); return 1; } FILE *fp = fopen(argv[1], "r"); if (!fp) { perror("打不开文件"); return 1; } char line[MAX_LINE_LEN]; char cached_handle[MAX_LINE_LEN] = {0}; char current_msg[MAX_NAME_LEN] = {0}; while (fgets(line, sizeof(line), fp)) { line[strcspn(line, "\r\n")] = 0; if (strstr(line, "#define HANDLE_WM_")) { strcpy(cached_handle, line); char *p = strstr(line, "HANDLE_WM_") + 10; int idx = 0; while (isalnum((unsigned char)p[idx]) || p[idx] == '_') { current_msg[idx] = p[idx]; idx++; } current_msg[idx] = '\0'; } else if (strstr(line, "#define FORWARD_WM_")) { if (strlen(current_msg) > 0 && strstr(line, current_msg)) { process_macros(cached_handle, line); cached_handle[0] = '\0'; current_msg[0] = '\0'; } } } fclose(fp); return 0; }