diff --git a/src/dialogs.h b/src/dialogs.h index 5acf6ea..9611783 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -11,4 +11,80 @@ class Dialog { static std::string save_file(); }; // namespace Dialog -#endif // JUCI_DIALOG_H_ \ No newline at end of file +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NTDDI_VERSION NTDDI_VISTA +#define _WIN32_WINNT _WIN32_WINNT_VISTA + +#include +#include + +#include +#include +#include +#include "singletons.h" + +#ifndef check +HRESULT __hr__; +#define check(__fun__, error_message) \ + __hr__ = __fun__; \ + if (FAILED(__hr__)) { \ + Singleton::terminal()->print(error_message); \ + throw std::exception(error_message); + } +#endif + + +// http://stackoverflow.com/questions/4804298/how-to-convert-wstring-into-string +std::wstring s2ws(const std::string& str) { + typedef std::codecvt_utf8 convert_typeX; + std::wstring_convert converterX; + return converterX.from_bytes(str); +} + +std::string ws2s(const std::wstring& wstr) { + typedef std::codecvt_utf8 convert_typeX; + std::wstring_convert converterX; + return converterX.to_bytes(wstr); +} + +class WinString { +public: + WinString() : str(nullptr) { } + WinString(const std::string &string); + ~WinString() { CoTaskMemFree(static_cast(str)); } + std::string operator()(); + wchar_t** operator&() { return &str; } +private: + wchar_t* str; +}; + +class CommonDialog { +public: + CommonDialog(CLSID type); + void add_option(unsigned option); + void set_title(const std::string &title); + std::string show(); + +private: + IFileDialog * dialog; + DWORD options; +}; + +class OpenDialog : public CommonDialog { +public: + OpenDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileOpenDialog) { + set_title(title); + add_option(option); + } +}; + +class SaveDialog : public CommonDialog { +public: + SaveDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileSaveDialog) { + set_title(title); + add_option(option); + } +}; +#endif +#endif // JUCI_DIALOG_H_ diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index e6891ee..ee1b30e 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,24 +1,70 @@ #ifdef _WIN32 #include "dialogs.h" -#include +// { WIN_STRING +WinString::WinString(const std::string &string) { + std::wstringstream ss; + ss << s2ws(string); + ss >> str; +} + +WinString::operator()() { + std::string res; + if (str != nullptr) { + std::wstring ss(str); + res = ws2s(ss); + } + return res; +} +// WIN_STRING } + +// { COMMON_DIALOG +CommonDialog::CommonDialog(CLSID type) : dialog(nullptr) { + check(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)), "Failed to create instance"); + check(dialog->GetOptions(&options), "Failed to get options from instance"); +} + +void CommonDialog::set_title(const std::string &title) { + auto tmp = std::wstring(title.begin(), title.end()); + auto t = tmp.data(); + check(dialog->SetTitle(t), "Failed to set dialog title"); +} + +void CommonDialog::add_option(unsigned option) { + check(dialog->SetOptions(options | option), "Failed to set options"); +} + +std::string CommonDialog::show() { + try { + check(dialog->Show(nullptr), "Failed to show dialog"); + IShellItem *result = nullptr; + check(dialog->GetResult(&result), "Failed to get result from dialog"); + win_string str; + check(result->GetDisplayName(SIGDN_FILESYSPATH, &str), "Failed to get display name from dialog"); + result->Release(); + return str(); + } catch (std::exception e) { + return ""; + } +} +// COMMON_DIALOG }} std::string Dialog::select_folder() { - return c_select_folder(); + return (OpenDialog("Select folder", FOS_PICKFOLDERS)).show(); } std::string Dialog::new_file() { - return c_new_file(); + return (SaveDialog("Please choose your destination", 0)).show(); } std::string Dialog::new_folder() { - return c_new_folder(); + return Dialog::select_folder(); } std::string Dialog::select_file() { - return c_select_file(); + return (OpenDialog("Open file", 0)).show(); } std::string Dialog::save_file() { - return c_save_file(); + return (SaveDialog("Please choose your destination", 0)).show(); } #endif