diff --git a/src/Notepad3.c b/src/Notepad3.c index ce51d3ad6..5c4d5d6d1 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -1532,7 +1532,7 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow) Globals.hwndMain = NULL; HWND const hwndMain = CreateWindowEx( - 0, + WS_EX_ACCEPTFILES, s_wchWndClass, _W(SAPPNAME), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, @@ -1865,7 +1865,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) return MsgDrawItem(hwnd, wParam, lParam); case WM_DROPFILES: - // see SCN_URIDROPP + // see SCN_URIDROPPED return MsgDropFiles(hwnd, wParam, lParam); case WM_COPYDATA: @@ -3264,13 +3264,13 @@ LRESULT MsgDropFiles(HWND hwnd, WPARAM wParam, LPARAM lParam) HPATHL hdrop_pth = Path_Allocate(NULL); wchar_t* const drop_buf = Path_WriteAccessBuf(hdrop_pth, STRINGW_MAX_URL_LENGTH); - UINT const cnt = DragQueryFile(hDrop, UINT_MAX, NULL, 0); + UINT const cnt = DragQueryFileW(hDrop, UINT_MAX, NULL, 0); int const offset = Settings2.LaunchInstanceWndPosOffset; for (UINT i = 0; i < cnt; ++i) { WININFO wi = GetMyWindowPlacement(hwnd, NULL, (vkCtrlDown ? (offset * (i + 1)) : 0)); - DragQueryFile(hDrop, i, drop_buf, (UINT)Path_GetBufCount(hdrop_pth)); + DragQueryFileW(hDrop, i, drop_buf, (UINT)Path_GetBufCount(hdrop_pth)); _OnDropOneFile(hwnd, hdrop_pth, (((0 == i) && !IsKeyDown(VK_CONTROL)) ? NULL : &wi)); } @@ -8272,16 +8272,6 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn) break; - case SCN_URIDROPPED: { - HPATHL hfile_pth = Path_Allocate(NULL); - wchar_t* const file_buf = Path_WriteAccessBuf(hfile_pth, STRINGW_MAX_URL_LENGTH); - int const cnt = MultiByteToWideChar(CP_UTF8, 0, scn->text, -1, file_buf, (int)Path_GetBufCount(hfile_pth)); - LRESULT const result = (cnt > 0) ? _OnDropOneFile(hwnd, hfile_pth, NULL) : FALSE; - Path_Release(hfile_pth); - return result; - } - - default: return FALSE; } @@ -10474,6 +10464,7 @@ bool FileLoad(const HPATHL hfile_pth, bool bDontSave, bool bNew, bool bReload, } else { Path_Reset(hopen_file, Path_Get(hfile_pth)); } + Path_NormalizeEx(hopen_file, Paths.WorkingDirectory, true, Flags.bSearchPathIfRelative); // change current directory to prevent directory lock on another path @@ -10966,12 +10957,13 @@ bool FileSave(bool bSaveAlways, bool bAsk, bool bSaveAs, bool bSaveCopy, bool bP if (bSaveCopy && Path_IsNotEmpty(_hpthLastSaveCopyDir)) { Path_Reset(hdir_pth, Path_Get(_hpthLastSaveCopyDir)); - Path_Reset(hfile_pth, Path_Get(_hpthLastSaveCopyDir)); - Path_Append(hfile_pth, Path_FindFileName(Paths.CurrentFile)); } else { - Path_Reset(hfile_pth, Path_Get(Paths.CurrentFile)); + Path_Reset(hdir_pth, Path_Get(Paths.CurrentFile)); + Path_RemoveFileSpec(hdir_pth); } + Path_Reset(hfile_pth, Path_FindFileName(Paths.CurrentFile)); + bool const ok = SaveFileDlg(Globals.hwndMain, hfile_pth, Path_IsNotEmpty(hdir_pth) ? hdir_pth : NULL); if (ok) { if (!bSaveCopy) { @@ -11131,8 +11123,6 @@ static void _CanonicalizeInitialDir(HPATHL hpth_in_out) // bool OpenFileDlg(HWND hwnd, HPATHL hfile_pth_io, const HPATHL hinidir_pth) { - UNREFERENCED_PARAMETER(hwnd); - if (!hfile_pth_io) { return false; } @@ -11144,35 +11134,21 @@ bool OpenFileDlg(HWND hwnd, HPATHL hfile_pth_io, const HPATHL hinidir_pth) HPATHL hpth_dir = Path_Allocate(Path_Get(hinidir_pth)); _CanonicalizeInitialDir(hpth_dir); - wchar_t* file_buf = Path_WriteAccessBuf(hfile_pth_io, PATHLONG_MAX_CCH); - -#if 1 OPENFILENAME ofn = { sizeof(OPENFILENAME) }; ofn.hwndOwner = hwnd; ofn.hInstance = Globals.hInstance; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = NULL; // no preserved (static member) user-defined patten ofn.lpstrInitialDir = Path_IsNotEmpty(hpth_dir) ? Path_Get(hpth_dir) : NULL; - ofn.lpstrFile = file_buf; + ofn.lpstrFile = Path_WriteAccessBuf(hfile_pth_io, PATHLONG_MAX_CCH); ofn.nMaxFile = (DWORD)Path_GetBufCount(hfile_pth_io); - ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | /* OFN_NOCHANGEDIR |*/ + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | /* OFN_NOCHANGEDIR |*/ OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST | OFN_SHAREAWARE /*| OFN_NODEREFERENCELINKS*/; ofn.lpstrDefExt = StrIsNotEmpty(szDefExt) ? szDefExt : Settings2.DefaultExtension; bool const res = GetOpenFileNameW(&ofn); -#else - bool res = false; - PIDLIST_ABSOLUTE pidl; - if (SUCCEEDED(SHParseDisplayName(file_buf, 0, &pidl, 0, 0))) { - ITEMIDLIST idNull = { 0 }; - LPCITEMIDLIST pidlNull[1] = { &idNull }; - res = SUCCEEDED(SHOpenFolderAndSelectItems(pidl, 1, pidlNull, 0)); - ILFree(pidl); - } -#endif - Path_Sanitize(hfile_pth_io); Path_Release(hpth_dir); @@ -11198,25 +11174,24 @@ bool SaveFileDlg(HWND hwnd, HPATHL hfile_pth_io, const HPATHL hinidir_pth) WCHAR szFilter[EXTENTIONS_FILTER_BUFFER]; Style_GetFileFilterStr(szFilter, COUNTOF(szFilter), szDefExt, COUNTOF(szDefExt), true); - HPATHL hpth_dir = Path_Allocate(Path_Get(hinidir_pth)); + HPATHL hpth_dir = Path_Copy(hinidir_pth); _CanonicalizeInitialDir(hpth_dir); - wchar_t* file_buf = Path_WriteAccessBuf(hfile_pth_io, PATHLONG_MAX_CCH); - OPENFILENAME ofn = { sizeof(OPENFILENAME) }; ofn.hwndOwner = hwnd; ofn.hInstance = Globals.hInstance; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = NULL; // no preserved (static member) user-defined patten ofn.lpstrInitialDir = Path_IsNotEmpty(hpth_dir) ? Path_Get(hpth_dir) : NULL; - ofn.lpstrFile = file_buf; + ofn.lpstrFile = Path_WriteAccessBuf(hfile_pth_io, PATHLONG_MAX_CCH); ofn.nMaxFile = (DWORD)Path_GetBufCount(hfile_pth_io); - ofn.Flags = OFN_HIDEREADONLY /*| OFN_NOCHANGEDIR*/ | + ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | /*| OFN_NOCHANGEDIR*/ /*OFN_NODEREFERENCELINKS |*/ OFN_OVERWRITEPROMPT | OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST; ofn.lpstrDefExt = StrIsNotEmpty(szDefExt) ? szDefExt : Settings2.DefaultExtension; bool const res = GetSaveFileNameW(&ofn); + Path_Sanitize(hfile_pth_io); Path_Release(hpth_dir); diff --git a/src/PathLib.c b/src/PathLib.c index e515f20ff..926ba7cba 100644 --- a/src/PathLib.c +++ b/src/PathLib.c @@ -146,6 +146,7 @@ #include #include +#include "Dialogs.h" #include "PathLib.h" @@ -324,9 +325,19 @@ static void PrependLongPathPrefix(HPATHL hpth_in_out, bool bForce) } } } - // ---------------------------------------------------------------------------- +static LPCWSTR _Path_SkipLPPrefix(const HSTRINGW hpth_str) +{ + LPCWSTR start = StrgGet(hpth_str); + if (wcsstr(start, PATHLONG_PREFIX) == start) { + start += wcslen(PATHLONG_PREFIX); + } + return start; +} +// ---------------------------------------------------------------------------- + + static void _UnExpandEnvStrgs(HSTRINGW hstr_in_out) { if (!hstr_in_out) { @@ -381,6 +392,8 @@ static bool _PathCanonicalize(HSTRINGW hstr_in_out) return false; } + LPCWSTR start = _Path_SkipLPPrefix(hstr_in_out); + LPWSTR const path = StrgWriteAccessBuf(hstr_in_out, 0); size_t const cch = StrgGetAllocLength(hstr_in_out); @@ -388,9 +401,8 @@ static bool _PathCanonicalize(HSTRINGW hstr_in_out) _PathFixBackslashes(path); // Move back to the beginning of the string - size_t i = 0; - size_t j = 0; - size_t k = 0; + size_t i, j, k; + i = j = k = (start - path); // Parse the entire string do { @@ -538,16 +550,6 @@ static bool _PathCanonicalize(HSTRINGW hstr_in_out) // ---------------------------------------------------------- // -static LPCWSTR _Path_SkipLPPrefix(const HPATHL hpth) -{ - LPCWSTR start = PathGet(hpth); - if (wcsstr(start, PATHLONG_PREFIX) == start) { - start += wcslen(PATHLONG_PREFIX) + 1; - } - return start; -} - - static LPCWSTR _Path_IsValidUNC(const HPATHL hpth, bool* isUNC_out) { if (!hpth) { @@ -658,7 +660,7 @@ static bool _Path_IsRelative(const HPATHL hpth) if (!hstr) return true; // empty is relative - LPCWSTR const skip = _Path_SkipLPPrefix(hpth); + LPCWSTR const skip = _Path_SkipLPPrefix(hstr); bool res = false; if (StrgGetLength(hstr) >= MAX_PATH_EXPLICIT) { @@ -799,9 +801,6 @@ bool PTHAPI Path_Canonicalize(HPATHL hpth_in_out) HPATHL hpth_cpy = Path_Allocate(PathGet(hpth_in_out)); HSTRINGW hstr_cpy = ToHStrgW(hpth_cpy); - LPWSTR const buf = StrgWriteAccessBuf(hstr_cpy, 0); - if (buf) {} - //~ PathXCchCanonicalizeEx() does not convert forward slashes (/) into back slashes (\). //~StrgReplaceCh(hstr_cpy, L'/', L'\\'); //~_PathFixBackslashes(StrgGet(hstr_cpy)); @@ -1316,11 +1315,12 @@ size_t PTHAPI Path_ToShortPathName(HPATHL hpth_in_out) HSTRINGW hstr_io = ToHStrgW(hpth_in_out); if (!hstr_io) return 0; - - DWORD const _len = GetShortPathNameW(StrgGet(hstr_io), NULL, 0); - if (!_len) - return false; + DWORD const _len = GetShortPathNameW(StrgGet(hstr_io), NULL, 0); + if (!_len) { + MsgBoxLastError(L"Path_ToShortPathName()", 0); + return 0; + } LPWSTR const buf = StrgWriteAccessBuf(hstr_io, _len); DWORD const len = GetShortPathNameW(buf, buf, (DWORD)StrgGetAllocLength(hstr_io)); @@ -1339,10 +1339,13 @@ size_t PTHAPI Path_GetLongPathNameEx(HPATHL hpth_in_out) PrependLongPathPrefix(hpth_in_out, false); // TODO: check or true ? - DWORD const len = GetLongPathNameW(StrgGet(hstr_io), NULL, 0); - LPWSTR const buf = StrgWriteAccessBuf(hstr_io, len); - - size_t const res = (size_t)GetLongPathNameW(buf, buf, len); + DWORD const _len = GetLongPathNameW(StrgGet(hstr_io), NULL, 0); + if (!_len) { + MsgBoxLastError(L"Path_GetLongPathNameEx()", 0); + return 0; + } + LPWSTR const buf = StrgWriteAccessBuf(hstr_io, _len); + size_t const res = (size_t)GetLongPathNameW(buf, buf, _len); StrgSanitize(hstr_io); if (res > 2ULL) { diff --git a/src/PathLib.h b/src/PathLib.h index 845fc9518..2a06bbfa7 100644 --- a/src/PathLib.h +++ b/src/PathLib.h @@ -112,8 +112,8 @@ void PTHAPI Path_GetAppDirectory(HPATHL hpth_out); bool PTHAPI Path_IsRelative(const HPATHL hpath); bool PTHAPI Path_IsPrefix(const HPATHL hprefix, const HPATHL hpth); size_t PTHAPI Path_CommonPrefix(const HPATHL hpth1, const HPATHL hpth2, HPATHL hpfx_out); -LPCWSTR PTHAPI Path_FindFileName(const HPATHL hpth); -LPCWSTR PTHAPI Path_FindExtension(const HPATHL hpth); +LPCWSTR PTHAPI Path_FindFileName(const HPATHL hpth); +LPCWSTR PTHAPI Path_FindExtension(const HPATHL hpth); bool PTHAPI Path_QuoteSpaces(HPATHL hpth_in_out, bool bForceQuotes); void PTHAPI Path_UnQuoteSpaces(HPATHL hpth_in_out); int PTHAPI Path_GetDriveNumber(const HPATHL hpth);