This commit is contained in:
睿 安
2026-01-25 23:46:14 +08:00
parent 2a2a3d68d8
commit 37e7d278bd
727 changed files with 193377 additions and 7 deletions

View File

@@ -0,0 +1,183 @@
#include "FileSystem.h"
namespace ezui {
namespace File {
bool Exists(const UIString& filename) {
DWORD dwAttr = ::GetFileAttributesW(filename.unicode().c_str());
return (dwAttr != INVALID_FILE_ATTRIBUTES && !(dwAttr & FILE_ATTRIBUTE_DIRECTORY));
}
bool Copy(const UIString& src, const UIString& desc) {
return ::CopyFileW(src.unicode().c_str(), desc.unicode().c_str(), FALSE);
}
bool Delete(const UIString& file) {
return ::DeleteFileW(file.unicode().c_str());
}
bool Move(const UIString& oldName, const UIString& newName) {
return ::MoveFileExW(oldName.unicode().c_str(), newName.unicode().c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
}
bool Create(const UIString& fileName) {
std::ofstream ofs(fileName.unicode(), std::ios::out | std::ios::binary);
return ofs.is_open();
}
bool Write(const char* fileData, size_t fileSize, const UIString& outFileName) {
std::ofstream ofs(outFileName.unicode(), std::ios::binary | std::ios::app);
if (ofs.is_open()) {
ofs.write(fileData, fileSize);
return ofs.good();
}
return false;
}
size_t Read(const UIString& fileName, std::string* data) {
std::ifstream ifs(fileName.unicode(), std::ios::binary);
ifs.seekg(0, std::ios::end);
size_t size = ifs.tellg();
data->resize(size);
ifs.seekg(0);
ifs.read((char*)data->data(), size);
return size;
}
}
namespace Path {
void Format(std::string* _str) {
auto& str = *_str;
size_t size = str.size();
if (size == 0) {
return;
}
char* buf = new char[size];
size_t j = 0;
for (size_t i = 0; i < size; i++)
{
if (str[i] == '\\') {
buf[j] = '/';
}
else {
buf[j] = str[i];
}
j++;
}
for (size_t i = 0; i < size; i++)
{
// 将多个斜杠替换成单个斜杠
if (buf[i] == '/') {
size_t k = i + 1;
while (buf[k] == '/' && k < size) {
k++;
}
if (k > i + 1) {
for (size_t m = i + 1; m < size - (k - i - 1); m++) {
buf[m] = buf[m + (k - i - 1)];
}
size -= (k - i - 1);
}
}
}
str.clear();
str.append(buf, size);
delete[] buf; // 释放内存
}
UIString GetFileNameWithoutExtension(const UIString& _filename) {
UIString newStr = _filename;
Path::Format(&newStr);
int bPos = newStr.rfind("/");
int ePos = newStr.rfind(".");
newStr = newStr.substr(bPos + 1, ePos - bPos - 1);
return newStr;
}
UIString GetDirectoryName(const UIString& _filename) {
UIString newStr = _filename;
Path::Format(&newStr);
int pos = newStr.rfind("/");
return newStr.substr(0, pos);
}
UIString GetExtension(const UIString& _filename) {
size_t pos = _filename.rfind(".");
return pos == size_t(-1) ? "" : _filename.substr(pos);
}
UIString GetFileName(const UIString& filename) {
return Path::GetFileNameWithoutExtension(filename) + Path::GetExtension(filename);
}
}
namespace Directory {
void __Find(const std::wstring& path, std::vector<FileInfo>* result, const std::wstring& pattern, bool looDir) {
WIN32_FIND_DATAW findData;
HANDLE findHandle = FindFirstFileW((path + L"/" + pattern).c_str(), &findData);
if (findHandle == INVALID_HANDLE_VALUE) {
return;
}
do
{
if (findData.cFileName[0] == L'.') {
continue;
}
FileInfo file;
std::wstring name = path + L"/" + findData.cFileName;
file.Name = name;
file.Attr = findData.dwFileAttributes;
result->push_back(file);
if (file.IsDirectory() && looDir) {
__Find(name, result, pattern, looDir);
}
} while (FindNextFileW(findHandle, &findData));
FindClose(findHandle);
}
bool Exists(const UIString& directoryNme) {
DWORD dwAttr = GetFileAttributesW(directoryNme.unicode().c_str());
if (dwAttr == DWORD(-1)) {
return false;
}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
{
return true;
}
return false;
}
bool Create(const UIString& path) {
::CreateDirectoryW(path.unicode().c_str(), NULL);
if (Exists(path)) {
return true;
}
//创建多级目录
if (path.find(":") != size_t(-1)) {
UIString dir = path + "/";
Path::Format(&dir);
auto arr = dir.split("/");
UIString root;
if (!arr.empty()) {
root += arr[0] + "/";
for (size_t i = 1; i < arr.size(); i++)
{
if (arr[i].empty()) {
continue;
}
root += arr[i] + "/";
if (!Exists(root)) {
::CreateDirectoryW(root.unicode().c_str(), NULL);
}
}
}
}
return Exists(path);
}
void Copy(const UIString& srcPath, const UIString& desPath)
{
UIString basePath = srcPath;
Path::Format(&basePath);
std::vector<FileInfo> result;
Directory::Find(srcPath, &result);
for (auto& it : result) {
auto fileName = it.Name;
fileName = fileName.replace(basePath, "");
if (it.IsDirectory()) {
Directory::Create(desPath + "/" + fileName);
}
else {
File::Copy(it.Name, desPath + "/" + fileName);
}
}
}
void Find(const UIString& directory, std::vector<FileInfo>* result, const UIString& pattern, bool loopDir)
{
__Find(directory.unicode(), result, pattern.unicode(), loopDir);
}
}
}

View File

@@ -0,0 +1,50 @@
#pragma once
#include "EzUI/EzUI.h"
#include "EzUI/UIString.h"
namespace ezui {
struct FileInfo final {
UIString Name;
DWORD Attr;
bool IsDirectory() {
return (Attr & FILE_ATTRIBUTE_DIRECTORY);
}
};
namespace File {
//判断文件是否存在
UI_EXPORT bool Exists(const UIString& filenNme);
//拷贝文件
UI_EXPORT bool Copy(const UIString& src, const UIString& desc);
//删除文件
UI_EXPORT bool Delete(const UIString& file);
//文件移动或者改名
UI_EXPORT bool Move(const UIString& oldName, const UIString& newName);
//创建一个文件(如果文件已存在则清空其内容)
UI_EXPORT bool Create(const UIString& fileName);
//将指定数据以二进制方式写入文件(如果文件存在内容则追加)
UI_EXPORT bool Write(const char* fileData, size_t fileSize, const UIString& outFileName);
//读取文件到内存中
UI_EXPORT size_t Read(const UIString& fileName, std::string* data);
}
namespace Path {
//格式化路径
UI_EXPORT void Format(std::string* str);
//获取文件名(不包括目录名 不包括扩展名)
UI_EXPORT UIString GetFileNameWithoutExtension(const UIString& _filename);
//获取文件所在目录
UI_EXPORT UIString GetDirectoryName(const UIString& _filename);
//获取文件扩展名
UI_EXPORT UIString GetExtension(const UIString& _filename);
//获取文件名(文件名+扩展名)
UI_EXPORT UIString GetFileName(const UIString& filename);
}
namespace Directory {
//检测目录是否存在
UI_EXPORT bool Exists(const UIString& directoryNme);
//创建目录 不存在的多级目录将会自动创建
UI_EXPORT bool Create(const UIString& path);
//将目录和目录下的文件复制到指定的位置
UI_EXPORT void Copy(const UIString& srcPath, const UIString& desPath);
//使用通配符搜索文件和目录
UI_EXPORT void Find(const UIString& directory, std::vector<FileInfo>* result, const UIString& pattern = "*.*", bool loopDir = true);
}
};

42
demo/ResPackage/main.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include "mainFrom.h"
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
//格式化命令行参数
int argc = 0;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
std::vector<UIString> args;
for (int i = 0; i < argc; i++) {
args.emplace_back(argv[i]);
}
LocalFree(argv);
// 查找 "-package" 参数
auto it = std::find(args.begin(), args.end(), L"-package");
if (it != args.end()) {
size_t index = std::distance(args.begin(), it);
UIString packageDir = args[index + 1];
UIString outFile = args[index + 2];
UIString log = UIString("packaging... %s -> %s \n").format(packageDir.c_str(), outFile.c_str()).ansi();
printf(log.c_str());
bool bRet = Resource::Package(packageDir, outFile);
if (bRet) {
printf("package succeeded !");
}
else {
printf("package failed !");
}
return 0;
}
Application app;
app.EnableHighDpi();
MainFrm frm(lpCmdLine);
frm.Show();
return app.Exec();
};

