fix bug that shobjidl.h isn't supported well on MinGW
This commit is contained in:
parent
3075eccacf
commit
a120447716
@ -16,6 +16,7 @@
|
|||||||
#define NANA_GUI_FILEBOX_HPP
|
#define NANA_GUI_FILEBOX_HPP
|
||||||
#include <nana/gui/basis.hpp>
|
#include <nana/gui/basis.hpp>
|
||||||
#include <nana/filesystem/filesystem.hpp>
|
#include <nana/filesystem/filesystem.hpp>
|
||||||
|
#include <nana/optional.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -16,7 +16,11 @@
|
|||||||
|
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <Shobjidl.h>
|
# ifndef NANA_MINGW //<Shobjidl.h> isn't supported well on MinGW
|
||||||
|
# include <Shobjidl.h>
|
||||||
|
# else
|
||||||
|
# include <Shlobj.h>
|
||||||
|
# endif
|
||||||
#elif defined(NANA_POSIX)
|
#elif defined(NANA_POSIX)
|
||||||
# include <nana/gui/widgets/label.hpp>
|
# include <nana/gui/widgets/label.hpp>
|
||||||
# include <nana/gui/widgets/button.hpp>
|
# include <nana/gui/widgets/button.hpp>
|
||||||
@ -243,10 +247,10 @@ namespace nana
|
|||||||
|
|
||||||
std::size_t end_a = a.find_first_not_of("0123456789", pos_a + 1);
|
std::size_t end_a = a.find_first_not_of("0123456789", pos_a + 1);
|
||||||
std::size_t end_b = b.find_first_not_of("0123456789", pos_b + 1);
|
std::size_t end_b = b.find_first_not_of("0123456789", pos_b + 1);
|
||||||
|
|
||||||
auto num_a = a.substr(pos_a, end_a != a.npos ? end_a - pos_a : a.npos);
|
auto num_a = a.substr(pos_a, end_a != a.npos ? end_a - pos_a : a.npos);
|
||||||
auto num_b = b.substr(pos_b, end_b != b.npos ? end_b - pos_b : b.npos);
|
auto num_b = b.substr(pos_b, end_b != b.npos ? end_b - pos_b : b.npos);
|
||||||
|
|
||||||
if(num_a != num_b)
|
if(num_a != num_b)
|
||||||
{
|
{
|
||||||
double ai = std::stod(num_a, 0);
|
double ai = std::stod(num_a, 0);
|
||||||
@ -294,7 +298,7 @@ namespace nana
|
|||||||
lb_file_.i18n(i18n_eval(idstr));
|
lb_file_.i18n(i18n_eval(idstr));
|
||||||
lb_file_.text_align(align::right, align_v::center);
|
lb_file_.text_align(align::right, align_v::center);
|
||||||
|
|
||||||
|
|
||||||
tb_file_.create(*this);
|
tb_file_.create(*this);
|
||||||
tb_file_.multi_lines(false);
|
tb_file_.multi_lines(false);
|
||||||
|
|
||||||
@ -350,7 +354,7 @@ namespace nana
|
|||||||
this->i18n(i18n_eval(idstr));
|
this->i18n(i18n_eval(idstr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
caption(title);
|
caption(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void def_extension(const std::string& ext)
|
void def_extension(const std::string& ext)
|
||||||
@ -390,7 +394,7 @@ namespace nana
|
|||||||
|
|
||||||
tb_file_.caption(file_with_path_removed);
|
tb_file_.caption(file_with_path_removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_filter(const std::string& desc, const std::string& type)
|
void add_filter(const std::string& desc, const std::string& type)
|
||||||
{
|
{
|
||||||
std::size_t i = cb_types_.the_number_of_options();
|
std::size_t i = cb_types_.the_number_of_options();
|
||||||
@ -558,7 +562,7 @@ namespace nana
|
|||||||
m.bytes = fs::file_size(fpath);
|
m.bytes = fs::file_size(fpath);
|
||||||
|
|
||||||
fs_ext::modified_file_time(fpath, m.modified_time);
|
fs_ext::modified_file_time(fpath, m.modified_time);
|
||||||
|
|
||||||
file_container_.push_back(m);
|
file_container_.push_back(m);
|
||||||
|
|
||||||
if(m.directory)
|
if(m.directory)
|
||||||
@ -575,7 +579,7 @@ namespace nana
|
|||||||
auto beg_node = tree_.selected();
|
auto beg_node = tree_.selected();
|
||||||
while(!beg_node.empty() && (beg_node != nodes_.home) && (beg_node != nodes_.filesystem))
|
while(!beg_node.empty() && (beg_node != nodes_.home) && (beg_node != nodes_.filesystem))
|
||||||
beg_node = beg_node.owner();
|
beg_node = beg_node.owner();
|
||||||
|
|
||||||
auto head = fs_ext::path_user().native();
|
auto head = fs_ext::path_user().native();
|
||||||
if(path.size() >= head.size() && (path.substr(0, head.size()) == head))
|
if(path.size() >= head.size() && (path.substr(0, head.size()) == head))
|
||||||
{//This is HOME
|
{//This is HOME
|
||||||
@ -605,20 +609,20 @@ namespace nana
|
|||||||
if(cat_path.size() && cat_path[cat_path.size() - 1] != '/')
|
if(cat_path.size() && cat_path[cat_path.size() - 1] != '/')
|
||||||
cat_path += '/';
|
cat_path += '/';
|
||||||
|
|
||||||
|
|
||||||
auto beg = head.size();
|
auto beg = head.size();
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
auto pos = path.find('/', beg);
|
auto pos = path.find('/', beg);
|
||||||
auto folder = path.substr(beg, pos != path.npos ? pos - beg: path.npos);
|
auto folder = path.substr(beg, pos != path.npos ? pos - beg: path.npos);
|
||||||
|
|
||||||
if(folder.empty())
|
if(folder.empty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
(cat_path += folder) += '/';
|
(cat_path += folder) += '/';
|
||||||
(head += folder) += '/';
|
(head += folder) += '/';
|
||||||
path_.caption(cat_path);
|
path_.caption(cat_path);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for(fs::directory_iterator i(head); i != end; ++i)
|
for(fs::directory_iterator i(head); i != end; ++i)
|
||||||
@ -748,7 +752,7 @@ namespace nana
|
|||||||
mb<<i18n("NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_FAILED_CREATION");
|
mb<<i18n("NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_FAILED_CREATION");
|
||||||
mb();
|
mb();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_._m_load_cat_path(fb_.addr_.filesystem);
|
fb_._m_load_cat_path(fb_.addr_.filesystem);
|
||||||
fm_.close();
|
fm_.close();
|
||||||
@ -778,7 +782,7 @@ namespace nana
|
|||||||
|
|
||||||
auto exts = cb_types_.anyobj<std::vector<std::string> >(cb_types_.option());
|
auto exts = cb_types_.anyobj<std::vector<std::string> >(cb_types_.option());
|
||||||
if(0 == exts || exts->size() == 0) return false;
|
if(0 == exts || exts->size() == 0) return false;
|
||||||
|
|
||||||
auto & ext = exts->at(0);
|
auto & ext = exts->at(0);
|
||||||
if(def_ext_[0] != '.')
|
if(def_ext_[0] != '.')
|
||||||
tar += '.';
|
tar += '.';
|
||||||
@ -791,7 +795,7 @@ namespace nana
|
|||||||
auto sel = ls_file_.selected();
|
auto sel = ls_file_.selected();
|
||||||
if(sel.empty())
|
if(sel.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto index = sel[0];
|
auto index = sel[0];
|
||||||
item_fs m;
|
item_fs m;
|
||||||
ls_file_.at(index).resolve_to(m);
|
ls_file_.at(index).resolve_to(m);
|
||||||
@ -831,7 +835,7 @@ namespace nana
|
|||||||
mb();
|
mb();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file[0] == '/')
|
if(file[0] == '/')
|
||||||
tar = file;
|
tar = file;
|
||||||
else
|
else
|
||||||
@ -850,7 +854,7 @@ namespace nana
|
|||||||
ftype = static_cast<fs::file_type>(fattr.type());
|
ftype = static_cast<fs::file_type>(fattr.type());
|
||||||
is_dir = fs::is_directory(fattr);
|
is_dir = fs::is_directory(fattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_dir)
|
if(is_dir)
|
||||||
{
|
{
|
||||||
_m_load_cat_path(tar);
|
_m_load_cat_path(tar);
|
||||||
@ -1078,7 +1082,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return impl_->path;
|
return impl_->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filebox::file() const
|
std::string filebox::file() const
|
||||||
{
|
{
|
||||||
return impl_->file;
|
return impl_->file;
|
||||||
@ -1150,7 +1154,7 @@ namespace nana
|
|||||||
ofn.lpstrFileTitle = nullptr;
|
ofn.lpstrFileTitle = nullptr;
|
||||||
ofn.nMaxFileTitle = 0;
|
ofn.nMaxFileTitle = 0;
|
||||||
ofn.lpstrInitialDir = (wpath.empty() ? nullptr : wpath.c_str());
|
ofn.lpstrInitialDir = (wpath.empty() ? nullptr : wpath.c_str());
|
||||||
|
|
||||||
if (!impl_->open_or_save)
|
if (!impl_->open_or_save)
|
||||||
ofn.Flags = OFN_OVERWRITEPROMPT; //Overwrite prompt if it is save mode
|
ofn.Flags = OFN_OVERWRITEPROMPT; //Overwrite prompt if it is save mode
|
||||||
ofn.Flags |= OFN_NOCHANGEDIR;
|
ofn.Flags |= OFN_NOCHANGEDIR;
|
||||||
@ -1166,7 +1170,7 @@ namespace nana
|
|||||||
#elif defined(NANA_POSIX)
|
#elif defined(NANA_POSIX)
|
||||||
using mode = filebox_implement::mode;
|
using mode = filebox_implement::mode;
|
||||||
filebox_implement fb(impl_->owner, (impl_->open_or_save ? mode::open_file : mode::write_file), impl_->title);
|
filebox_implement fb(impl_->owner, (impl_->open_or_save ? mode::open_file : mode::write_file), impl_->title);
|
||||||
|
|
||||||
if(impl_->filters.size())
|
if(impl_->filters.size())
|
||||||
{
|
{
|
||||||
for(auto & f: impl_->filters)
|
for(auto & f: impl_->filters)
|
||||||
@ -1221,12 +1225,30 @@ namespace nana
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NANA_MINGW
|
||||||
|
static int CALLBACK browse_folder_callback(HWND hwnd, UINT msg, LPARAM lparam, LPARAM data)
|
||||||
|
{
|
||||||
|
// If the BFFM_INITIALIZED message is received
|
||||||
|
// set the path to the start path.
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case BFFM_INITIALIZED:
|
||||||
|
if (data)
|
||||||
|
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // The function should always return 0.
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::optional<folderbox::path_type> folderbox::show() const
|
std::optional<folderbox::path_type> folderbox::show() const
|
||||||
{
|
{
|
||||||
#ifdef NANA_WINDOWS
|
#ifdef NANA_WINDOWS
|
||||||
std::optional<folderbox::path_type> target;
|
std::optional<folderbox::path_type> target;
|
||||||
|
|
||||||
CoInitialize(NULL);
|
::CoInitialize(nullptr);
|
||||||
|
#ifndef NANA_MINGW
|
||||||
IFileDialog *fd(nullptr);
|
IFileDialog *fd(nullptr);
|
||||||
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fd));
|
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fd));
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
@ -1254,7 +1276,28 @@ namespace nana
|
|||||||
}
|
}
|
||||||
fd->Release();
|
fd->Release();
|
||||||
}
|
}
|
||||||
CoUninitialize();
|
#else
|
||||||
|
BROWSEINFO brw = { 0 };
|
||||||
|
wchar_t display_text[MAX_PATH];
|
||||||
|
brw.hwndOwner = reinterpret_cast<HWND>(API::root(impl_->owner));
|
||||||
|
brw.pszDisplayName = display_text;
|
||||||
|
brw.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
|
||||||
|
brw.lpfn = browse_folder_callback;
|
||||||
|
|
||||||
|
std::wstring init_path = impl_->init_path.wstring();
|
||||||
|
brw.lParam = reinterpret_cast<LPARAM>(init_path.c_str());
|
||||||
|
auto pidl = ::SHBrowseForFolder(&brw);
|
||||||
|
|
||||||
|
if (pidl)
|
||||||
|
{
|
||||||
|
wchar_t folder_path[MAX_PATH];
|
||||||
|
if (FALSE != SHGetPathFromIDList(pidl, folder_path))
|
||||||
|
target = folder_path;
|
||||||
|
|
||||||
|
CoTaskMemFree(pidl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
::CoUninitialize();
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user