From 556901b83b1d71e47c861413ab7577693fdf5c9a Mon Sep 17 00:00:00 2001 From: Isaiah Norton Date: Wed, 14 Feb 2018 00:45:08 -0500 Subject: [PATCH] Make Unix style path (slashes) work in open file dialog (optional) Close #3948, fix #2438, fix #3840 --- .../OpenSaveFileDialog/FileDialog.cpp | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp b/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp index 9e823d56..a82ccc7e 100644 --- a/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp +++ b/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp @@ -31,6 +31,7 @@ #include "FileDialog.h" #include "Parameters.h" +#include FileDialog *FileDialog::staticThis = NULL; //int FileDialog::_dialogFileBoxId = (NppParameters::getInstance())->getWinVersion() < WV_W2K?edt1:cmb13; @@ -171,6 +172,12 @@ TCHAR* FileDialog::doOpenSingleFileDlg() _ofn.Flags |= OFN_FILEMUSTEXIST; + if (!params->useNewStyleSaveDlg()) + { + _ofn.Flags |= OFN_ENABLEHOOK | OFN_NOVALIDATE; + _ofn.lpfnHook = OFNHookProc; + } + TCHAR *fn = NULL; try { fn = ::GetOpenFileName(&_ofn)?_fileName:NULL; @@ -200,7 +207,13 @@ stringVector * FileDialog::doOpenMultiFilesDlg() NppParameters * params = NppParameters::getInstance(); _ofn.lpstrInitialDir = params->getWorkingDir(); - _ofn.Flags |= OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT; + _ofn.Flags |= OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_ENABLESIZING; + + if (!params->useNewStyleSaveDlg()) + { + _ofn.Flags |= OFN_ENABLEHOOK | OFN_NOVALIDATE; + _ofn.lpfnHook = OFNHookProc; + } BOOL res = ::GetOpenFileName(&_ofn); if (params->getNppGUI()._openSaveDir == dir_last) @@ -256,7 +269,7 @@ TCHAR * FileDialog::doSaveDlg() if (!params->useNewStyleSaveDlg()) { - _ofn.Flags |= OFN_ENABLEHOOK; + _ofn.Flags |= OFN_ENABLEHOOK | OFN_NOVALIDATE; _ofn.lpfnHook = OFNHookProc; } @@ -355,7 +368,6 @@ static generic_string addExt(HWND textCtrl, HWND typeCtrl) { return returnExt; }; - UINT_PTR CALLBACK FileDialog::OFNHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) @@ -374,7 +386,6 @@ UINT_PTR CALLBACK FileDialog::OFNHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, L HWND typeControl = ::GetDlgItem(hFileDlg, cmb1); ::SendMessage(typeControl, CB_SETCURSEL, index, 0); } - // Don't touch the following 3 lines, they are cursed !!! oldProc = reinterpret_cast(::GetWindowLongPtr(hFileDlg, GWLP_WNDPROC)); if (oldProc) @@ -431,6 +442,34 @@ BOOL APIENTRY FileDialog::run(HWND hWnd, UINT uMsg, WPARAM, LPARAM lParam) int index = static_cast(::SendMessage(typeControl, CB_GETCURSEL, 0, 0)); NppParameters *pNppParam = NppParameters::getInstance(); pNppParam->setFileSaveDlgFilterIndex(index); + + // change forward-slash to back-slash directory paths so dialog can interpret + OPENFILENAME* ofn = reinterpret_cast(lParam)->lpOFN; + TCHAR* fileName = ofn->lpstrFile; + + // note: this check is essential, because otherwise we could return True + // with a OFN_NOVALIDATE dialog, which leads to opening every file + // in the specified directory. Multi-select terminator is \0\0. + if ((ofn->Flags & OFN_ALLOWMULTISELECT) && + (*(fileName + lstrlen(fileName) + 1) != '\0')) + return FALSE; + + if (::PathIsDirectory(fileName)) + { + // change to backslash, and insert trailing '\' to indicate directory + hFileDlg = ::GetParent(hWnd); + std::wstring _fnStr(fileName); + std::replace(_fnStr.begin(), _fnStr.end(), '/', '\\'); + + if (_fnStr.back() != '\\') + _fnStr.insert(_fnStr.end(), '\\'); + + // change the dialog directory selection + ::SendMessage(hFileDlg, CDM_SETCONTROLTEXT, edt1, + reinterpret_cast(_fnStr.c_str())); + ::PostMessage(hFileDlg, WM_COMMAND, IDOK, 0); + ::SetWindowLongPtr(hWnd, 0 /*DWL_MSGRESULT*/, 1); + } return TRUE; }