88
demo/ResPackage/main.html Normal file
View File

@@ -0,0 +1,88 @@
<vbox id="main">
<hbox height="40">
<radiobutton class="btnTab" tablayout="tab" checked="true" text="打包" width="100"></radiobutton>
<radiobutton class="btnTab" tablayout="tab" text="解包" width="100"></radiobutton>
</hbox>
<tablayout id="tab">
<hbox id="page1">
<spacer width="10"></spacer>
<vbox>
<spacer height="10"></spacer>
<label height="30" halign="left" text="请选择你要打包的目录 :"></label>
<hbox height="30"> <textbox class="edit" id="editPackDir"></textbox> <spacer width="10"></spacer><button class="btn" id="btnBrowserDir" width="100" text="浏览"></button> </hbox>
<label halign="left" style="color:#ff0000" id="labelTipsErr" height="20"></label>
<spacer></spacer>
<label height="30" halign="left" text="请选择输出目录 :"></label>
<hbox height="30"> <textbox class="edit" id="editPackName"></textbox> <spacer width="10"></spacer><button class="btn" id="btnSatrtPackage" width="100" text="开始打包"></button> </hbox>
<spacer></spacer>
<!-- <hbox height="30"> <spacer></spacer> <button class="btn" id="btnSatrtPackage" width="100" text="开始"></button> <spacer></spacer></hbox>-->
<spacer height="10"></spacer>
</vbox>
<spacer width="10"></spacer>
</hbox>
<hbox id="page2">
<spacer width="10"></spacer>
<vbox>
<spacer height="10"></spacer>
<label height="30" halign="left" text="请选择你要预览的文件 :"></label>
<hbox height="30"> <textbox class="edit" readonly="true" id="editResFile"></textbox> <spacer width="10"></spacer><button class="btn" id="btnBrowserFile" width="100" text="浏览"></button><spacer width="10"></spacer><button class="btn" height="30" id="btnUnPackage" width="100" text="解压至..."></button> </hbox>
<spacer height="10"></spacer>
<vlist id="listFiles" scrollbar="fileScrollbar" style="background-color:rgba(175, 106, 106, 0.5)"></vlist>
</vbox>
<spacer width="10"></spacer>
</hbox>
</tablayout>
<hbox margin="0,10" height="30">
<label id="labelTips" text="技术支持 718987717@qq.com/19980103ly@gmail.com"></label>
</hbox>
</vbox>
<style>
.btn {
border-radius: 5;
border: 1;
border-color: #D0D0D0;
background-color: #FDFDFD;
font-size: 13;
}
.btn:hover {
border-color: #0078D4;
background-color: #E0EEF9;
}
.btn:active {
font-size: 14;
}
.edit {
border: 1;
border-radius: 2;
border-color: #808080;
}
#tab {
background-color: #F0F0F0;
}
.btnTab:checked {
background-color: #F0F0F0;
}
.btnTab:hover {
cursor: pointer;
}
#fileScrollbar {
border-radius: 5;
background-color: rgba(50,50,50,0.5);
fore-color: rgba(200,200,200,0.5);
}
#fileScrollbar:active {
fore-color: rgba(200,200,200,0.8);
}
</style>

