Implemented file input via explorer by invoking Win32 API && Modified the file input validity detection strategy && Adjusted UI layout
This commit is contained in:
parent
38b498e841
commit
34509a68a6
@ -5,7 +5,10 @@
|
||||
#define MAIN_FRAME_TITTLE L"DLT Splitter —— Dev by : LuChiChick"
|
||||
|
||||
// 主窗体最小面积
|
||||
#define MAIN_FRAME_SIZE_WIDTH_MIN 350
|
||||
#define MAIN_FRAME_SIZE_HEIGHT_MIN 350 * 1.5
|
||||
#define MAIN_FRAME_SIZE_WIDTH_MIN 400
|
||||
#define MAIN_FRAME_SIZE_HEIGHT_MIN 400 * 1.5
|
||||
|
||||
// 单次允许选择的最大文件数量
|
||||
#define MAX_SINGLE_SELECT_FILE_COUNT 512
|
||||
|
||||
#endif
|
||||
@ -13,6 +13,9 @@ extern "C"
|
||||
|
||||
#include "Type_Descriptions.hpp"
|
||||
|
||||
// 主窗体句柄
|
||||
extern HWND Main_Window_hWnd;
|
||||
|
||||
// D3D11 相关
|
||||
extern ID3D11Device *g_pd3dDevice; // D3D11 设备句柄
|
||||
extern ID3D11DeviceContext *g_pd3dDeviceContext; // D3D11 设备上下文句柄
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
#include "Global_Variables.hpp"
|
||||
|
||||
// 主窗体句柄
|
||||
HWND Main_Window_hWnd = nullptr;
|
||||
|
||||
// D3D11 相关
|
||||
ID3D11Device *g_pd3dDevice = nullptr; // D3D11 设备句柄
|
||||
ID3D11DeviceContext *g_pd3dDeviceContext = nullptr; // D3D11 设备上下文句柄
|
||||
|
||||
42
Src/Main.cpp
42
Src/Main.cpp
@ -61,7 +61,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
// 创建窗体
|
||||
HWND hwnd = CreateWindowW(wc.lpszClassName, // 创建的窗体类名
|
||||
Main_Window_hWnd = CreateWindowW(wc.lpszClassName, // 创建的窗体类名
|
||||
MAIN_FRAME_TITTLE, // 窗体标题
|
||||
WS_OVERLAPPEDWINDOW, // 窗体风格为标准可重叠的顶层窗口
|
||||
100, // 起始坐标x
|
||||
@ -74,7 +74,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
nullptr); // 额外的事件参数指针
|
||||
|
||||
// 在窗体内创建 Direct 3D 设备
|
||||
if (!CreateDeviceD3D(hwnd))
|
||||
if (!CreateDeviceD3D(Main_Window_hWnd))
|
||||
{
|
||||
// 未创建完成时清理 Direct 3D 设备并清理窗体注册类
|
||||
CleanupDeviceD3D();
|
||||
@ -85,11 +85,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
}
|
||||
|
||||
// 启用文件拖拽输入
|
||||
DragAcceptFiles(hwnd, TRUE);
|
||||
DragAcceptFiles(Main_Window_hWnd, TRUE);
|
||||
|
||||
// 显示窗体并强制更新一次窗体
|
||||
ShowWindow(hwnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hwnd);
|
||||
ShowWindow(Main_Window_hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(Main_Window_hWnd);
|
||||
|
||||
// 检查版本
|
||||
IMGUI_CHECKVERSION();
|
||||
@ -133,7 +133,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
}
|
||||
|
||||
// 初始化渲染器后端(Renderer backends)
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplWin32_Init(Main_Window_hWnd);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
|
||||
// 字体配置相关
|
||||
@ -164,7 +164,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
{
|
||||
// 非阻塞式获取所有窗体消息,Pick消息后从消息队列删除,并转译和派发消息
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
|
||||
while (PeekMessageW(&msg, nullptr, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg); // 转译
|
||||
DispatchMessageW(&msg); // 派发
|
||||
@ -236,7 +236,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
ImNodes::DestroyContext(); // 销毁 ImNodes 上下文
|
||||
|
||||
CleanupDeviceD3D(); // 清理 Direct 3D 设备
|
||||
DestroyWindow(hwnd); // 销毁窗体
|
||||
DestroyWindow(Main_Window_hWnd); // 销毁窗体
|
||||
UnregisterClassW(wc.lpszClassName, wc.hInstance); // 取消窗体注册类
|
||||
|
||||
return 0;
|
||||
@ -342,6 +342,10 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
// 获取拖拽的文件总数
|
||||
UINT fileCount = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
|
||||
|
||||
// 非法输入检测
|
||||
bool with_illegal_input = false;
|
||||
bool with_duplicated_input = false;
|
||||
|
||||
// 添加到文件列表
|
||||
for (UINT count = 0; count < fileCount; count++)
|
||||
{
|
||||
@ -357,26 +361,31 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, filePath, -1, NULL, 0, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filePath, -1, file_path_multi_byte, size_needed, NULL, NULL);
|
||||
|
||||
/**
|
||||
* @todo 文件类型筛选
|
||||
*/
|
||||
|
||||
// 重复文件剔除
|
||||
bool duplicated = false;
|
||||
for (Input_File_Node *p_file_node = input_dlt_file_list_head; p_file_node != nullptr; p_file_node = p_file_node->p_next)
|
||||
if (!strcmp(p_file_node->file_name_str, file_path_multi_byte))
|
||||
{
|
||||
duplicated = true;
|
||||
with_duplicated_input = true;
|
||||
break;
|
||||
}
|
||||
if (duplicated)
|
||||
continue;
|
||||
|
||||
// 文件类型后缀过滤
|
||||
const char *p_extension_name = file_path_multi_byte + (strlen(file_path_multi_byte) - 4);
|
||||
if (p_extension_name[0] != '.' || toupper(p_extension_name[1]) != 'D' || toupper(p_extension_name[2]) != 'L' || toupper(p_extension_name[3]) != 'T')
|
||||
{
|
||||
with_illegal_input = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 开辟新文件节点
|
||||
Input_File_Node *p_new_file_node = (Input_File_Node *)malloc(sizeof(Input_File_Node));
|
||||
p_new_file_node->file_name_str = (char *)malloc(strlen(file_path_multi_byte) + 1);
|
||||
memset(p_new_file_node->file_name_str, '\0', strlen(file_path_multi_byte) + 1);
|
||||
memcpy(p_new_file_node->file_name_str, file_path_multi_byte, strlen(file_path_multi_byte));
|
||||
memcpy(p_new_file_node->file_name_str, file_path_multi_byte, strlen(file_path_multi_byte) + 1);
|
||||
p_new_file_node->p_next = nullptr;
|
||||
|
||||
// 插入文件列表
|
||||
@ -396,6 +405,13 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
// 释放拖拽资源(必须调用,否则内存泄漏)
|
||||
DragFinish(hDrop);
|
||||
|
||||
if (with_duplicated_input)
|
||||
MessageBoxW(hWnd, L"存在重复输入", L"", MB_OK);
|
||||
|
||||
if (with_illegal_input)
|
||||
MessageBoxW(hWnd, L"存在非法输入,仅支持 .dlt 文件", L"", MB_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case WM_SIZE: // 窗体大小变事件
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
#include "UI_Layout.hpp"
|
||||
#include "imgui_impl_win32.h"
|
||||
#include "Global_Variables.hpp"
|
||||
#include "Config.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "windows.h"
|
||||
#include "stdio.h"
|
||||
}
|
||||
|
||||
// UI布局
|
||||
@ -51,7 +56,133 @@ void Widgets::Drag_Input_Area(const ImVec2 &size)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
// 显示一个按钮,作为拖拽源
|
||||
static bool pressed_hover = false;
|
||||
ImGui::Button(pressed_hover ? u8"松开左键以添加" : u8"拖拽文件到此处", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y));
|
||||
|
||||
if (ImGui::Button(pressed_hover ? u8"松开左键以添加" : u8"单击选择文件或拖拽文件到此处", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y)))
|
||||
{
|
||||
OPENFILENAMEW ofn; // common dialog box structure
|
||||
wchar_t szFile[MAX_PATH * MAX_SINGLE_SELECT_FILE_COUNT] = {L'\0'}; // buffer for file name
|
||||
|
||||
// Initialize OPENFILENAME
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = Main_Window_hWnd;
|
||||
ofn.lpstrFile = szFile;
|
||||
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
|
||||
// use the contents of szFile to initialize itself.
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = L"(.dlt)\0*.dlt\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
|
||||
|
||||
// Display the Open dialog box.
|
||||
|
||||
// 处理文件输入
|
||||
if (GetOpenFileNameW(&ofn) == TRUE)
|
||||
{
|
||||
// 重复输入检测
|
||||
bool with_duplicated_input = false;
|
||||
|
||||
wchar_t *p_first_str = ofn.lpstrFile;
|
||||
// 单文件
|
||||
if ((p_first_str[wcslen(p_first_str)] == L'\0') && (p_first_str[wcslen(p_first_str) + 1] == L'\0'))
|
||||
{
|
||||
char file_path_multi_byte[MAX_PATH] = {'\0'};
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, NULL, 0, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, file_path_multi_byte, size_needed, NULL, NULL);
|
||||
|
||||
for (Input_File_Node *p_file_node = input_dlt_file_list_head; p_file_node != nullptr; p_file_node = p_file_node->p_next)
|
||||
if (!strcmp(p_file_node->file_name_str, file_path_multi_byte))
|
||||
{
|
||||
with_duplicated_input = true;
|
||||
break;
|
||||
}
|
||||
if (with_duplicated_input)
|
||||
{
|
||||
MessageBoxW(Main_Window_hWnd, L"存在重复输入", L"", MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// 开辟新文件节点
|
||||
Input_File_Node *p_new_file_node = (Input_File_Node *)malloc(sizeof(Input_File_Node));
|
||||
p_new_file_node->file_name_str = (char *)malloc(strlen(file_path_multi_byte) + 1);
|
||||
memset(p_new_file_node->file_name_str, '\0', strlen(file_path_multi_byte) + 1);
|
||||
memcpy(p_new_file_node->file_name_str, file_path_multi_byte, strlen(file_path_multi_byte) + 1);
|
||||
p_new_file_node->p_next = nullptr;
|
||||
|
||||
// 插入文件列表
|
||||
if (input_dlt_file_list_head == nullptr)
|
||||
input_dlt_file_list_head = p_new_file_node;
|
||||
else
|
||||
{
|
||||
Input_File_Node *p_target_node = input_dlt_file_list_head;
|
||||
for (size_t count = 1; count < input_dlt_file_count; count++)
|
||||
p_target_node = p_target_node->p_next;
|
||||
|
||||
p_target_node->p_next = p_new_file_node;
|
||||
}
|
||||
|
||||
input_dlt_file_count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 多文件输入时
|
||||
char public_path_multi_byte[MAX_PATH] = {'\0'};
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, NULL, 0, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, public_path_multi_byte, size_needed, NULL, NULL);
|
||||
|
||||
for (wchar_t *p_file_name_str = ofn.lpstrFile + wcslen(ofn.lpstrFile) + 1; *p_file_name_str != L'\0'; p_file_name_str += (wcslen(p_file_name_str) + 1))
|
||||
{
|
||||
char file_name_multi_byte[MAX_PATH] = {'\0'};
|
||||
char file_path_multi_byte[MAX_PATH] = {'\0'};
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, p_file_name_str, -1, NULL, 0, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, p_file_name_str, -1, file_name_multi_byte, size_needed, NULL, NULL);
|
||||
|
||||
// 拼接完整路径
|
||||
sprintf(file_path_multi_byte, "%s\\%s", public_path_multi_byte, file_name_multi_byte);
|
||||
|
||||
for (Input_File_Node *p_file_node = input_dlt_file_list_head; p_file_node != nullptr; p_file_node = p_file_node->p_next)
|
||||
if (!strcmp(p_file_node->file_name_str, file_path_multi_byte))
|
||||
{
|
||||
with_duplicated_input = true;
|
||||
break;
|
||||
}
|
||||
if (with_duplicated_input)
|
||||
continue;
|
||||
|
||||
// 开辟新文件节点
|
||||
Input_File_Node *p_new_file_node = (Input_File_Node *)malloc(sizeof(Input_File_Node));
|
||||
p_new_file_node->file_name_str = (char *)malloc(strlen(file_path_multi_byte) + 1);
|
||||
memset(p_new_file_node->file_name_str, '\0', strlen(file_path_multi_byte) + 1);
|
||||
memcpy(p_new_file_node->file_name_str, file_path_multi_byte, strlen(file_path_multi_byte) + 1);
|
||||
p_new_file_node->p_next = nullptr;
|
||||
|
||||
// 插入文件列表
|
||||
if (input_dlt_file_list_head == nullptr)
|
||||
input_dlt_file_list_head = p_new_file_node;
|
||||
else
|
||||
{
|
||||
Input_File_Node *p_target_node = input_dlt_file_list_head;
|
||||
for (size_t count = 1; count < input_dlt_file_count; count++)
|
||||
p_target_node = p_target_node->p_next;
|
||||
|
||||
p_target_node->p_next = p_new_file_node;
|
||||
}
|
||||
|
||||
input_dlt_file_count++;
|
||||
}
|
||||
|
||||
if (with_duplicated_input)
|
||||
{
|
||||
MessageBoxW(Main_Window_hWnd, L"存在重复输入", L"", MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 仅在外部拖拽入内时触发,内部拖拽不触发
|
||||
pressed_hover = (ImGui::IsItemHovered() && (GetAsyncKeyState(VK_LBUTTON) < 0) && (!ImGui::IsMouseDown(ImGuiMouseButton_Left)));
|
||||
|
||||
@ -63,22 +194,52 @@ void Widgets::Drag_Input_Area(const ImVec2 &size)
|
||||
void Widgets::File_List_Area(const ImVec2 &size)
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f);
|
||||
ImGui::BeginChild("File_List_Area", ImVec2(size.x, size.y), ImGuiChildFlags_Border);
|
||||
ImGui::BeginChild("File_List_Area_Wrapper", ImVec2(size.x, size.y), ImGuiChildFlags_Border);
|
||||
ImGui::PopStyleVar();
|
||||
{
|
||||
|
||||
ImGui::Dummy(ImVec2(ImGui::GetContentRegionAvail().x - 30, ImGui::GetContentRegionAvail().y));
|
||||
int element_id = 0;
|
||||
Input_File_Node *p_file_node_pre = nullptr;
|
||||
Input_File_Node *p_file_node = input_dlt_file_list_head;
|
||||
for (size_t count = 0; count < input_dlt_file_count; count++)
|
||||
{
|
||||
ImGui::PushID(element_id++);
|
||||
|
||||
// 点击了删除
|
||||
if (ImGui::Button("X"))
|
||||
{
|
||||
if (p_file_node == input_dlt_file_list_head)
|
||||
{
|
||||
free(input_dlt_file_list_head->file_name_str);
|
||||
input_dlt_file_list_head = input_dlt_file_list_head->p_next;
|
||||
free(p_file_node);
|
||||
p_file_node = input_dlt_file_list_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_file_node_pre->p_next = p_file_node->p_next;
|
||||
free(p_file_node->file_name_str);
|
||||
free(p_file_node);
|
||||
}
|
||||
input_dlt_file_count--;
|
||||
count--;
|
||||
ImGui::PopID();
|
||||
continue;
|
||||
}
|
||||
|
||||
const float spacing = 4;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 10.0f); // 绘制风格栈压入窗口圆角为10
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_GrabRounding, 10.0f); // 抓取条圆角
|
||||
static int int_value = 0;
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::VSliderInt("int", ImVec2(30, ImGui::GetContentRegionAvail().y), &int_value, 0, 5);
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::InputText("##Text_Show", p_file_node->file_name_str, strlen(p_file_node->file_name_str) + 1, ImGuiInputTextFlags_ElideLeft | ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoUndoRedo);
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopID();
|
||||
|
||||
p_file_node = p_file_node->p_next;
|
||||
if (count == 0)
|
||||
p_file_node_pre = input_dlt_file_list_head;
|
||||
else
|
||||
p_file_node_pre = p_file_node_pre->p_next;
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user