#include "WindowsFileDialog.hxx" #include #include #include #include #include #include #include #include
#include
#include 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(*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(lpData); LPCTSTR path = dlg->getDirectory().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(_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); } opf.lpstrInitialDir = const_cast(_initialPath.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(_title.c_str()); binfo.lpfn = BrowseFolderCallback; binfo.lParam = reinterpret_cast(this); PIDLIST_ABSOLUTE results = SHBrowseForFolder(&binfo); if (results == NULL) { // user cancelled return; } SHGetPathFromIDList(results, pathBuf); CoTaskMemFree(results); _callback->onFileDialogDone(this, SGPath(pathBuf)); }