在 Windows 平台上使用 gcc 调用原生 Win32 API 实现文件打开对话框是可行的,但需要直接使用 Win32 的 GetOpenFileName
函数(位于 commdlg.h
头文件,依赖 comdlg32.lib
库)。以下是完整实现步骤和代码示例:
编写 filedialog.c 如下
#include <windows.h>
#include <commdlg.h>
// 定义文件选择对话框的过滤器(示例:文本文件和所有文件)
const char filter[] = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
// 打开文件对话框函数
char* OpenFileDialog(HWND hwnd) {
OPENFILENAMEA ofn;
char szFile[260] = {0};
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = filter;
ofn.nFilterIndex = 1;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(&ofn)) {
return strdup(ofn.lpstrFile); // 返回选择的文件路径
}
return NULL;
}
// 主函数(示例)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
char* filePath = OpenFileDialog(NULL);
if (filePath) {
MessageBoxA(NULL, filePath, "Selected File", MB_OK);
free(filePath);
}
return 0;
}
2. 编译命令
由于 gcc 在 Windows 上默认不包含完整的 Win32 SDK 路径,需手动指定头文件和库路径。
编写 win_gcc.bat 如下
SET INCLUDE=D:\Strawberry\c\include;D:\Strawberry\c\x86_64-w64-mingw32\include
SET LIB=D:\Strawberry\c\x86_64-w64-mingw32\lib
gcc -o filedialog.exe filedialog.c -lcomdlg32 -lgdi32 -luser32
关键参数:
-I<路径>
:指定 Windows API 头文件路径(如 MinGW 的include
目录)。-L<路径>
:指定库文件路径(如 MinGW 的lib
目录)。-lcomdlg32
:链接通用对话框库(GetOpenFileName
依赖)。-lgdi32
和-luser32
:基础 GUI 库(窗口和消息处理)。
3. 运行依赖
编译后的
filedialog.exe
需要以下动态链接库(DLL):comdlg32.dll
(通用对话框库,通常位于系统目录)。gdi32.dll
和user32.dll
(基础 GUI 库)。
4. 注意事项
UNICODE 支持:
若需支持 Unicode,改用
GetOpenFileNameW
并调整字符类型为wchar_t
,但 TCC 对宽字符支持有限,建议使用 ANSI 版本(GetOpenFileNameA
)。
内存管理:
使用
strdup
复制返回的字符串后,需手动调用free
释放内存。
路径分隔符:
Windows 路径使用反斜杠
\
,但代码中需用\\
转义。
从 TCC : Tiny C Compiler
从 Index of /releases/tinycc/ 下载 winapi-full-for-0.9.27.zip , 解压到 D:\Tcc\
编写 win_tcc.bat 如下
SET INCLUDE=D:\Tcc\winapi-full-for-0.9.27\include;D:\Tcc\winapi-full-for-0.9.27\include\winapi
SET LIB=D:\Strawberry\c\x86_64-w64-mingw32\lib
tcc -o filedialog1.exe filedialog.c -I"%INCLUDE%" -L"%LIB%" -lcomdlg32 -lgdi32 -luser32
运行 win_tcc.bat
生成 filedialog1.exe
也可以执行。