View File

@@ -0,0 +1,311 @@
#include "mainFrom.h"
#include "FileSystem.h"
const wchar_t* xml = LR"xml(
<vbox id="main">
<hbox height="40">
<radiobutton class="btnTab" tablayout="tab" checked="true" text="" width="100"></radiobutton>
<radiobutton class="btnTab" tablayout="tab" text="" width="100"></radiobutton>
</hbox>
<tablayout id="tab">
<hbox id="page1">
<spacer width="10"></spacer>
<vbox>
<spacer height="10"></spacer>
<label height="30" halign="left" text="请选择你要打包的目录 :"></label>
<hbox height="30">
<textbox class="edit" id="editPackDir"></textbox>
<spacer width="10"></spacer>
<button class="btn" id="btnBrowserDir" width="100" text=""></button>
</hbox>
<label halign="left" style="color:#ff0000" id="labelTipsErr" height="20"></label>
<spacer></spacer>
<label height="30" halign="left" text="请选择输出目录 :"></label>
<hbox height="30">
<textbox class="edit" id="editPackName"></textbox>
<spacer width="10"></spacer>
<button class="btn" id="btnSatrtPackage" width="100" text=""></button>
</hbox>
<spacer></spacer>
<spacer height="10"></spacer>
</vbox>
<spacer width="10"></spacer>
</hbox>
<hbox id="page2">
<spacer width="10"></spacer>
<vbox>
<spacer height="10"></spacer>
<label height="30" halign="left" text="请选择你要预览的文件 :"></label>
<hbox height="30">
<textbox class="edit" readonly="true" id="editResFile"></textbox>
<spacer width="10"></spacer>
<button class="btn" id="btnBrowserFile" width="100" text=""></button>
<spacer width="10"></spacer>
<button class="btn" height="30" id="btnUnPackage" width="100" text="..."></button>
</hbox>
<spacer height="10"></spacer>
<vlist id="listFiles" scrollbar="fileScrollbar" style="background-color:rgba(175, 106, 106, 0.5)"></vlist>
</vbox>
<spacer width="10"></spacer>
</hbox>
</tablayout>
<hbox margin="0,10" height="30">
<label id="labelTips" text="技术支持 718987717@qq.com/19980103ly@gmail.com"></label>
</hbox>
</vbox>
<style>
.btn {
border-radius: 5px;
border: 1px #D0D0D0 solid;
background-color: #FDFDFD;
font-size: 13px;
}
.btn:hover {
border-color: #0078D4;
background-color: #E0EEF9;
}
.btn:active {
font-size: 14px;
}
.edit {
border: 1px #808080 solid;
border-radius: 2px;
}
#tab {
background-color: #F0F0F0;
}
.btnTab:checked {
background-color: #F0F0F0;
}
.btnTab:hover {
cursor: pointer;
}
#fileScrollbar {
border-radius: 5px;
background-color: rgba(50,50,50,0.5);
fore-color: rgba(200,200,200,0.5);
}
#fileScrollbar:active {
fore-color: rgba(200,200,200,0.8);
}
</style>
)xml";
void MainFrm::Init() {
this->SetText(L"EzUI资源打包器");
//ui.LoadXmlFile("main.html");
UIString xmlData = xml;
ui.LoadXml(xmlData.c_str(), xmlData.size());
ui.SetupUI(this);
//第一页的控件
this->tab = (TabLayout*)this->FindControl("tab");
this->editPackDir = (TextBox*)this->FindControl("editPackDir");
this->editPackName = (TextBox*)this->FindControl("editPackName");
this->btnSatrtPackage = (Button*)this->FindControl("btnSatrtPackage");
this->labelTipsErr = (Label*)this->FindControl("labelTipsErr");
this->labelTips = (Label*)this->FindControl("labelTips");
this->editPackDir->TextChanged = [=](const UIString text)->void {
this->OnPackDirChange();
};
//第二页的控件
this->editResFile = (TextBox*)this->FindControl("editResFile");
this->btnBrowserFile = (Button*)this->FindControl("btnBrowserFile");
this->listFiles = (VListView*)this->FindControl("listFiles");
this->btnUnPackage = (Button*)this->FindControl("btnUnPackage");
}
MainFrm::MainFrm(const UIString& cmdLine) :Window(600, 400) {
Init();
editPackDir->SetText(cmdLine);
OnPackDirChange();
}
void MainFrm::OnPackDirChange()
{
UIString dir = editPackDir->GetText();
if (dir.empty() || !PathExist(dir)) {
editPackName->SetText("");
editPackName->Invalidate();
labelTipsErr->SetText(L"打包目录无效!");
labelTipsErr->Invalidate();
return;
}
else {
labelTipsErr->SetText("");
labelTipsErr->Invalidate();
}
ui_text::Replace(&dir, "\"", "");
ui_text::Replace(&dir, "\\", "/");
ui_text::Replace(&dir, "//", "/");
if (dir[dir.size() - 1] == '/') {
dir.erase(dir.size() - 1, 1);
}
UIString resDir = dir;
UIString rootDir;
size_t pos = dir.rfind('/');
UIString dirName;
if (pos != size_t(-1)) {
rootDir = dir.substr(0, pos);
dirName = dir.substr(pos + 1);
}
UIString resFile = rootDir + "/" + dirName + ".bin";
editPackName->SetText(resFile);
editPackName->Invalidate();
}
void MainFrm::OnClose(bool& close) {
Application::Exit(0);
}
bool MainFrm::FileExists(const UIString& fileName) {
DWORD dwAttr = GetFileAttributesW(fileName.unicode().c_str());
if (dwAttr == DWORD(-1)) {
return false;
}
if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) {
return true;
}
return false;
}
void MainFrm::OnNotify(Control* sd, EventArgs& args) {
if (args.EventType == Event::OnMouseDown) {
if (sd->Name == "btnBrowserDir") {
UIString dir = ShowFolderDialog(Hwnd(), "", "");
if (!dir.empty()) {
this->editPackDir->SetText(dir);
this->editPackDir->Invalidate();
this->OnPackDirChange();
}
}
if (sd->Name == "btnSatrtPackage") {
do
{
UIString resDir = editPackDir->GetText();
UIString resFile = editPackName->GetText();
if (task && !task->IsStopped()) {
::MessageBoxW(Hwnd(), L"请等待上次任务完成!", L"失败", 0);
break;
}
if (FileExists(resFile) && ::DeleteFileW(resFile.unicode().c_str()) == FALSE) {
::MessageBoxW(Hwnd(), L"文件已存在且无法覆盖!", L"失败", 0);
break;
}
if (task) {
delete task;
task = NULL;
}
if (resFile.empty()) {
::MessageBoxW(Hwnd(), L"打包文件路径不正确!", L"失败", 0);
break;
}
labelTips->SetText(L"正在计算...");
labelTips->Invalidate();
task = new Task([resDir, resFile, this]() {
Resource::Package(resDir, resFile, [=](const UIString& file, int index, int count) {
Invoke([&]() {
int rate = (index + 1) * 1.0f / count * 100 + 0.5;
labelTips->SetText(UIString("(" + std::to_string(rate) + "%)") + UIString(L"正在打包\"") + file + "\"");
labelTips->Invalidate();
});
Sleep(2);
});
Invoke([&]() {
labelTips->SetText(L"打包成功!");
labelTips->Invalidate();
::MessageBoxW(Hwnd(), L"打包成功!", L"成功", 0);
});
});
} while (false);
}
if (sd->Name == "btnBrowserFile") {
UIString resFile = ShowFileDialog(Hwnd());
OnResFileChange(resFile);
}
if (sd->Name == "btnUnPackage") {
UIString resDir = ShowFolderDialog(Hwnd());
if (!resDir.empty() && PathExist(resDir)) {
for (auto& it : this->res->Items) {
UIString fileName = resDir + "/" + it.Name;
UIString dir = Path::GetDirectoryName(fileName);
Directory::Create(dir);
File::Delete(fileName);
UIString data;
this->res->GetFile(it, &data);
File::Write(data.c_str(), data.size(), fileName);
}
::MessageBoxW(Hwnd(), L"解压完成!", L"", 0);
}
}
}
ezui::DefaultNotify(sd, args);
}
void MainFrm::OnResFileChange(UIString& resFile)
{
do
{
if (FileExists(resFile)) {
Resource* newRes = new Resource(resFile);
if (!newRes->IsGood()) {
::MessageBoxW(Hwnd(), L"不是标准的资源文件", L"错误", 0);
delete newRes;
break;
}
if (res) {
delete res;
res = NULL;
}
res = newRes;
listFiles->Clear(true);
for (auto& item : res->Items) {
FileItem* fileItem = new FileItem(item.Name, item.Size);
listFiles->Add(fileItem);
}
listFiles->Invalidate();
this->editResFile->SetText(resFile);
this->editResFile->Invalidate();
}
} while (false);
}
LRESULT MainFrm::WndProc(UINT msg, WPARAM wp, LPARAM lp) {
//准备做一个解压的功能
if (msg == WM_DROPFILES) {
HDROP hDrop = (HDROP)wp;
UINT numFiles = ::DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); // 获取拖入的文件数量
TCHAR szFilePath[MAX_PATH]{ 0 };
::DragQueryFileW(hDrop, 0, szFilePath, sizeof(szFilePath)); // 获取第一个文件路径
UIString file = szFilePath;
if (tab->GetPageIndex() == 0) {
//打包
if (PathExist(file)) {
this->editPackDir->SetText(file);
this->editPackDir->Invalidate();
this->OnPackDirChange();
}
}
else if (tab->GetPageIndex() == 1) {
//解包
if (FileExists(file)) {
this->OnResFileChange(file);
}
}
}
return __super::WndProc(msg, wp, lp);
}
MainFrm::~MainFrm() {
if (task) {
delete task;
}
if (res) {
delete res;
}
}

