diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 79d26431..be7a9156 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -32,7 +32,7 @@ e2d::Game::Game() , _transition(nullptr) , _scenes() { - CoInitialize(nullptr); + ::CoInitialize(nullptr); _window = Window::getInstance(); _input = Input::getInstance(); @@ -43,7 +43,7 @@ e2d::Game::Game() e2d::Game::~Game() { - CoUninitialize(); + ::CoUninitialize(); } void e2d::Game::start() diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index 4e544935..9cdb51ab 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -27,7 +27,7 @@ e2d::Input::Input() , _keyboardDevice(false) , _mouseDevice(false) { - CoInitialize(nullptr); + ::CoInitialize(nullptr); ZeroMemory(_keyBuffer, sizeof(_keyBuffer)); ZeroMemory(&_mouseState, sizeof(_mouseState)); @@ -85,7 +85,7 @@ e2d::Input::~Input() SafeRelease(_keyboardDevice); SafeRelease(_directInput); - CoUninitialize(); + ::CoUninitialize(); } void e2d::Input::update() diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index cd0c2559..2733b568 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -47,7 +47,7 @@ e2d::Renderer::Renderer() , _textRenderer(nullptr) , _clearColor(D2D1::ColorF(D2D1::ColorF::Black)) { - CoInitialize(nullptr); + ::CoInitialize(nullptr); HWND hWnd = Window::getInstance()->getHWnd(); @@ -99,7 +99,7 @@ e2d::Renderer::~Renderer() SafeRelease(_solidBrush); SafeRelease(_renderTarget); - CoUninitialize(); + ::CoUninitialize(); } void e2d::Renderer::beginDraw() @@ -216,12 +216,16 @@ ID2D1Factory * e2d::Renderer::getFactory() { if (!_factory) { + ::CoInitialize(nullptr); + ThrowIfFailed( D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, &_factory ) ); + + ::CoUninitialize(); } return _factory; } @@ -230,6 +234,8 @@ IWICImagingFactory * e2d::Renderer::getImagingFactory() { if (!_imagingFactory) { + ::CoInitialize(nullptr); + ThrowIfFailed( CoCreateInstance( CLSID_WICImagingFactory, @@ -239,6 +245,8 @@ IWICImagingFactory * e2d::Renderer::getImagingFactory() reinterpret_cast(&_imagingFactory) ) ); + + ::CoUninitialize(); } return _imagingFactory; } @@ -247,6 +255,8 @@ IDWriteFactory * e2d::Renderer::getWriteFactory() { if (!_writeFactory) { + ::CoInitialize(nullptr); + ThrowIfFailed( DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, @@ -254,6 +264,8 @@ IDWriteFactory * e2d::Renderer::getWriteFactory() reinterpret_cast(&_writeFactory) ) ); + + ::CoUninitialize(); } return _writeFactory; } diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 6e9c74f3..7e3d122d 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -34,7 +34,7 @@ e2d::Window::Window() , _iconID(0) , _dpi(0.f) { - CoInitialize(nullptr); + ::CoInitialize(nullptr); // 获取系统 DPI _dpi = static_cast(::GetDpiForSystem()); @@ -50,7 +50,7 @@ e2d::Window::~Window() if (_hWnd) ::DestroyWindow(_hWnd); - CoUninitialize(); + ::CoUninitialize(); } bool e2d::Window::createMutex(const String & mutex) diff --git a/core/Custom/VoiceCallback.cpp b/core/Custom/VoiceCallback.cpp index 516e57c0..afe2c79c 100644 --- a/core/Custom/VoiceCallback.cpp +++ b/core/Custom/VoiceCallback.cpp @@ -1,6 +1,5 @@ #include "..\e2dcustom.h" -#include "..\e2dbase.h" -#include "..\e2dtool.h" +#include "..\e2dcommon.h" e2d::VoiceCallback::VoiceCallback() { diff --git a/core/Tool/File.cpp b/core/Tool/File.cpp index f5b2ed92..7adcb5e1 100644 --- a/core/Tool/File.cpp +++ b/core/Tool/File.cpp @@ -1,5 +1,5 @@ #include "..\e2dtool.h" -#include +#include std::list e2d::File::_searchPaths; @@ -158,27 +158,144 @@ bool e2d::File::createFolder(const String & dirPath) return true; } -e2d::String e2d::File::getSaveFilePath(const String& title, const String& defExt) +e2d::File e2d::File::showOpenDialog(const String & title, const String & filter) { - HWND hwnd = Window::getInstance()->getHWnd(); + String filePath; + HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - // 弹出保存对话框 - OPENFILENAME ofn = { 0 }; - wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名 - ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小 - ofn.hwndOwner = hwnd; // 窗口句柄 - ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤 - ofn.nFilterIndex = 1; // 过滤器索引 - ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名 - ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度 - ofn.lpstrInitialDir = nullptr; // 初始目录为默认 - ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; - ofn.lpstrTitle = (LPCWSTR)title; // 标题 - ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名 - - if (::GetSaveFileName(&ofn)) + if (SUCCEEDED(hr)) { - return strFilename; + IFileOpenDialog *pFileOpen; + + hr = ::CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, + IID_IFileOpenDialog, reinterpret_cast(&pFileOpen)); + + if (SUCCEEDED(hr)) + { + if (!title.isEmpty()) + { + pFileOpen->SetTitle(LPCWSTR(title)); + } + + if (!filter.isEmpty()) + { + COMDLG_FILTERSPEC rgSpec[] = + { + { L"", LPCWSTR(filter) } + }; + pFileOpen->SetFileTypes(1, rgSpec); + } + else + { + COMDLG_FILTERSPEC rgSpec[] = + { + { L"所有文件", L"*.*" } + }; + pFileOpen->SetFileTypes(1, rgSpec); + } + + Game::getInstance()->pause(); + { + HWND hWnd = Window::getInstance()->getHWnd(); + hr = pFileOpen->Show(hWnd); + } + Game::getInstance()->resume(); + + if (SUCCEEDED(hr)) + { + IShellItem *pItem; + hr = pFileOpen->GetResult(&pItem); + if (SUCCEEDED(hr)) + { + PWSTR pszFilePath; + hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath); + + if (SUCCEEDED(hr)) + { + filePath = pszFilePath; + ::CoTaskMemFree(pszFilePath); + } + pItem->Release(); + } + } + pFileOpen->Release(); + } + ::CoUninitialize(); } - return std::move(String()); + return std::move(File(filePath)); +} + +e2d::File e2d::File::showSaveDialog(const String & title, const String& defFile, const String & defExt) +{ + String filePath; + HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + + if (SUCCEEDED(hr)) + { + IFileSaveDialog *pFileSave; + + hr = ::CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, + IID_IFileSaveDialog, reinterpret_cast(&pFileSave)); + + if (SUCCEEDED(hr)) + { + if (!title.isEmpty()) + { + pFileSave->SetTitle(LPCWSTR(title)); + } + + if (!defFile.isEmpty()) + { + pFileSave->SetFileName(LPCWSTR(defFile)); + } + + if (!defExt.isEmpty()) + { + pFileSave->SetDefaultExtension(LPCWSTR(defExt)); + + String spec = L"*." + defExt; + COMDLG_FILTERSPEC rgSpec[] = + { + { L"", LPCWSTR(spec) } + }; + pFileSave->SetFileTypes(1, rgSpec); + } + else + { + COMDLG_FILTERSPEC rgSpec[] = + { + { L"所有文件", L"*.*" } + }; + pFileSave->SetFileTypes(1, rgSpec); + } + + Game::getInstance()->pause(); + { + HWND hWnd = Window::getInstance()->getHWnd(); + hr = pFileSave->Show(hWnd); + } + Game::getInstance()->resume(); + + if (SUCCEEDED(hr)) + { + IShellItem *pItem; + hr = pFileSave->GetResult(&pItem); + if (SUCCEEDED(hr)) + { + PWSTR pszFilePath; + hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath); + + if (SUCCEEDED(hr)) + { + filePath = pszFilePath; + ::CoTaskMemFree(pszFilePath); + } + pItem->Release(); + } + } + pFileSave->Release(); + } + ::CoUninitialize(); + } + return std::move(File(filePath)); } diff --git a/core/Tool/Music.cpp b/core/Tool/Music.cpp index d7a8e4bc..ea966e66 100644 --- a/core/Tool/Music.cpp +++ b/core/Tool/Music.cpp @@ -24,7 +24,7 @@ inline bool TraceError(wchar_t* sPrompt, HRESULT hr) e2d::Music::XAudio2Tool::XAudio2Tool() { - CoInitialize(nullptr); + ::CoInitialize(nullptr); ThrowIfFailed( XAudio2Create(&_xAudio2, 0) @@ -40,7 +40,7 @@ e2d::Music::XAudio2Tool::~XAudio2Tool() _masteringVoice->DestroyVoice(); _xAudio2->Release(); - CoUninitialize(); + ::CoUninitialize(); } e2d::Music::XAudio2Tool* e2d::Music::XAudio2Tool::getInstance() diff --git a/core/Tool/Path.cpp b/core/Tool/Path.cpp index e08e9afc..c164bc2e 100644 --- a/core/Tool/Path.cpp +++ b/core/Tool/Path.cpp @@ -1,9 +1,5 @@ #include "..\e2dtool.h" - -extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_LocalAppData = { - 0xF1B32785, 0x6FBA, 0x4FCF, { 0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91 } -}; - +#include e2d::String e2d::Path::getDataPath() { @@ -60,18 +56,9 @@ e2d::String e2d::Path::getLocalAppDataPath() if (localAppDataPath.isEmpty()) { // 获取 AppData/Local 文件夹的路径 - typedef HRESULT(WINAPI* pFunSHGetKnownFolderPath)(const GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); - - PWSTR pszPath = nullptr; - HMODULE hModule = LoadLibrary(L"shell32.dll"); - pFunSHGetKnownFolderPath SHGetKnownFolderPath = (pFunSHGetKnownFolderPath)GetProcAddress(hModule, "SHGetKnownFolderPath"); - HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &pszPath); - - if (SUCCEEDED(hr)) - { - localAppDataPath = pszPath; - CoTaskMemFree(pszPath); - } + WCHAR strPath[MAX_PATH] = { 0 }; + ::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath); + localAppDataPath = strPath; } return localAppDataPath; diff --git a/core/e2dtool.h b/core/e2dtool.h index 0ae132fb..b2c53f7b 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -482,10 +482,17 @@ public: const String& dirPath /* 文件夹路径 */ ); - // 打开保存文件对话框 - static String getSaveFilePath( - const String& title = L"保存到", /* 对话框标题 */ - const String& defExt = L"" /* 默认扩展名 */ + // 弹出打开文件对话框 + static File showOpenDialog( + const String& title = L"打开", /* 对话框标题 */ + const String& filter = L"" /* 筛选扩展名,例如 "*.jpg;*.jpeg" */ + ); + + // 弹出保存文件对话框 + static File showSaveDialog( + const String& title = L"保存", /* 对话框标题 */ + const String& defFile = L"", /* 默认保存的文件名 */ + const String& defExt = L"" /* 默认追加的扩展名,例如 "txt" */ ); protected: