CppUtils/Utils/Dialog.cpp

275 lines
6.9 KiB
C++
Raw Normal View History

2025-06-05 10:06:43 +08:00
#include "Dialog.h"
HWND GetTopMostWindowInCurrentProcess()
{
struct EnumParams {
DWORD processID;
HWND topMostWindow;
};
DWORD currentProcessID = GetCurrentProcessId();
EnumParams params = { currentProcessID, NULL };
EnumWindows(
[](HWND hwnd, LPARAM lParam) {
EnumParams* params = (EnumParams*)lParam;
DWORD windowProcessID;
GetWindowThreadProcessId(hwnd, &windowProcessID);
if (windowProcessID == params->processID) {
HWND hwndTop = hwnd;
while (hwndTop != NULL) {
hwndTop = GetWindow(hwndTop, GW_HWNDPREV);
if (hwndTop == NULL) {
params->topMostWindow = hwnd;
break;
}
}
}
return TRUE;
}, (LPARAM)&params);
return params.topMostWindow;
}
OpenFileDialog::OpenFileDialog()
: FilterIndex(0),
Multiselect(false),
SupportMultiDottedExtensions(false),
DereferenceLinks(true),
ValidateNames(true),
Filter("All Files\0*.*\0"),
Title("Open File")
{
}
DialogResult OpenFileDialog::ShowDialog(HWND owner)
{
Filter.append(2, '\0');
OPENFILENAMEA ofn;
CHAR szFile[1024] = { 0 };
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner;
ofn.hInstance = GetModuleHandle(NULL);
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = Filter.c_str();
ofn.nFilterIndex = FilterIndex;
ofn.lpstrTitle = Title.c_str();
ofn.lpstrInitialDir = InitialDirectory.empty() ? NULL : InitialDirectory.c_str();
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (Multiselect)
{
ofn.Flags |= OFN_ALLOWMULTISELECT | OFN_EXPLORER;
}
if (!DereferenceLinks)
{
ofn.Flags |= OFN_NODEREFERENCELINKS;
}
if (!ValidateNames)
{
ofn.Flags |= OFN_NOVALIDATE;
}
if (GetOpenFileNameA(&ofn) == TRUE)
{
SelectedPaths.clear();
if (Multiselect)
{
CHAR* p = ofn.lpstrFile;
std::string directory = p;
p += directory.size() + 1;
while (*p)
{
std::string filename = p;
std::string fullpath = directory + "\\" + filename;
SelectedPaths.push_back(fullpath);
p += filename.size() + 1;
}
if (SelectedPaths.empty())
{
SelectedPaths.push_back(directory);
}
}
else
{
SelectedPaths.push_back(ofn.lpstrFile);
}
return DialogResult::OK;
}
else
{
DWORD err = CommDlgExtendedError();
if (err != 0)
{
return DialogResult::Abort;
}
else
{
return DialogResult::Cancel;
}
}
}
SaveFileDialog::SaveFileDialog()
: FilterIndex(0),
SupportMultiDottedExtensions(false),
DereferenceLinks(true),
ValidateNames(true),
Filter("All Files\0*.*\0"),
Title("Save File")
{
}
DialogResult SaveFileDialog::ShowDialog(HWND owner)
{
Filter.append(2, '\0');
OPENFILENAMEA ofn;
CHAR szFile[1024] = { 0 };
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner;
ofn.hInstance = GetModuleHandle(NULL);
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = Filter.c_str();
ofn.nFilterIndex = FilterIndex;
ofn.lpstrTitle = Title.c_str();
ofn.lpstrInitialDir = InitialDirectory.empty() ? NULL : InitialDirectory.c_str();
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (SupportMultiDottedExtensions)
{
ofn.Flags |= OFN_EXPLORER | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT | OFN_ENABLEHOOK;
}
if (GetSaveFileNameA(&ofn) == TRUE)
{
SelectedPath = ofn.lpstrFile;
return DialogResult::OK;
}
else
{
return DialogResult::Cancel;
}
}
FolderBrowserDialog::FolderBrowserDialog()
: ShowNewFolderButton(true),
Multiselect(false)
{
}
DialogResult FolderBrowserDialog::ShowDialog(HWND owner)
{
BROWSEINFOA bi = { 0 };
bi.hwndOwner = owner;
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = Description.c_str();
bi.ulFlags = BIF_RETURNONLYFSDIRS;
if (ShowNewFolderButton)
{
bi.ulFlags |= BIF_NEWDIALOGSTYLE;
}
LPITEMIDLIST idl = SHBrowseForFolderA(&bi);
if (idl == NULL)
{
return DialogResult::Cancel;
}
else
{
char path[MAX_PATH] = { 0 };
SHGetPathFromIDListA(idl, path);
SelectedPath = path;
return DialogResult::OK;
}
}
ColorDialog::ColorDialog()
: Color(RGB(0, 0, 0))
{
}
DialogResult ColorDialog::ShowDialog(HWND owner)
{
CHOOSECOLORA cc = { 0 };
static COLORREF acrCustClr[16];
cc.lStructSize = sizeof(cc);
cc.hwndOwner = owner;
cc.lpCustColors = (LPDWORD)acrCustClr;
cc.rgbResult = Color;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColorA(&cc))
{
Color = cc.rgbResult;
return DialogResult::OK;
}
else
{
return DialogResult::Cancel;
}
}
FontDialog::FontDialog()
: FontSize(9),
Color(RGB(0, 0, 0)),
Bold(false),
Italic(false),
Underline(false),
Strikeout(false)
{
}
/**
* @brief
*
* @param owner
* @return DialogResult DialogResult::OK DialogResult::Cancel
*
* @details 使 Windows API ChooseFontA
* FontNameFontSizeColor
* DPI
*/
DialogResult FontDialog::ShowDialog(HWND owner)
{
CHOOSEFONTA cf = {0};
static LOGFONTA lf = { 0 };
cf.lStructSize = sizeof(cf);
cf.hwndOwner = owner;
cf.lpLogFont = &lf;
cf.rgbColors = Color;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
if (ChooseFontA(&cf))
{
int fontSizeInPixels = abs(lf.lfHeight);
int dpi = GetDeviceCaps(GetDC(cf.hwndOwner), LOGPIXELSY);
int fontSize = MulDiv(fontSizeInPixels, 72, dpi);
FontName = lf.lfFaceName;
FontSize = fontSize;
Color = cf.rgbColors;
Bold = lf.lfWeight == FW_BOLD;
Italic = lf.lfItalic;
Underline = lf.lfUnderline;
Strikeout = lf.lfStrikeOut;
return DialogResult::OK;
}
else
{
return DialogResult::Cancel;
}
}
DialogResult MessageBox::Show(const std::string& text, const std::string& caption, UINT type)
{
return (DialogResult)MessageBoxA(GetTopMostWindowInCurrentProcess(), text.c_str(), caption.c_str(), type);
}
DialogResult MessageBox::Show(const std::wstring& text, const std::wstring& caption, UINT type)
{
return (DialogResult)MessageBoxW(GetTopMostWindowInCurrentProcess(), text.c_str(), caption.c_str(), type);
}