3 #include "WindowsFileDialog.hxx"
8 #include <boost/foreach.hpp>
10 #include <osgViewer/Viewer>
11 #include <osgViewer/api/Win32/GraphicsWindowWin32>
13 #include <simgear/debug/logstream.hxx>
14 #include <simgear/misc/strutils.hxx>
16 #include <Main/globals.hxx>
17 #include <Main/fg_props.hxx>
18 #include <Viewer/renderer.hxx>
22 HWND getMainViewerHWND()
24 osgViewer::Viewer::Windows windows;
25 if (!globals->get_renderer() || !globals->get_renderer()->getViewer()) {
29 globals->get_renderer()->getViewer()->getWindows(windows);
30 osgViewer::Viewer::Windows::const_iterator it = windows.begin();
31 for(; it != windows.end(); ++it) {
32 if (strcmp((*it)->className(), "GraphicsWindowWin32")) {
36 osgViewer::GraphicsWindowWin32* platformWin =
37 static_cast<osgViewer::GraphicsWindowWin32*>(*it);
38 return platformWin->getHWND();
44 static int CALLBACK BrowseFolderCallback(
45 HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
47 if (uMsg == BFFM_INITIALIZED) {
48 // set the initial directory now
49 WindowsFileDialog* dlg = reinterpret_cast<WindowsFileDialog*>(lpData);
50 LPCTSTR path = dlg->getDirectory().c_str();
51 ::SendMessage(hwnd, BFFM_SETSELECTION, true, (LPARAM) path);
56 } // of anonymous namespace
58 WindowsFileDialog::WindowsFileDialog(FGFileDialog::Usage use) :
64 WindowsFileDialog::~WindowsFileDialog()
69 void WindowsFileDialog::exec()
71 char Filestring[MAX_PATH] = "\0";
73 opf.lStructSize = sizeof(OPENFILENAME);
74 opf.lpstrFile = Filestring;
75 opf.lpstrTitle = const_cast<char *>(_title.c_str());
76 opf.nMaxFile = MAX_PATH;
78 std::string extensions;
80 if (!_filterPatterns.empty()) {
81 BOOST_FOREACH(std::string ext, _filterPatterns) {
82 if (!simgear::strutils::starts_with(ext, "*.")) {
83 SG_LOG(SG_GENERAL, SG_ALERT, "WindowsFileDialog: can't use pattern on Windows:" << ext);
86 extensions += "("+ext+")\0"+ext+"\0";
87 extensionsLen += ext.size()*2+4;
89 opf.lpstrFilter = (LPCSTR) malloc(extensionsLen);
90 memcpy((void*)opf.lpstrFilter, (void*)extensions.data(), extensionsLen);
93 opf.lpstrInitialDir = const_cast<char *>(_initialPath.c_str());
96 opf.Flags = OFN_PATHMUSTEXIST;
99 if (_usage == USE_SAVE_FILE) {
100 if (GetSaveFileNameA(&opf)) {
101 std::string stringPath(opf.lpstrFile);
102 _callback->onFileDialogDone(this, stringPath);
104 } else if (_usage == USE_CHOOSE_DIR) {
107 if (GetOpenFileNameA(&opf)) {
108 std::string stringPath(opf.lpstrFile);
109 _callback->onFileDialogDone(this, stringPath);
114 void WindowsFileDialog::close()
119 void WindowsFileDialog::chooseDir()
121 // MSDN says this needs to be called first
124 char pathBuf[MAX_PATH] = "\0";
127 memset(&binfo, 0, sizeof(BROWSEINFO));
128 binfo.hwndOwner = getMainViewerHWND();
129 binfo.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_EDITBOX;
131 binfo.pidlRoot = NULL; // can browse anywhere
132 binfo.lpszTitle = const_cast<char *>(_title.c_str());
133 binfo.lpfn = BrowseFolderCallback;
134 binfo.lParam = reinterpret_cast<LPARAM>(this);
136 PIDLIST_ABSOLUTE results = SHBrowseForFolder(&binfo);
137 if (results == NULL) {
142 SHGetPathFromIDList(results, pathBuf);
143 CoTaskMemFree(results);
145 _callback->onFileDialogDone(this, SGPath(pathBuf));