This commit is contained in:
20
utils/folder/folder.go
Normal file
20
utils/folder/folder.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package folder
|
||||
|
||||
/*
|
||||
#cgo windows LDFLAGS: -lole32 -luuid
|
||||
|
||||
#include "windows_dialog.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// OpenFolderDialog 调用Windows原生文件夹选择对话框
|
||||
// 返回选择的文件夹路径,如果用户取消选择则返回空字符串
|
||||
func OpenFolderDialog() string {
|
||||
cPath := C.OpenFolderDialog()
|
||||
if cPath == nil {
|
||||
return ""
|
||||
}
|
||||
defer C.FreeMemory(cPath)
|
||||
|
||||
return C.GoString(cPath)
|
||||
}
|
||||
56
utils/folder/windows_dialog.c
Normal file
56
utils/folder/windows_dialog.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "windows_dialog.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char* OpenFolderDialog(void) {
|
||||
IFileOpenDialog *pFileOpen = NULL;
|
||||
IShellItem *pItem = NULL;
|
||||
PWSTR pszFilePath = NULL;
|
||||
char* result = NULL;
|
||||
|
||||
// 初始化COM库
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
if (FAILED(hr)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 创建FileOpenDialog对象
|
||||
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void**)&pFileOpen);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// 设置为选择文件夹模式
|
||||
DWORD options;
|
||||
pFileOpen->lpVtbl->GetOptions(pFileOpen, &options);
|
||||
pFileOpen->lpVtbl->SetOptions(pFileOpen, options | FOS_PICKFOLDERS);
|
||||
|
||||
// 显示对话框
|
||||
hr = pFileOpen->lpVtbl->Show(pFileOpen, NULL);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// 获取结果
|
||||
hr = pFileOpen->lpVtbl->GetResult(pFileOpen, &pItem);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// 获取文件夹路径
|
||||
hr = pItem->lpVtbl->GetDisplayName(pItem, SIGDN_FILESYSPATH, &pszFilePath);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// 计算所需缓冲区大小并转换宽字符串到多字节字符串
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, pszFilePath, -1, NULL, 0, NULL, NULL);
|
||||
result = (char*)malloc(size_needed);
|
||||
if (result) {
|
||||
WideCharToMultiByte(CP_UTF8, 0, pszFilePath, -1, result, size_needed, NULL, NULL);
|
||||
}
|
||||
CoTaskMemFree(pszFilePath);
|
||||
}
|
||||
pItem->lpVtbl->Release(pItem);
|
||||
}
|
||||
}
|
||||
pFileOpen->lpVtbl->Release(pFileOpen);
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
return result;
|
||||
}
|
||||
|
||||
void FreeMemory(char* ptr) {
|
||||
if (ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
11
utils/folder/windows_dialog.h
Normal file
11
utils/folder/windows_dialog.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef WINDOWS_DIALOG_H
|
||||
#define WINDOWS_DIALOG_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <shobjidl.h>
|
||||
|
||||
// 导出函数声明
|
||||
char* OpenFolderDialog(void);
|
||||
void FreeMemory(char* ptr);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user