189
demo/ResPackage/mainFrom.h Normal file
View File

@@ -0,0 +1,189 @@
#include "EzUI/Application.h"
#include "EzUI/VLayout.h"
#include "EzUI/TextBox.h"
#include "EzUI/Button.h"
#include "EzUI/Window.h"
#include "EzUI/Resource.h"
#include "EzUI/Task.h"
#include "EzUI/HLayout.h"
#include "EzUI/UIManager.h"
using namespace ezui;
class MainFrm :public Window {
Task* task = NULL;
UIManager ui;
//选项卡
TabLayout* tab;
//第一页的控件
//要打包的目录
TextBox* editPackDir;
//打包之后要输出的文件名
TextBox* editPackName;
//开始打包的按钮
Button* btnSatrtPackage;
//提示文本
Label* labelTips;
Label* labelTipsErr;
//第二页的控件
TextBox* editResFile;
Button* btnBrowserFile;
VListView* listFiles;
Button* btnUnPackage;
//资源指针
Resource* res = NULL;
public:
void Init();
MainFrm(const UIString& cmdLine);
void OnPackDirChange();
void OnClose(bool& close) override;
bool FileExists(const UIString& fileName);
void OnNotify(Control* sender, EventArgs& args)override;
void OnResFileChange(UIString& resFile);
virtual LRESULT WndProc(UINT msg, WPARAM wp, LPARAM lp);
virtual ~MainFrm();
};
inline bool FileExists(const UIString& filename) {
DWORD dwAttr = GetFileAttributesW(filename.unicode().c_str());
if (dwAttr == DWORD(-1)) {
return false;
}
if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) {
return true;
}
return false;
}
inline bool PathExist(const UIString& dir) {
DWORD dwAttr = GetFileAttributesW(dir.unicode().c_str());
if (dwAttr == DWORD(-1)) {
return false;
}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
{
return true;
}
return false;
}
inline bool CreatePath(const UIString& path) {
::CreateDirectoryW(path.unicode().c_str(), NULL);
if (PathExist(path)) {
return true;
}
//创建多级目录
if (path.find(":") != size_t(-1)) {
UIString dir = path + "/";
dir = dir.replace("\\", "/");
dir = dir.replace("//", "/");
auto arr = dir.split("/");
UIString root;
if (arr.size() > 0) {
root += arr[0] + "/";
for (size_t i = 1; i < arr.size(); i++)
{
if (arr[i].empty()) {
continue;
}
root += arr[i] + "/";
if (!PathExist(root)) {
::CreateDirectoryW(root.unicode().c_str(), NULL);
}
}
}
}
return PathExist(path);
}
inline UIString ShowFileDialog(HWND ownerWnd, const UIString& defaultPath = "", const UIString& title = "") {
OPENFILENAMEW ofn; // 打开文件对话框结构体
WCHAR szFile[512]{ 0 }; // 选择的文件名
// 初始化OPENFILENAME结构体
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.hwndOwner = ownerWnd;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All Files\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// 显示文件对话框
if (GetOpenFileNameW(&ofn) == TRUE) {
return szFile;
}
return szFile;
}
#include <ShlObj.h>
inline UIString ShowFolderDialog(HWND ownerWnd, const UIString& defaultPath = "", const UIString& title = "") {
WCHAR selectedPath[MAX_PATH]{ 0 };
BROWSEINFOW browseInfo{ 0 };
browseInfo.hwndOwner = ownerWnd;
browseInfo.pszDisplayName = selectedPath;
auto wTitle = title.unicode();
browseInfo.lpszTitle = wTitle.c_str();
//设置根目录
LPITEMIDLIST pidlRoot;
::SHParseDisplayName(defaultPath.unicode().c_str(), NULL, &pidlRoot, 0, NULL);
browseInfo.pidlRoot = pidlRoot;
browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
LPITEMIDLIST itemIdList = SHBrowseForFolderW(&browseInfo);
if (itemIdList != nullptr) {
SHGetPathFromIDListW(itemIdList, selectedPath);//设置路径
CoTaskMemFree(itemIdList);//清理
return selectedPath;
}
return selectedPath;
}
inline std::string GetFileSize(__int64 _KEY_FILE_SIZE) {
std::string ext;
std::string disp_size;
long double KEY_FILE_SIZE = _KEY_FILE_SIZE;
if (KEY_FILE_SIZE > 1024) {
KEY_FILE_SIZE = KEY_FILE_SIZE / 1024.0f; // kb
ext = "KB";
if (KEY_FILE_SIZE > 1024) {
KEY_FILE_SIZE = KEY_FILE_SIZE / 1024.0f; // mb
ext = "MB";
if (KEY_FILE_SIZE > 1024) {
KEY_FILE_SIZE = KEY_FILE_SIZE / 1024.0f; // gb
ext = "GB";
}
}
}
else {
ext = "BT";
}
disp_size = ui_text::ToString(KEY_FILE_SIZE, 2) + " " + ext;
return disp_size;
}
class FileItem :public HBox {
Label name;
Label size;
public:
FileItem(const UIString& fileName, size_t fileSize) {
this->SetFixedHeight(25);
this->SetDockStyle(DockStyle::Horizontal);
name.TextAlign = TextAlign::MiddleLeft;
name.SetText(" " + fileName);
name.SetElidedText("...");
this->Add(&name);
size.SetFixedWidth(100);
size.SetText(GetFileSize(fileSize));
this->Add(&size);
name.SetHitTestVisible(false);
this->HoverStyle.BackColor = Color(100, 100, 100, 50);
this->Style.FontSize = 13;
this->ActiveStyle.FontSize = 14;
}
};