SlideCombine/slide_combine_simple.c

244 lines
7.8 KiB
C
Raw Permalink Normal View History

// 简化版PDF书签合并工具
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <shlwapi.h>
#include <commctrl.h>
#define MAX_PATH 1024
#define MAX_FILES 100
typedef struct {
char title[256];
char page[32];
} Bookmark;
typedef struct {
char folder[256];
Bookmark bookmarks[500];
int bookmark_count;
} FileData;
// 全局变量
char pdf_path[MAX_PATH] = "";
char txt_path[MAX_PATH] = "";
char output_path[MAX_PATH] = "";
// 函数声明
void log_message(HWND hwnd, const char* msg);
BOOL browse_folder(HWND hwnd, char* path);
void start_processing(HWND hwnd);
int extract_number(const char* str);
int compare_files(const void* a, const void* b);
// 简化的日志函数
void log_message(HWND hwnd, const char* msg) {
if (hwnd) {
HWND hLog = GetDlgItem(hwnd, 3001);
if (hLog) {
char full_msg[1024];
sprintf(full_msg, "%s\r\n", msg);
SendMessageA(hLog, EM_SETSEL, -1, -1);
SendMessageA(hLog, EM_REPLACESEL, FALSE, (LPARAM)full_msg);
}
}
printf("%s\n", msg);
}
// 简化的文件夹选择
BOOL browse_folder(HWND hwnd, char* path) {
BROWSEINFOA bi = {0};
bi.hwndOwner = hwnd;
bi.lpszTitle = "选择文件夹";
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
LPITEMIDLIST pidl = SHBrowseForFolderA(&bi);
if (pidl) {
if (SHGetPathFromIDListA(pidl, path)) {
CoTaskMemFree(pidl);
return TRUE;
}
CoTaskMemFree(pidl);
}
return FALSE;
}
// 提取文件名中的数字
int extract_number(const char* str) {
const char* p = str;
while (*p) {
if (isdigit(*p)) {
int num = 0;
while (*p && isdigit(*p)) {
num = num * 10 + (*p - '0');
p++;
}
return num;
}
p++;
}
return 0;
}
// 文件比较函数
int compare_files(const void* a, const void* b) {
const char* file_a = *(const char**)a;
const char* file_b = *(const char**)b;
char folder_a[MAX_PATH], folder_b[MAX_PATH];
strcpy(folder_a, strrchr(file_a, '\\') ? strrchr(file_a, '\\') + 1 : file_a);
strcpy(folder_b, strrchr(file_b, '\\') ? strrchr(file_b, '\\') + 1 : file_b);
int num_a = extract_number(folder_a);
int num_b = extract_number(folder_b);
if (num_a != num_b) return num_a - num_b;
return strcmp(file_a, file_b);
}
// 查找bkmk文件
int find_bkmk_files(const char* root, char* files[], int* count) {
*count = 0;
char search[MAX_PATH];
sprintf(search, "%s\\*.*", root);
WIN32_FIND_DATAA find_data;
HANDLE hFind = FindFirstFileA(search, &find_data);
if (hFind == INVALID_HANDLE_VALUE) return 0;
do {
if (strcmp(find_data.cFileName, ".") == 0 || strcmp(find_data.cFileName, "..") == 0) continue;
char full_path[MAX_PATH];
sprintf(full_path, "%s\\%s", root, find_data.cFileName);
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
find_bmkk_files(full_path, files, count);
} else if (strstr(find_data.cFileName, "FreePic2Pdf_bkmk")) {
if (*count < MAX_FILES) {
files[*count] = strdup(full_path);
(*count)++;
}
}
} while (FindNextFileA(hFind, &find_data));
FindClose(hFind);
return *count;
}
// 简化的处理函数
void start_processing(HWND hwnd) {
log_message(hwnd, "开始处理...");
if (strlen(pdf_path) == 0 || strlen(txt_path) == 0 || strlen(output_path) == 0) {
log_message(hwnd, "错误:请选择所有路径");
return;
}
char* bmk_files[MAX_FILES];
int bmk_count = 0;
if (!find_bmkk_files(pdf_path, bmk_files, &bmk_count)) {
log_message(hwnd, "未找到bkmk文件");
return;
}
log_message(hwnd, "找到bmk文件开始排序...");
qsort(bmk_files, bmk_count, sizeof(char*), compare_files);
log_message(hwnd, "处理完成!");
// 释放内存
for (int i = 0; i < bmk_count; i++) {
free(bmk_files[i]);
}
}
// 窗口过程
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
// 创建控件
CreateWindowA("STATIC", "PDF路径:", WS_VISIBLE | WS_CHILD, 10, 10, 100, 20, hwnd, NULL, NULL, NULL);
CreateWindowA("EDIT", pdf_path, WS_VISIBLE | WS_CHILD | WS_BORDER, 120, 10, 400, 20, hwnd, (HMENU)2001, NULL, NULL);
CreateWindowA("BUTTON", "浏览", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 530, 10, 50, 20, hwnd, (HMENU)1001, NULL, NULL);
CreateWindowA("STATIC", "TXT路径:", WS_VISIBLE | WS_CHILD, 10, 40, 100, 20, hwnd, NULL, NULL, NULL);
CreateWindowA("EDIT", txt_path, WS_VISIBLE | WS_CHILD | WS_BORDER, 120, 40, 400, 20, hwnd, (HMENU)2002, NULL, NULL);
CreateWindowA("BUTTON", "浏览", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 530, 40, 50, 20, hwnd, (HMENU)1002, NULL, NULL);
CreateWindowA("STATIC", "输出路径:", WS_VISIBLE | WS_CHILD, 10, 70, 100, 20, hwnd, NULL, NULL, NULL);
CreateWindowA("EDIT", output_path, WS_VISIBLE | WS_CHILD | WS_BORDER, 120, 70, 400, 20, hwnd, (HMENU)2003, NULL, NULL);
CreateWindowA("BUTTON", "浏览", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 530, 70, 50, 20, hwnd, (HMENU)1003, NULL, NULL);
CreateWindowA("BUTTON", "开始处理", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 10, 100, 80, 30, hwnd, (HMENU)1004, NULL, NULL);
CreateWindowA("BUTTON", "退出", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 100, 100, 80, 30, hwnd, (HMENU)1005, NULL, NULL);
CreateWindowA("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_READONLY,
10, 140, 570, 300, hwnd, (HMENU)3001, NULL, NULL);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case 1001:
browse_folder(hwnd, pdf_path);
SetWindowTextA(GetDlgItem(hwnd, 2001), pdf_path);
break;
case 1002:
browse_folder(hwnd, txt_path);
SetWindowTextA(GetDlgItem(hwnd, 2002), txt_path);
break;
case 1003:
browse_folder(hwnd, output_path);
SetWindowTextA(GetDlgItem(hwnd, 2003), output_path);
break;
case 1004:
GetWindowTextA(GetDlgItem(hwnd, 2001), pdf_path, MAX_PATH);
GetWindowTextA(GetDlgItem(hwnd, 2002), txt_path, MAX_PATH);
GetWindowTextA(GetDlgItem(hwnd, 2003), output_path, MAX_PATH);
start_processing(hwnd);
break;
case 1005:
DestroyWindow(hwnd);
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
// 主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
InitCommonControls();
WNDCLASSA wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = "SlideCombine";
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
RegisterClassA(&wc);
HWND hwnd = CreateWindowExA(0, "SlideCombine", "PDF书签合并工具 v2.0", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 600, 500, NULL, NULL, hInstance, NULL);
if (!hwnd) return 1;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}