148 lines
No EOL
3.7 KiB
C++
148 lines
No EOL
3.7 KiB
C++
|
|
|
|
#include "WindowsFileDialog.hxx"
|
|
|
|
#include <windows.h>
|
|
#include <Shlobj.h>
|
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
#include <osgViewer/Viewer>
|
|
#include <osgViewer/api/Win32/GraphicsWindowWin32>
|
|
|
|
#include <simgear/debug/logstream.hxx>
|
|
#include <simgear/misc/strutils.hxx>
|
|
|
|
#include <Main/globals.hxx>
|
|
#include <Main/fg_props.hxx>
|
|
#include <Viewer/renderer.hxx>
|
|
|
|
namespace {
|
|
|
|
HWND getMainViewerHWND()
|
|
{
|
|
osgViewer::Viewer::Windows windows;
|
|
if (!globals->get_renderer() || !globals->get_renderer()->getViewer()) {
|
|
return 0;
|
|
}
|
|
|
|
globals->get_renderer()->getViewer()->getWindows(windows);
|
|
osgViewer::Viewer::Windows::const_iterator it = windows.begin();
|
|
for(; it != windows.end(); ++it) {
|
|
if (strcmp((*it)->className(), "GraphicsWindowWin32")) {
|
|
continue;
|
|
}
|
|
|
|
osgViewer::GraphicsWindowWin32* platformWin =
|
|
static_cast<osgViewer::GraphicsWindowWin32*>(*it);
|
|
return platformWin->getHWND();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int CALLBACK BrowseFolderCallback(
|
|
HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
|
{
|
|
if (uMsg == BFFM_INITIALIZED) {
|
|
// set the initial directory now
|
|
WindowsFileDialog* dlg = reinterpret_cast<WindowsFileDialog*>(lpData);
|
|
std::string s = dlg->getDirectory().local8BitStr();
|
|
LPCTSTR path = s.c_str();
|
|
::SendMessage(hwnd, BFFM_SETSELECTION, true, (LPARAM) path);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
} // of anonymous namespace
|
|
|
|
WindowsFileDialog::WindowsFileDialog(FGFileDialog::Usage use) :
|
|
FGFileDialog(use)
|
|
{
|
|
|
|
}
|
|
|
|
WindowsFileDialog::~WindowsFileDialog()
|
|
{
|
|
|
|
}
|
|
|
|
void WindowsFileDialog::exec()
|
|
{
|
|
char Filestring[MAX_PATH] = "\0";
|
|
OPENFILENAME opf={0};
|
|
opf.lStructSize = sizeof(OPENFILENAME);
|
|
opf.lpstrFile = Filestring;
|
|
opf.lpstrTitle = const_cast<char *>(_title.c_str());
|
|
opf.nMaxFile = MAX_PATH;
|
|
|
|
std::string extensions;
|
|
size_t extensionsLen;
|
|
if (!_filterPatterns.empty()) {
|
|
BOOST_FOREACH(std::string ext, _filterPatterns) {
|
|
if (!simgear::strutils::starts_with(ext, "*.")) {
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "WindowsFileDialog: can't use pattern on Windows:" << ext);
|
|
continue;
|
|
}
|
|
extensions += "("+ext+")\0"+ext+"\0";
|
|
extensionsLen += ext.size()*2+4;
|
|
}
|
|
opf.lpstrFilter = (LPCSTR) malloc(extensionsLen);
|
|
memcpy((void*)opf.lpstrFilter, (void*)extensions.data(), extensionsLen);
|
|
}
|
|
|
|
std::string s = _initialPath.local8BitStr();
|
|
opf.lpstrInitialDir = const_cast<char *>(s.c_str());
|
|
|
|
if (_showHidden) {
|
|
opf.Flags = OFN_PATHMUSTEXIST;
|
|
}
|
|
|
|
if (_usage == USE_SAVE_FILE) {
|
|
if (GetSaveFileNameA(&opf)) {
|
|
std::string stringPath(opf.lpstrFile);
|
|
_callback->onFileDialogDone(this, stringPath);
|
|
}
|
|
} else if (_usage == USE_CHOOSE_DIR) {
|
|
chooseDir();
|
|
} else {
|
|
if (GetOpenFileNameA(&opf)) {
|
|
std::string stringPath(opf.lpstrFile);
|
|
_callback->onFileDialogDone(this, stringPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WindowsFileDialog::close()
|
|
{
|
|
|
|
}
|
|
|
|
void WindowsFileDialog::chooseDir()
|
|
{
|
|
// MSDN says this needs to be called first
|
|
OleInitialize(NULL);
|
|
|
|
char pathBuf[MAX_PATH] = "\0";
|
|
|
|
BROWSEINFO binfo;
|
|
memset(&binfo, 0, sizeof(BROWSEINFO));
|
|
binfo.hwndOwner = getMainViewerHWND();
|
|
binfo.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_EDITBOX;
|
|
|
|
binfo.pidlRoot = NULL; // can browse anywhere
|
|
binfo.lpszTitle = const_cast<char *>(_title.c_str());
|
|
binfo.lpfn = BrowseFolderCallback;
|
|
binfo.lParam = reinterpret_cast<LPARAM>(this);
|
|
|
|
PIDLIST_ABSOLUTE results = SHBrowseForFolder(&binfo);
|
|
if (results == NULL) {
|
|
// user cancelled
|
|
return;
|
|
}
|
|
|
|
SHGetPathFromIDList(results, pathBuf);
|
|
CoTaskMemFree(results);
|
|
|
|
_callback->onFileDialogDone(this, SGPath(pathBuf));
|
|
} |