From dd2fd09c209a9206852f7249d921ad22b95fccec Mon Sep 17 00:00:00 2001 From: rkotten Date: Tue, 28 Mar 2023 13:44:55 +0200 Subject: [PATCH 1/4] +fix: Integration and Notification of DirectoryObserver and FileChanged-Polling --- src/Config/Config.cpp | 5 +- src/Edit.c | 8 +-- src/Helpers.h | 110 ++++++++++++++++++++++-------------------- src/Notepad3.c | 95 +++++++++++++++++------------------- src/TypeDefs.h | 9 ++-- 5 files changed, 112 insertions(+), 115 deletions(-) diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index c1a6593a6..3a41dd4ea 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -1261,8 +1261,7 @@ void LoadSettings() } int const deprecatedFCI = max_i(autoReload, dfci); - Settings2.FileCheckInterval = static_cast(clampll(IniSectionGetLongLong(IniSecSettings2, correctKeyFCI, deprecatedFCI), - MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL)); + Settings2.FileCheckInterval = IniSectionGetLongLong(IniSecSettings2, correctKeyFCI, deprecatedFCI); if (Settings2.FileCheckInterval == defaultFCI) { if (deprecatedFCI != defaultFCI) { @@ -1274,7 +1273,7 @@ void LoadSettings() IniSectionSetLongLong(IniSecSettings2, correctKeyFCI, Settings2.FileCheckInterval); bDirtyFlag = true; } - FileWatching.FileCheckInterval = Settings2.FileCheckInterval; + FileWatching.FileCheckInterval = clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); IniSectionGetString(IniSecSettings2, L"FileChangedIndicator", L"[@]", Settings2.FileChangedIndicator, COUNTOF(Settings2.FileChangedIndicator)); diff --git a/src/Edit.c b/src/Edit.c index f2212e8ce..b9bd2a1b7 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -5242,7 +5242,7 @@ void EditSortLines(HWND hwnd, int iSortFlags) qsort(pLines, iLineCount, sizeof(SORTLINE), CmpStdRev); } } else { /*if (iSortFlags & SORT_SHUFFLE)*/ - srand((UINT)GetTicks()); + srand((UINT)GetTicks_ms()); for (DocLn i = (iLineCount - 1); i > 0; --i) { int j = rand() % i; SORTLINE sLine = { NULL, NULL }; @@ -9691,8 +9691,8 @@ void EditFoldClick(DocLn ln, int mode) if (!(SciCall_GetFoldLevel(ln) & SC_FOLDLEVELHEADERFLAG)) { // Not a fold point: need to look for a double-click - if (prev.ln == ln && prev.mode == mode && - GetTicks() - prev.iTickCount <= GetDoubleClickTime()) { + if ((prev.ln == ln) && (prev.mode == mode) && + ((GetTicks_ms() - prev.iTickCount) <= GetDoubleClickTime())) { prev.ln = NOT_FOUND_LN; // Prevent re-triggering on a triple-click ln = SciCall_GetFoldParent(ln); @@ -9706,7 +9706,7 @@ void EditFoldClick(DocLn ln, int mode) // Save the info needed to match this click with the next click prev.ln = ln; prev.mode = mode; - prev.iTickCount = GetTicks(); + prev.iTickCount = GetTicks_ms(); return; } } diff --git a/src/Helpers.h b/src/Helpers.h index f51c7484f..99971899b 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -63,12 +63,12 @@ #define DEFAULT_ALLOC_FLAGS (HEAP_CREATE_HARDENED) #endif -inline LPVOID AllocMem(size_t numBytes, DWORD dwFlags) +static inline LPVOID AllocMem(size_t numBytes, DWORD dwFlags) { return HeapAlloc(Globals.hndlProcessHeap, (dwFlags | DEFAULT_ALLOC_FLAGS), numBytes); } -inline LPVOID ReAllocMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) +static inline LPVOID ReAllocMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) { if (lpMem) { return HeapReAlloc(Globals.hndlProcessHeap, (dwFlags | DEFAULT_ALLOC_FLAGS), lpMem, numBytes); @@ -76,7 +76,7 @@ inline LPVOID ReAllocMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) return HeapAlloc(Globals.hndlProcessHeap, (dwFlags | DEFAULT_ALLOC_FLAGS), numBytes); } -inline LPVOID ReAllocGrowMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) +static inline LPVOID ReAllocGrowMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) { if (lpMem) { size_t const memSize = HeapSize(Globals.hndlProcessHeap, 0, lpMem); @@ -91,12 +91,12 @@ inline LPVOID ReAllocGrowMem(LPVOID lpMem, size_t numBytes, DWORD dwFlags) return HeapAlloc(Globals.hndlProcessHeap, (dwFlags | DEFAULT_ALLOC_FLAGS), numBytes); } -inline bool FreeMem(LPVOID lpMem) +static inline bool FreeMem(LPVOID lpMem) { return (lpMem ? HeapFree(Globals.hndlProcessHeap, 0, lpMem) : true); } -inline size_t SizeOfMem(LPCVOID lpMem) +static inline size_t SizeOfMem(LPCVOID lpMem) { return (lpMem ? HeapSize(Globals.hndlProcessHeap, 0, lpMem) : 0); } @@ -207,7 +207,7 @@ __forceinline bool IsAsyncKeyDown(int key) { // ---------------------------------------------------------------------------- -inline DWORD GetNumberOfProcessors() +static inline DWORD GetNumberOfProcessors() { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); @@ -216,13 +216,14 @@ inline DWORD GetNumberOfProcessors() // ---------------------------------------------------------------------------- -inline bool Str2Int(LPCWSTR str, int *value) { +__forceinline bool Str2Int(LPCWSTR str, int* value) +{ LPWSTR end; *value = (int)wcstol(str, &end, 10); return (str != end); } -inline bool Str2Float(LPCWSTR str, float* value) +__forceinline bool Str2Float(LPCWSTR str, float* value) { LPWSTR end; *value = (float)wcstod(str, &end); @@ -298,7 +299,7 @@ __forceinline bool StrIsEmptyW(LPCWSTR s) { //inline COLORREF GetBackgroundColor(HWND hwnd) { return GetBkColor(GetDC(hwnd)); } -inline int SetModeBkColor(const HDC hdc, const bool bDarkMode) +static inline int SetModeBkColor(const HDC hdc, const bool bDarkMode) { #ifdef D_NP3_WIN10_DARK_MODE return SetBkColor(hdc, bDarkMode ? Settings2.DarkModeBkgColor : GetSysColor(COLOR_WINDOW)); @@ -308,7 +309,7 @@ inline int SetModeBkColor(const HDC hdc, const bool bDarkMode) #endif } -inline int SetModeBtnFaceColor(const HDC hdc, const bool bDarkMode) +static inline int SetModeBtnFaceColor(const HDC hdc, const bool bDarkMode) { #ifdef D_NP3_WIN10_DARK_MODE return SetBkColor(hdc, bDarkMode ? Settings2.DarkModeBtnFaceColor : GetSysColor(COLOR_BTNFACE)); @@ -318,7 +319,7 @@ inline int SetModeBtnFaceColor(const HDC hdc, const bool bDarkMode) #endif } -inline COLORREF GetModeBkColor(const bool bDarkMode) +static inline COLORREF GetModeBkColor(const bool bDarkMode) { #ifdef D_NP3_WIN10_DARK_MODE return bDarkMode ? Settings2.DarkModeBkgColor : (COLORREF)GetSysColor(COLOR_WINDOW); @@ -328,7 +329,7 @@ inline COLORREF GetModeBkColor(const bool bDarkMode) #endif } -inline COLORREF GetModeBtnfaceColor(const bool bDarkMode) +static inline COLORREF GetModeBtnfaceColor(const bool bDarkMode) { #ifdef D_NP3_WIN10_DARK_MODE return bDarkMode ? Settings2.DarkModeBtnFaceColor : (COLORREF)GetSysColor(COLOR_BTNFACE); @@ -339,7 +340,7 @@ inline COLORREF GetModeBtnfaceColor(const bool bDarkMode) } -inline int SetModeTextColor(const HDC hdc, const bool bDarkMode) +static inline int SetModeTextColor(const HDC hdc, const bool bDarkMode) { #ifdef D_NP3_WIN10_DARK_MODE //return SetTextColor(hdc, bDarkMode ? Settings2.DarkModeTxtColor : GetSysColor(COLOR_WINDOWTEXT)); @@ -350,7 +351,7 @@ inline int SetModeTextColor(const HDC hdc, const bool bDarkMode) #endif } -inline COLORREF GetModeTextColor(const bool bDarkMode) +static inline COLORREF GetModeTextColor(const bool bDarkMode) { #ifdef D_NP3_WIN10_DARK_MODE //return bDarkMode ? Settings2.DarkModeTxtColor : (COLORREF)GetSysColor(COLOR_WINDOWTEXT); @@ -364,7 +365,7 @@ inline COLORREF GetModeTextColor(const bool bDarkMode) #ifdef D_NP3_WIN10_DARK_MODE -inline INT_PTR SetDarkModeCtlColors(const HDC hdc, const bool bDarkMode) +static inline INT_PTR SetDarkModeCtlColors(const HDC hdc, const bool bDarkMode) { if (bDarkMode) { SetBkColor(hdc, Settings2.DarkModeBkgColor); @@ -390,7 +391,7 @@ bool SetClipboardText(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW); // ---------------------------------------------------------------------------- -inline void GetCurrentMonitorResolution(HWND hwnd, int* pCXScreen, int* pCYScreen) +static inline void GetCurrentMonitorResolution(HWND hwnd, int* pCXScreen, int* pCYScreen) { HMONITOR const hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); MONITORINFO mi = { sizeof(MONITORINFO) }; @@ -400,7 +401,7 @@ inline void GetCurrentMonitorResolution(HWND hwnd, int* pCXScreen, int* pCYScree } // FullHD? => 0:'==', -1:'<', +1:'>' -inline int IsFullHD(HWND hwnd, int resX, int resY) +static inline int IsFullHD(HWND hwnd, int resX, int resY) { int cxScreen, cyScreen; GetCurrentMonitorResolution(hwnd, &cxScreen, &cyScreen); @@ -427,10 +428,10 @@ void BackgroundWorker_Start(BackgroundWorker* worker, _beginthreadex_proc void BackgroundWorker_Cancel(BackgroundWorker* worker); void BackgroundWorker_Destroy(BackgroundWorker* worker); -inline bool BackgroundWorker_Continue(BackgroundWorker* worker) { +static inline bool BackgroundWorker_Continue(BackgroundWorker* worker) { return (worker) ? (WaitForSingleObject(worker->eventCancel, 0) != WAIT_OBJECT_0) : false; } -inline void BackgroundWorker_End(BackgroundWorker* worker, unsigned int retcode) { if (worker) { _endthreadex(retcode); }} +static inline void BackgroundWorker_End(BackgroundWorker* worker, unsigned int retcode) { if (worker) { _endthreadex(retcode); }} bool BitmapMergeAlpha(HBITMAP hbmp,COLORREF crDest); @@ -445,15 +446,15 @@ bool IsCmdEnabled(HWND hwnd, UINT uId); #define SetBtn(b) ((b) ? BST_CHECKED : BST_UNCHECKED) -inline bool IsButtonChecked(HWND hwnd, int iButtonID) +__forceinline bool IsButtonChecked(HWND hwnd, int iButtonID) { return (IsDlgButtonChecked(hwnd, iButtonID) == BST_CHECKED); } -inline bool IsButtonIntermediate(HWND hwnd, int iButtonID) +__forceinline bool IsButtonIntermediate(HWND hwnd, int iButtonID) { return (IsDlgButtonChecked(hwnd, iButtonID) == BST_INDETERMINATE); } -inline bool IsButtonUnchecked(HWND hwnd, int iButtonID) +__forceinline bool IsButtonUnchecked(HWND hwnd, int iButtonID) { return (IsDlgButtonChecked(hwnd, iButtonID) == BST_UNCHECKED); } @@ -478,7 +479,7 @@ bool SplitFilePathLineNum(LPWSTR lpszPath, int *lineNum); bool StrLTrimI(LPWSTR pszSource,LPCWSTR pszTrimChars); bool StrRTrimI(LPWSTR pszSource,LPCWSTR pszTrimChars); -inline bool TrimSpcA(LPSTR lpString) +static inline bool TrimSpcA(LPSTR lpString) { if (!lpString || !*lpString) { return false; @@ -486,7 +487,7 @@ inline bool TrimSpcA(LPSTR lpString) return (bool)StrTrimA(lpString, " \t\v"); }; -inline bool TrimSpcW(LPWSTR lpString) +static inline bool TrimSpcW(LPWSTR lpString) { if (!lpString || !*lpString) { return false; @@ -577,29 +578,29 @@ __forceinline ptrdiff_t MultiByteToWideCharEx( // ============================================================================ -inline int wcscmp_s(const wchar_t* s1, const wchar_t* s2) +__forceinline int wcscmp_s(const wchar_t* s1, const wchar_t* s2) { return (s1 && s2) ? wcscmp(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); } -inline int wcscoll_s(const wchar_t* s1, const wchar_t* s2) +__forceinline int wcscoll_s(const wchar_t* s1, const wchar_t* s2) { return (s1 && s2) ? wcscoll(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); } -inline int wcsicmp_s(const wchar_t* s1, const wchar_t* s2) +__forceinline int wcsicmp_s(const wchar_t* s1, const wchar_t* s2) { return (s1 && s2) ? _wcsicmp(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); } -inline int wcsicoll_s(const wchar_t* s1, const wchar_t* s2) +__forceinline int wcsicoll_s(const wchar_t* s1, const wchar_t* s2) { return (s1 && s2) ? _wcsicoll(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); } // ============================================================================ -inline void SwabEx(char* src, char* dest, size_t n) +static inline void SwabEx(char* src, char* dest, size_t n) { static int const max = (INT_MAX - (INT_MAX % 2)); @@ -658,7 +659,7 @@ bool StrDelChrA(LPSTR pszSource, LPCSTR pCharsToRemove); // inline size_t StringCchLenW(LPCWSTR s, size_t n) { // n = (n ? n : STRSAFE_MAX_CCH); size_t len; return (size_t)(!s ? 0 : (SUCCEEDED(StringCchLengthW(s, n, &len)) ? len : n)); // } -inline size_t StringCchLenW(LPCWSTR s, size_t n) +static inline size_t StringCchLenW(LPCWSTR s, size_t n) { n = (n ? n : STRSAFE_MAX_CCH); return (s ? wcsnlen_s(s, n) : 0LL); @@ -666,7 +667,7 @@ inline size_t StringCchLenW(LPCWSTR s, size_t n) // inline size_t StringCchLenA(LPCSTR s, size_t n) { // n = (n ? n : STRSAFE_MAX_CCH); size_t len; return (size_t)(!s ? 0 : (SUCCEEDED(StringCchLengthA(s, n, &len)) ? len : n)); // } -inline size_t StringCchLenA(LPCSTR s, size_t n) +static inline size_t StringCchLenA(LPCSTR s, size_t n) { n = (n ? n : STRSAFE_MAX_CCH); return (s ? strnlen_s(s, n) : 0LL); @@ -679,12 +680,12 @@ inline size_t StringCchLenA(LPCSTR s, size_t n) // ---------------------------------------------------------------------------- -inline WCHAR* StrEndW(const WCHAR* pStart, size_t siz) +static inline WCHAR* StrEndW(const WCHAR* pStart, size_t siz) { // cppcheck-suppress cert-EXP05-C // Attempt to cast away const - Intended(!) return (WCHAR*)(pStart + StringCchLenW(pStart, siz)); } -inline char* StrEndA(const char* pStart, size_t siz) +static inline char* StrEndA(const char* pStart, size_t siz) { // cppcheck-suppress cert-EXP05-C // Attempt to cast away const - Intended(!) return (char*)(pStart + StringCchLenA(pStart, siz)); @@ -697,7 +698,7 @@ inline char* StrEndA(const char* pStart, size_t siz) // ---------------------------------------------------------------------------- -inline void StrReplChrW(WCHAR* pStrg, const WCHAR chSearch, const WCHAR chReplace) +static inline void StrReplChrW(WCHAR* pStrg, const WCHAR chSearch, const WCHAR chReplace) { while (pStrg && *pStrg) { if (*pStrg == chSearch) { @@ -706,7 +707,7 @@ inline void StrReplChrW(WCHAR* pStrg, const WCHAR chSearch, const WCHAR chReplac ++pStrg; } } -inline void StrReplChrA(CHAR* pStrg, const CHAR chSearch, const CHAR chReplace) +static inline void StrReplChrA(CHAR* pStrg, const CHAR chSearch, const CHAR chReplace) { while (pStrg && *pStrg) { if (*pStrg == chSearch) { @@ -781,29 +782,35 @@ inline void StrReplChrA(CHAR* pStrg, const CHAR chSearch, const CHAR chReplace) #define IsOctalDigitW(wch) (((wch) >= L'0') && ((wch) <= L'7')) // Is the character an octal digit? -inline bool IsDigitA(const char ch) { +__forceinline bool IsDigitA(const char ch) +{ return ((ch >= '0') && (ch <= '9')); } -inline bool IsDigitW(const WCHAR wch) { +__forceinline bool IsDigitW(const WCHAR wch) +{ return ((wch >= L'0') && (wch <= L'9')); } // Is the character a white space char? -inline bool IsBlankCharA(const char ch) { +__forceinline bool IsBlankCharA(const char ch) +{ return ((ch == ' ') || (ch == '\t')); } -inline bool IsBlankCharW(const WCHAR wch) { +__forceinline bool IsBlankCharW(const WCHAR wch) +{ return ((wch == L' ') || (wch == L'\t')); } // no encoding for safe chars -inline bool IsAlphaNumericA(const char ch) { +__forceinline bool IsAlphaNumericA(const char ch) +{ return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')); } -inline bool IsAlphaNumericW(const WCHAR ch) { +__forceinline bool IsAlphaNumericW(const WCHAR ch) +{ return ((ch >= L'0') && (ch <= L'9')) || ((ch >= L'a') && (ch <= L'z')) || @@ -811,7 +818,7 @@ inline bool IsAlphaNumericW(const WCHAR ch) { } // If the character is an hexadecimal digit, get its value. -inline int GetHexDigitA(const char ch) +static inline int GetHexDigitA(const char ch) { if (ch >= '0' && ch <= '9') { return ch - '0'; @@ -825,7 +832,7 @@ inline int GetHexDigitA(const char ch) return -1; } -inline int GetHexDigitW(const WCHAR ch) +static inline int GetHexDigitW(const WCHAR ch) { if (ch >= L'0' && ch <= L'9') { return ch - L'0'; @@ -855,24 +862,23 @@ void CloseApplication(); // ---------------------------------------------------------------------------- -inline int PointSizeToFontHeight(const float fPtHeight, const HDC hdc) { +static inline int PointSizeToFontHeight(const float fPtHeight, const HDC hdc) { return -MulDiv(f2int(fPtHeight * 100.0f), GetDeviceCaps(hdc, LOGPIXELSY), 72 * SC_FONT_SIZE_MULTIPLIER); } // ---------------------------------------------------------------------------- -static inline int64_t GetTicks() { - LARGE_INTEGER ticks; - if (!QueryPerformanceCounter(&ticks)) { - return (int64_t)GetTickCount64(); - } + +static inline int64_t GetTicks_ms() { LARGE_INTEGER freq; if (!QueryPerformanceFrequency(&freq)) { return (int64_t)GetTickCount64(); } - ticks.QuadPart *= 1000000; - ticks.QuadPart /= freq.QuadPart; - return ticks.QuadPart; + LARGE_INTEGER ticks; + if (!QueryPerformanceCounter(&ticks)) { + return (int64_t)GetTickCount64(); + } + return (ticks.QuadPart * 1000LL) / freq.QuadPart; } // ---------------------------------------------------------------------------- diff --git a/src/Notepad3.c b/src/Notepad3.c index 07ad52d0c..b61462693 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -622,7 +622,7 @@ static inline bool IsFileDeletedFlagSet() { return (WaitForSingleObject(s_FileChgObsvrData.hEventFileDeleted, 0) != WAIT_TIMEOUT); } -static inline bool HasCurrentFileChanged() { +static inline bool RaiseFlagIfCurrentFileChanged() { if (Path_IsEmpty(Paths.CurrentFile)) { return false; @@ -1521,7 +1521,7 @@ static BOOL CALLBACK _EnumWndProc(HWND hwnd, LPARAM lParam) if (StringCchCompareNIW(szClassName, COUNTOF(szClassName), s_wchWndClass, COUNTOF(s_wchWndClass)) == 0) { UINT const iReuseLock = GetDlgItemInt(hwnd, IDC_REUSELOCK, NULL, FALSE); - if ((GetTicks() - iReuseLock) >= REUSEWINDOWLOCKTIMEOUT) { + if ((GetTicks_ms() - iReuseLock) >= REUSEWINDOWLOCKTIMEOUT) { *(HWND*)lParam = hwnd; @@ -1549,7 +1549,7 @@ static BOOL CALLBACK _EnumWndProc2(HWND hwnd, LPARAM lParam) if (StringCchCompareNIW(szClassName, COUNTOF(szClassName), s_wchWndClass, COUNTOF(s_wchWndClass)) == 0) { UINT const iReuseLock = GetDlgItemInt(hwnd, IDC_REUSELOCK, NULL, FALSE); - if ((GetTicks() - iReuseLock) >= REUSEWINDOWLOCKTIMEOUT) { + if ((GetTicks_ms() - iReuseLock) >= REUSEWINDOWLOCKTIMEOUT) { if (IsWindowEnabled(hwnd)) { bContinue = FALSE; @@ -1835,11 +1835,26 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) // Source Encoding Encoding_Forced(s_flagSetEncoding); + switch (s_flagChangeNotify) { + case FWM_NO_INIT: + FileWatching.FileWatchingMode = Settings.FileWatchingMode; + break; + case FWM_DONT_CARE: + case FWM_INDICATORSILENT: + case FWM_MSGBOX: + case FWM_AUTORELOAD: + case FWM_EXCLUSIVELOCK: + FileWatching.FileWatchingMode = s_flagChangeNotify; + break; + default: + FileWatching.FileWatchingMode = FWM_MSGBOX; + break; + } + // Initial FileLoad() moved in front of ShowWindow() bool bOpened = false; // Pathname parameter - if (s_IsThisAnElevatedRelaunch || (Path_IsNotEmpty(s_pthArgFilePath) /*&& !g_flagNewFromClipboard*/)) { fLoadFlags |= Settings.SkipUnicodeDetection ? FLF_SkipUnicodeDetect : 0; @@ -1890,26 +1905,6 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) Path_Empty(s_pthArgFilePath, false); - if (bOpened) { - switch (s_flagChangeNotify) { - case FWM_NO_INIT: - FileWatching.FileWatchingMode = Settings.FileWatchingMode; - break; - case FWM_DONT_CARE: - case FWM_INDICATORSILENT: - case FWM_MSGBOX: - case FWM_AUTORELOAD: - case FWM_EXCLUSIVELOCK: - FileWatching.FileWatchingMode = s_flagChangeNotify; - break; - default: - FileWatching.FileWatchingMode = FWM_MSGBOX; - break; - } - if (!s_IsThisAnElevatedRelaunch) { - InstallFileWatching(true); - } - } } else { cpi_enc_t const forcedEncoding = Encoding_Forced(CPI_GET); if (Encoding_IsValid(forcedEncoding)) { @@ -2204,7 +2199,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case WM_DRAWCLIPBOARD: if (!s_bLastCopyFromMe) { - s_iLastCopyTime = GetTicks(); + s_iLastCopyTime = GetTicks_ms(); } else { s_bLastCopyFromMe = false; } @@ -2758,7 +2753,7 @@ LRESULT MsgCreate(HWND hwnd, WPARAM wParam,LPARAM lParam) hInstance, NULL); - SetDlgItemInt(hwnd,IDC_REUSELOCK,(UINT)GetTicks(),false); + SetDlgItemInt(hwnd,IDC_REUSELOCK,(UINT)GetTicks_ms(),false); // Menu //~SetMenuDefaultItem(GetSubMenu(GetMenu(hwnd),0),0); @@ -3678,7 +3673,7 @@ LRESULT MsgCopyData(HWND hwnd, WPARAM wParam, LPARAM lParam) // Reset Change Notify //bPendingChangeNotify = false; - SetDlgItemInt(hwnd, IDC_REUSELOCK, (UINT)GetTicks(), false); + SetDlgItemInt(hwnd, IDC_REUSELOCK, (UINT)GetTicks_ms(), false); if (pcds->dwData == DATA_NOTEPAD3_PARAMS) { LPnp3params const params = AllocMem(pcds->cbData, HEAP_ZERO_MEMORY); @@ -3931,7 +3926,7 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) SET_FCT_GUARD(TRUE); - InstallFileWatching(false); // terminate + ResetFileObservationData(true); DocPos const iCurPos = SciCall_GetCurrentPos(); @@ -3963,6 +3958,8 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) } else { // file has been deleted + InstallFileWatching(false); // terminate + if (FileWatching.FileWatchingMode == FWM_MSGBOX) { if (IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY2))) { FileSave(FSF_SaveAlways); @@ -3976,8 +3973,6 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) } - InstallFileWatching(true); - RESET_FCT_GUARD(); return TRUE; } @@ -6281,11 +6276,11 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) SendWMCommand(hwnd, IDM_FILE_REVERT); _saveChgNotify = FileWatching.FileWatchingMode; FileWatching.FileWatchingMode = FWM_AUTORELOAD; - FileWatching.FileCheckInterval = 250LL; + FileWatching.FileCheckInterval = MIN_FC_POLL_INTERVAL << 2; SciCall_SetEndAtLastLine(false); } else { FileWatching.FileWatchingMode = _saveChgNotify; - FileWatching.FileCheckInterval = Settings2.FileCheckInterval; + FileWatching.FileCheckInterval = clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); SciCall_SetEndAtLastLine(!Settings.ScrollPastEOF); } Sci_ScrollSelectionToView(); @@ -11298,7 +11293,7 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) Path_Empty(Paths.CurrentFile, false); SetDlgItemText(Globals.hwndMain, IDC_FILENAME, Path_Get(Paths.CurrentFile)); - SetDlgItemInt(Globals.hwndMain, IDC_REUSELOCK, (UINT)GetTicks(), false); + SetDlgItemInt(Globals.hwndMain, IDC_REUSELOCK, (UINT)GetTicks_ms(), false); if (!s_flagKeepTitleExcerpt) { StringCchCopy(s_wchTitleExcerpt, COUNTOF(s_wchTitleExcerpt), L""); } @@ -11448,7 +11443,7 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) Path_Reset(Paths.CurrentFile, Path_Get(hopen_file)); // dup SetDlgItemText(Globals.hwndMain, IDC_FILENAME, Path_Get(Paths.CurrentFile)); - SetDlgItemInt(Globals.hwndMain, IDC_REUSELOCK, (UINT)GetTicks(), false); + SetDlgItemInt(Globals.hwndMain, IDC_REUSELOCK, (UINT)GetTicks_ms(), false); if (!s_flagKeepTitleExcerpt) { StringCchCopy(s_wchTitleExcerpt, COUNTOF(s_wchTitleExcerpt), L""); @@ -11898,7 +11893,7 @@ bool FileSave(FileSaveFlags fSaveFlags) if (!(fSaveFlags & FSF_SaveCopy)) { Path_Swap(Paths.CurrentFile, hfile_pth); SetDlgItemText(Globals.hwndMain, IDC_FILENAME, Path_Get(Paths.CurrentFile)); - SetDlgItemInt(Globals.hwndMain, IDC_REUSELOCK, (UINT)GetTicks(), false); + SetDlgItemInt(Globals.hwndMain, IDC_REUSELOCK, (UINT)GetTicks_ms(), false); if (!s_flagKeepTitleExcerpt) { StringCchCopy(s_wchTitleExcerpt, COUNTOF(s_wchTitleExcerpt), L""); } @@ -12532,7 +12527,7 @@ void CALLBACK PasteBoardTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD UNREFERENCED_PARAMETER(idEvent); UNREFERENCED_PARAMETER(dwTime); - if ((s_iLastCopyTime > 0) && ((GetTicks() - s_iLastCopyTime) > 200)) { + if ((s_iLastCopyTime > 0) && ((GetTicks_ms() - s_iLastCopyTime) > 200)) { if (SciCall_CanPaste()) { bool bAutoIndent2 = Settings.AutoIndent; @@ -12561,13 +12556,13 @@ void CALLBACK PasteBoardTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD //============================================================================= -static inline void NotifyIfFileHasChanged(const bool forcedNotify) { +static inline void NotifyIfFileHasChanged() { - if (forcedNotify || HasCurrentFileChanged()) { + if (IsFileChangedFlagSet() || IsFileDeletedFlagSet() || RaiseFlagIfCurrentFileChanged()) { PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0); } // reset Timeout interval - s_FileChgObsvrData.iFileChangeNotifyTime = GetTicks(); + s_FileChgObsvrData.iFileChangeNotifyTime = GetTicks_ms(); } // ---------------------------------------------------------------------------- @@ -12580,10 +12575,10 @@ static void CALLBACK WatchTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR UNREFERENCED_PARAMETER(uMsg); UNREFERENCED_PARAMETER(hwnd); - int64_t const diff = GetTicks() - s_FileChgObsvrData.iFileChangeNotifyTime; + int64_t const diff = (GetTicks_ms() - s_FileChgObsvrData.iFileChangeNotifyTime); // Directory-Observer is not notified for continuously updated (log-)files - if (diff > Settings2.FileCheckInterval) { - NotifyIfFileHasChanged(/*FileWatching.MonitoringLog*/ false); + if (diff > FileWatching.FileCheckInterval) { + NotifyIfFileHasChanged(); } } // ---------------------------------------------------------------------------- @@ -12615,11 +12610,11 @@ unsigned int WINAPI FileChangeObserver(LPVOID lpParam) break; case WAIT_OBJECT_0: - if (pFCOBSVData->bNotifyImmediate) { - NotifyIfFileHasChanged(/*(!)*/false); // immediate notification - } else { - s_FileChgObsvrData.iFileChangeNotifyTime = GetTicks(); - WatchTimerProc(NULL, 0, 0ULL, 0); // rely on FileCheckInterval + // check if current file is trigger for directory notification + if (RaiseFlagIfCurrentFileChanged()) { + if (FileWatching.FileCheckInterval <= MIN_FC_POLL_INTERVAL) { + NotifyIfFileHasChanged(); // immediate notification + } } FindNextChangeNotification(pFCOBSVData->hFileChanged); break; @@ -12661,8 +12656,6 @@ void InstallFileWatching(const bool bInstall) { bool const bExclusiveLock = (FileWatching.FileWatchingMode == FWM_EXCLUSIVELOCK); bool const bWatchFile = (FileWatching.FileWatchingMode != FWM_DONT_CARE) && !bExclusiveLock; - s_FileChgObsvrData.bNotifyImmediate = (FileWatching.FileCheckInterval <= MIN_FC_POLL_INTERVAL); - // always release exclusive file lock in any case if (IS_VALID_HANDLE(_hCurrFileHandle)) { CloseHandle(_hCurrFileHandle); @@ -12696,9 +12689,9 @@ void InstallFileWatching(const bool bInstall) { BackgroundWorker_Start(&(s_FileChgObsvrData.worker), FileChangeObserver, &s_FileChgObsvrData); } - s_FileChgObsvrData.iFileChangeNotifyTime = (FileWatching.FileWatchingMode == FWM_AUTORELOAD) ? GetTicks() : 0; + s_FileChgObsvrData.iFileChangeNotifyTime = GetTicks_ms(); - if (FileWatching.FileCheckInterval > 0) { + if (Settings2.FileCheckInterval > 0) { SetTimer(Globals.hwndMain, ID_WATCHTIMER, (UINT)FileWatching.FileCheckInterval, WatchTimerProc); } else { diff --git a/src/TypeDefs.h b/src/TypeDefs.h index 55d8d61a0..d87e5ee86 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -852,15 +852,14 @@ typedef struct FCOBSRVDATA_T { HANDLE hEventFileDeleted; HANDLE hFileChanged; // FindFirstChangeNotification() - bool bNotifyImmediate; BackgroundWorker worker; } FCOBSRVDATA_T, *PFCOBSRVDATA_T; -#define INIT_FCOBSRV_T { 0UL, { 0 }, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, false, { NULL, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, NULL } } +#define INIT_FCOBSRV_T { 0LL, { 0 }, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, { NULL, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, NULL } } -#define MIN_FC_POLL_INTERVAL (500UL) -#define MAX_FC_POLL_INTERVAL ((24UL * 60 * 60 * 1000) << 1) // max: 48h +#define MIN_FC_POLL_INTERVAL (500LL) +#define MAX_FC_POLL_INTERVAL ((24LL * 60 * 60 * 1000) << 1) // max: 48h //============================================================================= @@ -868,7 +867,7 @@ typedef struct FILEWATCHING_T { FILE_WATCHING_MODE flagChangeNotify; // <-> s_flagChangeNotify; FILE_WATCHING_MODE FileWatchingMode; // <-> Settings.FileWatchingMode; - int64_t FileCheckInterval; // <-> Settings2.FileCheckInterval; + int64_t FileCheckInterval; // <-> clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); bool MonitoringLog; } FILEWATCHING_T, *PFILEWATCHING_T; From e04709659683ca87bf32aa8d469cfd9c150d32f6 Mon Sep 17 00:00:00 2001 From: rkotten Date: Tue, 28 Mar 2023 18:50:02 +0200 Subject: [PATCH 2/4] +enh: Enhanced File-Change Notification Messagebox --- language/common_res.h | 18 +++--- language/np3_de_de/dialogs_de_de.rc | 68 +++++++++++++++++++++- language/np3_de_de/strings_de_de.rc | 2 +- language/np3_en_us/dialogs_en_us.rc | 74 ++++++++++++++++++++++-- language/np3_en_us/strings_en_us.rc | 2 +- src/Dialogs.c | 51 +++++++++++++++- src/Dialogs.h | 5 +- src/Notepad3.c | 90 ++++++++++++++++++++++------- src/Styles.c | 5 ++ 9 files changed, 271 insertions(+), 44 deletions(-) diff --git a/language/common_res.h b/language/common_res.h index df0f9785e..cb7115530 100644 --- a/language/common_res.h +++ b/language/common_res.h @@ -317,14 +317,16 @@ #define IDD_MUI_INFOBOX3 17029 #define IDD_MUI_INFOBOX4 17030 #define IDD_MUI_INFOBOX5 17031 -#define IDD_MUI_SORT 17032 -#define IDD_MUI_RECODE 17033 -#define IDD_MUI_ENCODING 17034 -#define IDD_MUI_ALIGN 17035 -#define IDD_MUI_CMDLINEHELP 17037 -#define IDD_MUI_SYSFONT_WITHLINK 17038 -#define IDD_MUI_SYSCOLOR_DLG 17039 -#define IDD_MUI_AUTOSAVE_BACKUP 17040 +#define IDD_MUI_INFOBOX6 17032 +#define IDD_MUI_INFOBOX7 17033 +#define IDD_MUI_SORT 17034 +#define IDD_MUI_RECODE 17035 +#define IDD_MUI_ENCODING 17036 +#define IDD_MUI_ALIGN 17037 +#define IDD_MUI_CMDLINEHELP 17038 +#define IDD_MUI_SYSFONT_WITHLINK 17039 +#define IDD_MUI_SYSCOLOR_DLG 17040 +#define IDD_MUI_AUTOSAVE_BACKUP 17041 #define IDC_COMMANDLINE 18000 #define IDC_SEARCHEXE 18001 diff --git a/language/np3_de_de/dialogs_de_de.rc b/language/np3_de_de/dialogs_de_de.rc index 8ebea69f7..fcda92435 100644 --- a/language/np3_de_de/dialogs_de_de.rc +++ b/language/np3_de_de/dialogs_de_de.rc @@ -276,7 +276,7 @@ CAPTION "Nachricht bei Dateiänderung" FONT 9, "Segoe UI", 400, 0, 0x1 BEGIN CONTROL "&Keine.", IDC_RADIO_BTN_A,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,7,99,10 - CONTROL "&Indikator (lautlos).", IDC_RADIO_BTN_B, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 7, 19, 99, 10 + CONTROL "&Indikator (still).", IDC_RADIO_BTN_B, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 7, 19, 99, 10 CONTROL "&Zeige Nachricht.", IDC_RADIO_BTN_C,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,31,99,10 CONTROL "&Auto-Neuladen.", IDC_RADIO_BTN_D,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,43,99,10 CONTROL "&Exklusive Sperrung der Datei.", IDC_RADIO_BTN_E,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,55,120,10 @@ -615,7 +615,7 @@ BEGIN PUSHBUTTON "&Nein",IDNO,61,70,50,14 PUSHBUTTON "&Abbrechen",IDCANCEL,115,70,50,14 CONTROL "&Diese Nachricht nicht nochmals anzeigen.",IDC_INFOBOXCHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,54,122,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,54,140,10 END IDD_MUI_INFOBOX5 DIALOGEX 0, 0, 244, 71 @@ -626,12 +626,42 @@ BEGIN //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT LTEXT "",IDC_INFOBOXTEXT,35,7,202,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT - DEFPUSHBUTTON "Wiederholen",IDRETRY,131,50,50,14 + DEFPUSHBUTTON "&Wiederholen",IDRETRY,131,50,50,14 PUSHBUTTON "&Abbrechen",IDCANCEL,187,50,50,14 CONTROL "&Diese Nachricht nicht nochmals anzeigen.",IDC_INFOBOXCHECK, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,54,122,10 END +IDD_MUI_INFOBOX6 DIALOGEX 0, 0, 299, 91 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Notepad3" +FONT 9, "Segoe UI", 400, 0, 0x1 +BEGIN + //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 + CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT + LTEXT "",IDC_INFOBOXTEXT,35,7,202,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT + CONTROL "&Diese Nachricht nicht nochmals anzeigen.",IDC_INFOBOXCHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,54,140,10 + DEFPUSHBUTTON "&Wiederholen",IDRETRY,186,70,50,14 + PUSHBUTTON "&Abbrechen",IDABORT,130,70, 50, 14 + PUSHBUTTON "&Ignorieren",IDIGNORE,242,70,50,14 +END + +IDD_MUI_INFOBOX7 DIALOGEX 0, 0, 299, 91 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Notepad3" +FONT 9, "Segoe UI", 400, 0, 0x1 +BEGIN + //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 + CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT + LTEXT "",IDC_INFOBOXTEXT,35,7,202,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT + CONTROL "&Diese Nachricht nicht nochmals anzeigen.",IDC_INFOBOXCHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,54,140,10 + DEFPUSHBUTTON "&Wiederholen", IDRETRY, 186, 70, 50, 14 + PUSHBUTTON "&Abbrechen",IDCANCEL,130,70, 50, 14 + PUSHBUTTON "&Weiter",IDCONTINUE,242,70,50,14 +END + IDD_MUI_SORT DIALOGEX 0, 0, 185, 188 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Sortiere Zeilen" @@ -1072,6 +1102,38 @@ BEGIN BOTTOMMARGIN, 64 END + IDD_MUI_INFOBOX4, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 181 + TOPMARGIN, 7 + BOTTOMMARGIN, 84 + END + + IDD_MUI_INFOBOX5, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 251 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + + IDD_MUI_INFOBOX6, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 306 + TOPMARGIN, 7 + BOTTOMMARGIN, 84 + END + + IDD_MUI_INFOBOX7, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 306 + TOPMARGIN, 7 + BOTTOMMARGIN, 84 + END + IDD_MUI_SORT, DIALOG BEGIN LEFTMARGIN, 7 diff --git a/language/np3_de_de/strings_de_de.rc b/language/np3_de_de/strings_de_de.rc index 543c718c0..3f89c9a65 100644 --- a/language/np3_de_de/strings_de_de.rc +++ b/language/np3_de_de/strings_de_de.rc @@ -177,7 +177,7 @@ BEGIN IDS_MUI_ASK_CLEAR_UNDO "Diese Operation wird die Undo-History löschen. Weiter machen?" IDS_MUI_READONLY_SAVE """%s"" ist schreibgeschützt. Dokument unter einem anderen Dateipfad speichern?" IDS_MUI_FILECHANGENOTIFY - "Die geladene Datei wurde durch ein anderes Programm auf dem Datenträger verändert. Neu laden?" + "Die geladene Datei wurde durch ein anderes Programm auf dem Datenträger verändert.\n[Abbrechen]: \tIgnoriere alle Änderungen (Stiller Indikator).\n[Wiederholen]:\tDatei neu laden.\n[Weiter]: \tWechsle ins Logfile Monitoring." IDS_MUI_FILECHANGENOTIFY2 "Die geladene Datei wurde auf dem Datenträger gelöscht. Nochmals speichern?" IDS_MUI_FILELOCK_ERROR "Es konnte keine exklusive Dateisperre auf ""%s"" gesetzt werden!" IDS_MUI_STICKYWINPOS "Eingefrorene Fensterpositionierung is eingeschaltet worden. Jede neue Notepad3 Instanz wird nun diese Fensterpositionierung initial verwenden." diff --git a/language/np3_en_us/dialogs_en_us.rc b/language/np3_en_us/dialogs_en_us.rc index db5911015..c6b190efa 100644 --- a/language/np3_en_us/dialogs_en_us.rc +++ b/language/np3_en_us/dialogs_en_us.rc @@ -611,11 +611,11 @@ BEGIN //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT LTEXT "",IDC_INFOBOXTEXT,35,7,126,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT + CONTROL "&Don't display this message again.",IDC_INFOBOXCHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,54,122,10 DEFPUSHBUTTON "&Yes",IDOK,7,70,50,14 PUSHBUTTON "&No",IDNO,61,70,50,14 PUSHBUTTON "&Cancel",IDCANCEL,115,70,50,14 - CONTROL "&Don't display this message again.",IDC_INFOBOXCHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,54,122,10 END IDD_MUI_INFOBOX5 DIALOGEX 0, 0, 244, 71 @@ -626,12 +626,42 @@ BEGIN //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT LTEXT "",IDC_INFOBOXTEXT,35,7,202,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT - DEFPUSHBUTTON "Retry",IDRETRY,131,50,50,14 + DEFPUSHBUTTON "&Retry",IDRETRY,131,50,50,14 PUSHBUTTON "&Cancel",IDCANCEL,187,50,50,14 CONTROL "&Don't display this message again.",IDC_INFOBOXCHECK, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,54,122,10 END +IDD_MUI_INFOBOX6 DIALOGEX 0, 0, 299, 91 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Notepad3" +FONT 9, "Segoe UI", 400, 0, 0x1 +BEGIN + //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 + CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT + LTEXT "",IDC_INFOBOXTEXT,35,7,202,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT + CONTROL "&Don't display this message again.",IDC_INFOBOXCHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,54,122,10 + DEFPUSHBUTTON "&Retry",IDRETRY,186,70,50,14 + PUSHBUTTON "&Abort",IDABORT, 130, 70, 50, 14 + PUSHBUTTON "&Ignore",IDIGNORE,242,70,50,14 +END + +IDD_MUI_INFOBOX7 DIALOGEX 0, 0, 299, 91 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Notepad3" +FONT 9, "Segoe UI", 400, 0, 0x1 +BEGIN + //~ICON IDR_MAINWND,IDC_INFOBOXICON,7,7,0,0 + CONTROL IDR_MAINWND, IDC_INFOBOXICON, "Static", SS_BITMAP | SS_NOTIFY, 7, 7, 24, 24, WS_EX_TRANSPARENT + LTEXT "",IDC_INFOBOXTEXT,35,7,202,41,SS_EDITCONTROL | SS_NOPREFIX | SS_LEFT + CONTROL "&Don't display this message again.",IDC_INFOBOXCHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,54,122,10 + DEFPUSHBUTTON "&Try Again",IDRETRY,186,70,50,14 + PUSHBUTTON "&Cancel", IDCANCEL, 130, 70, 50, 14 + PUSHBUTTON "&Continue",IDCONTINUE,242,70,50,14 +END + IDD_MUI_SORT DIALOGEX 0, 0, 185, 188 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Sort Lines" @@ -1051,7 +1081,7 @@ BEGIN IDD_MUI_INFOBOX, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 237 + RIGHTMARGIN, 251 TOPMARGIN, 7 BOTTOMMARGIN, 64 END @@ -1059,7 +1089,7 @@ BEGIN IDD_MUI_INFOBOX2, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 237 + RIGHTMARGIN, 251 TOPMARGIN, 7 BOTTOMMARGIN, 64 END @@ -1067,11 +1097,43 @@ BEGIN IDD_MUI_INFOBOX3, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 237 + RIGHTMARGIN, 251 TOPMARGIN, 7 BOTTOMMARGIN, 64 END + IDD_MUI_INFOBOX4, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 181 + TOPMARGIN, 7 + BOTTOMMARGIN, 84 + END + + IDD_MUI_INFOBOX5, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 251 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + + IDD_MUI_INFOBOX6, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 306 + TOPMARGIN, 7 + BOTTOMMARGIN, 84 + END + + IDD_MUI_INFOBOX7, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 306 + TOPMARGIN, 7 + BOTTOMMARGIN, 84 + END + IDD_MUI_SORT, DIALOG BEGIN LEFTMARGIN, 7 diff --git a/language/np3_en_us/strings_en_us.rc b/language/np3_en_us/strings_en_us.rc index fc27ddfa6..c0c8c76ef 100644 --- a/language/np3_en_us/strings_en_us.rc +++ b/language/np3_en_us/strings_en_us.rc @@ -177,7 +177,7 @@ BEGIN IDS_MUI_ASK_CLEAR_UNDO "This operation will clear the undo history. Continue?" IDS_MUI_READONLY_SAVE """%s"" is read only. Save to a different file?" IDS_MUI_FILECHANGENOTIFY - "The current file has been modified by an external program. Reload?" + "The current file has been modified by an external program.\n[Cancel]: \tIgnore any changes (silent indicator).\n[Try Again]:\tReload File.\n[Continue]: \tSwitch to File Monitoring." IDS_MUI_FILECHANGENOTIFY2 "The current file has been deleted. Save now?" IDS_MUI_FILELOCK_ERROR "Can not acquire exclusive file lock for ""%s""!" IDS_MUI_STICKYWINPOS "Sticky Window Position is enabled. Any new Notepad3 windows will use the current window placement settings." diff --git a/src/Dialogs.c b/src/Dialogs.c index 879968bea..a300df980 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -311,6 +311,10 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, return TRUE; + case WM_CLOSE: + EndDialog(hwnd, LOWORD(IDCLOSE)); + break; + case WM_DESTROY: if (hIconBmp) { DeleteObject(hIconBmp); @@ -374,6 +378,8 @@ CASE_WM_CTLCOLOR_SET: bool const isChecked = IsButtonChecked(hwnd, IDC_INFOBOXCHECK); DialogEnableControl(hwnd, IDNO, !isChecked); DialogEnableControl(hwnd, IDABORT, !isChecked); + DialogEnableControl(hwnd, IDIGNORE, !isChecked); + DialogEnableControl(hwnd, IDCONTINUE, !isChecked); DialogEnableControl(hwnd, IDCLOSE, !isChecked); DialogEnableControl(hwnd, IDCANCEL, !isChecked); SendMessage(hwnd, WM_NEXTDLGCTL, 0, FALSE); @@ -488,7 +494,11 @@ LONG InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...) int idDlg; switch (uType & MB_TYPEMASK) { - case MB_YESNO: // contains two push buttons : Yes and No. + case MB_OK: // one push button : OK. This is the default. + idDlg = IDD_MUI_INFOBOX; + break; + + case MB_YESNO: // contains two push buttons : Yes and No. idDlg = IDD_MUI_INFOBOX2; break; @@ -505,9 +515,13 @@ LONG InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...) break; case MB_ABORTRETRYIGNORE: // three push buttons : Abort, Retry, and Ignore. - case MB_CANCELTRYCONTINUE: // three push buttons : Cancel, Try Again, Continue.Use this message box type instead of MB_ABORTRETRYIGNORE. + idDlg = IDD_MUI_INFOBOX6; + break; + // Use this message box type instead of MB_ABORTRETRYIGNORE. + case MB_CANCELTRYCONTINUE: // three push buttons : Cancel, Try Again, Continue. + idDlg = IDD_MUI_INFOBOX7; + break; - case MB_OK: // one push button : OK. This is the default. default: idDlg = IDD_MUI_INFOBOX; break; @@ -1040,6 +1054,10 @@ INT_PTR CALLBACK AboutDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam } break; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + case WM_DESTROY: if (hVersionFont) { DeleteObject(hVersionFont); @@ -1329,6 +1347,10 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM l return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + case WM_DESTROY: DeleteBitmapButton(hwnd, IDC_SEARCHEXE); return FALSE; @@ -1582,6 +1604,10 @@ static INT_PTR CALLBACK OpenWithDlgProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + case WM_DESTROY: DirList_Destroy(hwndLV); hwndLV = NULL; @@ -1838,6 +1864,11 @@ static INT_PTR CALLBACK FavoritesDlgProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARA return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + + case WM_DESTROY: DirList_Destroy(hwndLV); hwndLV = NULL; @@ -2046,6 +2077,11 @@ static INT_PTR CALLBACK AddToFavDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPA return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + + case WM_DESTROY: ResizeDlg_Destroy(hwnd, &Settings.AddToFavDlgSizeX, NULL); return FALSE; @@ -2316,6 +2352,10 @@ static INT_PTR CALLBACK FileMRUDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPAR } return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + case WM_DESTROY: { BackgroundWorker *worker = (BackgroundWorker *)GetProp(hwnd, L"it"); BackgroundWorker_Destroy(worker); @@ -3628,6 +3668,11 @@ static INT_PTR CALLBACK SelectEncodingDlgProc(HWND hwnd,UINT umsg,WPARAM wParam, return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + + case WM_DESTROY: { ImageList_Destroy(himl); himl = NULL; diff --git a/src/Dialogs.h b/src/Dialogs.h index fb081c777..91274eae3 100644 --- a/src/Dialogs.h +++ b/src/Dialogs.h @@ -83,14 +83,15 @@ DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID); LONG InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...); #define INFOBOX_ANSW(_R_) LOWORD(_R_) #define INFOBOX_MODE(_R_) HIWORD(_R_) + inline bool IsYesOkay(INT_PTR answ) { return ((LOWORD(answ) == IDOK) || (LOWORD(answ) == IDYES)); } inline bool IsRetryContinue(INT_PTR answ) { return ((LOWORD(answ) == IDRETRY) || (LOWORD(answ) == IDCONTINUE)); } -inline bool IsNoCancel(INT_PTR answ) { - return ((LOWORD(answ) == IDNO) || (LOWORD(answ) == IDCANCEL)); +inline bool IsNoCancelClose(INT_PTR answ) { + return ((LOWORD(answ) == IDNO) || (LOWORD(answ) == IDCANCEL) || (LOWORD(answ) == 0)); } void SetWindowTitle(HWND hwnd, const HPATHL pthFilePath, int iFormat, diff --git a/src/Notepad3.c b/src/Notepad3.c index b61462693..22feccb5b 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -3926,27 +3926,70 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) SET_FCT_GUARD(TRUE); - ResetFileObservationData(true); - DocPos const iCurPos = SciCall_GetCurrentPos(); - if ((FileWatching.FileWatchingMode == FWM_MSGBOX) || IsSaveNeeded()) { - SetForegroundWindow(hwnd); - } - if (Path_IsExistingFile(Paths.CurrentFile)) { - bool bRevertFile = ((FileWatching.FileWatchingMode == FWM_AUTORELOAD) && !IsSaveNeeded()); + bool bRevertFile = IsSaveNeeded(); + + switch (FileWatching.FileWatchingMode) + { + case FWM_AUTORELOAD: + bRevertFile = true; + break; - if (!bRevertFile) { - if (FileWatching.FileWatchingMode == FWM_MSGBOX) { - bRevertFile = IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY)); - } else { - // FWM_INDICATORSILENT: nothing todo here + case FWM_MSGBOX: + { + SetForegroundWindow(hwnd); + /// LONG const answer = MessageBoxExW(Globals.hwndMain, L"File change, Cancel, Retry, Continue", L"NP3", MB_ABORTRETRYIGNORE, GetLangIdByLocaleName(Globals.CurrentLngLocaleName)); + LONG const answer = InfoBoxLng(MB_CANCELTRYCONTINUE | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY); + switch (LOWORD(answer)) { + case IDCANCEL: + case IDABORT: + FileWatching.FileWatchingMode = FWM_INDICATORSILENT; + UpdateToolbar(); + bRevertFile = false; + ResetFileObservationData(true); + break; + + case IDIGNORE: + case IDCONTINUE: + UndoRedoReset(); + FileRevert(Paths.CurrentFile, false); + SciCall_SetReadOnly(true); + FileWatching.MonitoringLog = false; // will be reset in IDM_VIEW_CHASING_DOCTAIL + PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); + bRevertFile = false; // done already + break; + + case IDTRYAGAIN: + case IDCLOSE: + default: + bRevertFile = true; + ResetFileObservationData(true); + break; + } } + break; + + case FWM_DONT_CARE: + case FWM_EXCLUSIVELOCK: + ResetFileObservationData(true); + break; + + case FWM_INDICATORSILENT: + bRevertFile = false; + UpdateToolbar(); + break; + + case FWM_NO_INIT: + default: + assert("Invalid FileWatching Mode!" && 0); + break; } if (bRevertFile) { + SetForegroundWindow(hwnd); FileRevert(Paths.CurrentFile, false); if (FileWatching.MonitoringLog) { SciCall_SetReadOnly(FileWatching.MonitoringLog); @@ -4652,15 +4695,17 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_FILE_REVERT: - if (IsSaveNeeded()) { - if (!IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONQUESTION, NULL, IDS_MUI_ASK_REVERT))) { - break; + if (!FileWatching.MonitoringLog) { + if (IsSaveNeeded()) { + if (!IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONQUESTION, NULL, IDS_MUI_ASK_REVERT))) { + break; + } + //~ don't revert if no save needed + //~FileRevert(Paths.CurrentFile, false); } - //~ don't revert if no save needed - //~FileRevert(Paths.CurrentFile, false); + // revert in any case (manually forced) + FileRevert(Paths.CurrentFile, true); } - // revert in any case (manually forced) - FileRevert(Paths.CurrentFile, true); break; @@ -6263,6 +6308,9 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) break; case IDM_VIEW_CHASING_DOCTAIL: { + + InstallFileWatching(false); + static FILE_WATCHING_MODE _saveChgNotify = FWM_NO_INIT; if (_saveChgNotify == FWM_NO_INIT) { _saveChgNotify = FileWatching.FileWatchingMode; @@ -8643,7 +8691,9 @@ inline static LRESULT _MsgNotifyLean(const SCNotification *const scn, bool* bMod EditToggleView(Globals.hwndEdit); } else { - if (!IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONINFORMATION, L"QuietKeepReadonlyLock", IDS_MUI_DOCUMENT_READONLY))) { + if (!FileWatching.MonitoringLog + && !IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONINFORMATION, L"QuietKeepReadonlyLock", IDS_MUI_DOCUMENT_READONLY))) + { SendWMCommand(Globals.hwndMain, IDM_VIEW_READONLY); } else { diff --git a/src/Styles.c b/src/Styles.c index 9262d308f..7acaa2db0 100644 --- a/src/Styles.c +++ b/src/Styles.c @@ -5173,6 +5173,11 @@ INT_PTR CALLBACK Style_SelectLexerDlgProc(HWND hwnd,UINT umsg,WPARAM wParam,LPAR return TRUE; + case WM_CLOSE: + EndDialog(hwnd, IDCLOSE); + break; + + case WM_DESTROY: return TRUE; From ed5334ad0c7e4acf9632a6b900ede8604d236ffe Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Wed, 29 Mar 2023 09:08:32 +0200 Subject: [PATCH 3/4] +fix: issue "file changed on disk" for silent mode on closing --- src/Notepad3.c | 231 +++++++++++++++++++++++++------------------------ 1 file changed, 118 insertions(+), 113 deletions(-) diff --git a/src/Notepad3.c b/src/Notepad3.c index 22feccb5b..22e9b52bc 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -3915,112 +3915,6 @@ LRESULT MsgContextMenu(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) return (imenu != MNU_NONE) ? !0 : 0; } -//============================================================================= -// -// MsgFileChangeNotify() - Handles WM_FILECHANGEDNOTIFY -// -LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - SET_FCT_GUARD(TRUE); - - DocPos const iCurPos = SciCall_GetCurrentPos(); - - if (Path_IsExistingFile(Paths.CurrentFile)) { - - bool bRevertFile = IsSaveNeeded(); - - switch (FileWatching.FileWatchingMode) - { - case FWM_AUTORELOAD: - bRevertFile = true; - break; - - case FWM_MSGBOX: - { - SetForegroundWindow(hwnd); - /// LONG const answer = MessageBoxExW(Globals.hwndMain, L"File change, Cancel, Retry, Continue", L"NP3", MB_ABORTRETRYIGNORE, GetLangIdByLocaleName(Globals.CurrentLngLocaleName)); - LONG const answer = InfoBoxLng(MB_CANCELTRYCONTINUE | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY); - switch (LOWORD(answer)) { - case IDCANCEL: - case IDABORT: - FileWatching.FileWatchingMode = FWM_INDICATORSILENT; - UpdateToolbar(); - bRevertFile = false; - ResetFileObservationData(true); - break; - - case IDIGNORE: - case IDCONTINUE: - UndoRedoReset(); - FileRevert(Paths.CurrentFile, false); - SciCall_SetReadOnly(true); - FileWatching.MonitoringLog = false; // will be reset in IDM_VIEW_CHASING_DOCTAIL - PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); - bRevertFile = false; // done already - break; - - case IDTRYAGAIN: - case IDCLOSE: - default: - bRevertFile = true; - ResetFileObservationData(true); - break; - } - } - break; - - case FWM_DONT_CARE: - case FWM_EXCLUSIVELOCK: - ResetFileObservationData(true); - break; - - case FWM_INDICATORSILENT: - bRevertFile = false; - UpdateToolbar(); - break; - - case FWM_NO_INIT: - default: - assert("Invalid FileWatching Mode!" && 0); - break; - } - - if (bRevertFile) { - SetForegroundWindow(hwnd); - FileRevert(Paths.CurrentFile, false); - if (FileWatching.MonitoringLog) { - SciCall_SetReadOnly(FileWatching.MonitoringLog); - } else { - Sci_GotoPosChooseCaret(iCurPos); - } - Sci_ScrollSelectionToView(); - } - - } else { // file has been deleted - - InstallFileWatching(false); // terminate - - if (FileWatching.FileWatchingMode == FWM_MSGBOX) { - if (IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY2))) { - FileSave(FSF_SaveAlways); - } else { - SetSaveNeeded(true); - } - } else { - // FWM_INDICATORSILENT: nothing todo here - SetSaveNeeded(true); - } - - } - - RESET_FCT_GUARD(); - return TRUE; -} - - //============================================================================= // // MsgTrayMessage() - Handles WM_TRAYMESSAGE @@ -11861,15 +11755,21 @@ bool FileSave(FileSaveFlags fSaveFlags) bool const bIsEmptyNewFile = (Path_IsEmpty(Paths.CurrentFile) && (SciCall_GetTextLength() <= 0LL)); #endif + bool const bSaveAs = (fSaveFlags & FSF_SaveAs); + bool const bSaveAsk = (fSaveFlags & FSF_Ask); + bool const bSaveCopy = (fSaveFlags & FSF_SaveCopy); + bool const bSaveAlways = (fSaveFlags & FSF_SaveAlways); + bool const bSaveNeeded = (IsSaveNeeded() || IsFileChangedFlagSet()) && !bIsEmptyNewFile; - if (!(fSaveFlags & FSF_SaveAlways) && (!IsSaveNeeded() || IsFileChangedFlagSet() || bIsEmptyNewFile) && !(fSaveFlags & FSF_SaveAs)) { + + if (!bSaveAs && !bSaveAlways && !bSaveNeeded) { _MRU_UpdateSession(); AutoSaveStop(); ResetFileObservationData(true); return true; } - if (fSaveFlags & FSF_Ask) { + if (bSaveAsk) { // File or "Untitled" ... WCHAR wchFileName[MAX_PATH_EXPLICIT>>1] = { L'\0' }; @@ -11894,7 +11794,7 @@ bool FileSave(FileSaveFlags fSaveFlags) } // Read only... - if (!(fSaveFlags & FSF_SaveAs) && !(fSaveFlags & FSF_SaveCopy) && Path_IsNotEmpty(Paths.CurrentFile)) { + if (!bSaveAs && !bSaveCopy && Path_IsNotEmpty(Paths.CurrentFile)) { if (IsFileReadOnly()) { UpdateToolbar(); INT_PTR const answer = (Settings.MuteMessageBeep) ? @@ -11909,7 +11809,7 @@ bool FileSave(FileSaveFlags fSaveFlags) } // Save As... - if ((fSaveFlags & FSF_SaveAs) || (fSaveFlags & FSF_SaveCopy) || Path_IsEmpty(Paths.CurrentFile)) { + if (bSaveAs || bSaveCopy || Path_IsEmpty(Paths.CurrentFile)) { static HPATHL _hpthLastSaveCopyDir = NULL; // session remember copyTo dir if (!_hpthLastSaveCopyDir) { @@ -11967,7 +11867,7 @@ bool FileSave(FileSaveFlags fSaveFlags) if (fSuccess) { - if (!((fSaveFlags & FSF_SaveCopy) || Flags.bDoRelaunchElevated)) { + if (!bSaveCopy && !Flags.bDoRelaunchElevated) { _MRU_AddSession(); AddFilePathToRecentDocs(Paths.CurrentFile); // Install watching of the current file @@ -12598,6 +12498,111 @@ void CALLBACK PasteBoardTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD } +//============================================================================= +// +// MsgFileChangeNotify() - Handles WM_FILECHANGEDNOTIFY +// +LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + SET_FCT_GUARD(TRUE); + + DocPos const iCurPos = SciCall_GetCurrentPos(); + + if (Path_IsExistingFile(Paths.CurrentFile)) { + + bool bRevertFile = IsSaveNeeded(); + + switch (FileWatching.FileWatchingMode) { + case FWM_AUTORELOAD: + bRevertFile = true; + break; + + case FWM_MSGBOX: { + SetForegroundWindow(hwnd); + /// LONG const answer = MessageBoxExW(Globals.hwndMain, L"File change, Cancel, Retry, Continue", L"NP3", MB_ABORTRETRYIGNORE, GetLangIdByLocaleName(Globals.CurrentLngLocaleName)); + LONG const answer = InfoBoxLng(MB_CANCELTRYCONTINUE | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY); + switch (LOWORD(answer)) { + case IDCANCEL: + case IDABORT: + FileWatching.FileWatchingMode = FWM_INDICATORSILENT; + SetSaveNeeded(true); + bRevertFile = false; + ResetFileObservationData(false); // false (!) + UpdateToolbar(); + break; + + case IDIGNORE: + case IDCONTINUE: + UndoRedoReset(); + FileRevert(Paths.CurrentFile, false); + SciCall_SetReadOnly(true); + FileWatching.MonitoringLog = false; // will be reset in IDM_VIEW_CHASING_DOCTAIL + PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); + bRevertFile = false; // done already + break; + + case IDTRYAGAIN: + case IDCLOSE: + default: + bRevertFile = true; + ResetFileObservationData(true); + break; + } + } break; + + case FWM_DONT_CARE: + case FWM_EXCLUSIVELOCK: + ResetFileObservationData(true); + break; + + case FWM_INDICATORSILENT: + bRevertFile = false; + UpdateToolbar(); + break; + + case FWM_NO_INIT: + default: + assert("Invalid FileWatching Mode!" && 0); + break; + } + + if (bRevertFile) { + SetForegroundWindow(hwnd); + FileRevert(Paths.CurrentFile, false); + if (FileWatching.MonitoringLog) { + SciCall_SetReadOnly(FileWatching.MonitoringLog); + } + else { + Sci_GotoPosChooseCaret(iCurPos); + } + Sci_ScrollSelectionToView(); + } + } + else { // file has been deleted + + InstallFileWatching(false); // terminate + + if (FileWatching.FileWatchingMode == FWM_MSGBOX) { + if (IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY2))) { + FileSave(FSF_SaveAlways); + } + else { + SetSaveNeeded(true); + } + } + else { + // FWM_INDICATORSILENT: nothing todo here + SetSaveNeeded(true); + } + } + + RESET_FCT_GUARD(); + return TRUE; +} + //============================================================================= // @@ -12605,8 +12610,8 @@ void CALLBACK PasteBoardTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD // //============================================================================= - -static inline void NotifyIfFileHasChanged() { +static inline void NotifyIfFileHasChanged() +{ if (IsFileChangedFlagSet() || IsFileDeletedFlagSet() || RaiseFlagIfCurrentFileChanged()) { PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0); From 890312272433a87491842b057d8bea3047efde08 Mon Sep 17 00:00:00 2001 From: rkotten Date: Thu, 30 Mar 2023 18:19:48 +0200 Subject: [PATCH 4/4] +fix: some more issues around "File Change Monitoring" --- lexilla/Lexilla.vcxproj | 4 +- scintilla/Scintilla.vcxproj | 4 +- src/Config/Config.cpp | 32 ++++++------ src/DynStrg.c | 98 +++++++++++++++++-------------------- src/Edit.c | 8 +-- src/Helpers.h | 6 +-- src/Notepad3.c | 82 ++++++++++++++++--------------- src/Notepad3.h | 2 +- src/Notepad3.vcxproj | 8 +-- src/TypeDefs.h | 11 ++--- 10 files changed, 126 insertions(+), 129 deletions(-) diff --git a/lexilla/Lexilla.vcxproj b/lexilla/Lexilla.vcxproj index 67be12d06..2c59086ff 100644 --- a/lexilla/Lexilla.vcxproj +++ b/lexilla/Lexilla.vcxproj @@ -136,7 +136,7 @@ v142 v143 Unicode - true + false StaticLibrary @@ -163,7 +163,7 @@ v142 v143 Unicode - true + false StaticLibrary diff --git a/scintilla/Scintilla.vcxproj b/scintilla/Scintilla.vcxproj index 5056d1196..6a2dfb707 100644 --- a/scintilla/Scintilla.vcxproj +++ b/scintilla/Scintilla.vcxproj @@ -38,7 +38,7 @@ Unicode StaticLibrary true - true + false v141 v142 v143 @@ -50,7 +50,7 @@ v141 v142 v143 - true + false Unicode diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index 3a41dd4ea..798f94e2f 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -1244,36 +1244,38 @@ void LoadSettings() StrgReset(Settings2.FileDlgFilters, pPathBuffer); // handle deprecated (typo) key 'FileCheckInverval' - constexpr const int64_t defaultFCI = 2000; + constexpr const LONG64 NOTSETFCI = -111LL; + constexpr const LONG64 defaultFCI = 2000LL; constexpr const WCHAR* deprecatedKeyART = L"AutoReloadTimeout"; constexpr const WCHAR* deprecatedKeyFCI = L"FileCheckInverval"; constexpr const WCHAR* correctKeyFCI = L"FileCheckInterval"; - int const autoReload = IniSectionGetInt(IniSecSettings2, deprecatedKeyART, -111); // deprecated - if (autoReload != -111) { + LONG64 const autoReload = IniSectionGetLongLong(IniSecSettings2, deprecatedKeyART, NOTSETFCI); // deprecated + if (autoReload != NOTSETFCI) { IniSectionDelete(IniSecSettings2, deprecatedKeyART, true); // deprecated bDirtyFlag = true; } - int const dfci = IniSectionGetInt(IniSecSettings2, deprecatedKeyFCI, -111); // get deprecated typo setting - if (dfci != -111) { + LONG64 const dfci = IniSectionGetLongLong(IniSecSettings2, deprecatedKeyFCI, NOTSETFCI); // get deprecated typo setting + if (dfci != NOTSETFCI) { IniSectionDelete(IniSecSettings2, deprecatedKeyFCI, true); // deprecated wrong (typo) name bDirtyFlag = true; } - int const deprecatedFCI = max_i(autoReload, dfci); + LONG64 const adpDefaultFCI = (max_ll(autoReload, dfci) == NOTSETFCI) ? defaultFCI : + clampll(max_ll(autoReload, dfci), MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); - Settings2.FileCheckInterval = IniSectionGetLongLong(IniSecSettings2, correctKeyFCI, deprecatedFCI); + Settings2.FileCheckInterval = clampll(IniSectionGetLongLong(IniSecSettings2, correctKeyFCI, adpDefaultFCI), MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); if (Settings2.FileCheckInterval == defaultFCI) { - if (deprecatedFCI != defaultFCI) { - IniSectionDelete(IniSecSettings2, correctKeyFCI, true); // is default - bDirtyFlag = true; - } - } - else if (Settings2.FileCheckInterval == static_cast(deprecatedFCI)) { - IniSectionSetLongLong(IniSecSettings2, correctKeyFCI, Settings2.FileCheckInterval); + IniSectionDelete(IniSecSettings2, correctKeyFCI, true); // is default bDirtyFlag = true; } - FileWatching.FileCheckInterval = clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); + else if (Settings2.FileCheckInterval == adpDefaultFCI) { + IniSectionSetLongLong(IniSecSettings2, correctKeyFCI, adpDefaultFCI); + bDirtyFlag = true; + } + + FileWatching.FileCheckInterval = Settings2.FileCheckInterval; + IniSectionGetString(IniSecSettings2, L"FileChangedIndicator", L"[@]", Settings2.FileChangedIndicator, COUNTOF(Settings2.FileChangedIndicator)); diff --git a/src/DynStrg.c b/src/DynStrg.c index ff5ec354b..34183c4e9 100644 --- a/src/DynStrg.c +++ b/src/DynStrg.c @@ -102,23 +102,23 @@ __forceinline size_t SizeOfMemStrg(LPCVOID lpMemory) { /* */ /**************************************************/ -#define limit_len(len) (((len) < STRINGW_MAX_CCH) ? (len) : (STRINGW_MAX_CCH - 1)) +__forceinline size_t limit_len(const size_t len) { return (((len) < STRINGW_MAX_CCH) ? max_s((8 / sizeof(wchar_t)), len) : (STRINGW_MAX_CCH - 1)); } __forceinline STRINGW* ToWStrg(HSTRINGW hstr) { return (STRINGW*)hstr; } -inline static void * AllocBuffer(const size_t len, bool bZeroMem) { +inline static void * AllocBuffer(const size_t len) { if (!s_hndlProcessHeap) { s_hndlProcessHeap = GetProcessHeap(); } - return AllocMemStrg(limit_len(len) * sizeof(wchar_t), bZeroMem ? HEAP_ZERO_MEMORY : 0); + return AllocMemStrg(limit_len(len) * sizeof(wchar_t), HEAP_ZERO_MEMORY); } // ---------------------------------------------------------------------------- -inline static void * ReAllocBuffer(void* pdata, const size_t len, bool bZeroMem, bool bInPlace) { +inline static void * ReAllocBuffer(void* pdata, const size_t len, bool bInPlace) { if (!s_hndlProcessHeap) { s_hndlProcessHeap = GetProcessHeap(); } - DWORD const dwFlags = (bZeroMem ? HEAP_ZERO_MEMORY : 0) | (bInPlace ? HEAP_REALLOC_IN_PLACE_ONLY : 0); + DWORD const dwFlags = HEAP_ZERO_MEMORY | (bInPlace ? HEAP_REALLOC_IN_PLACE_ONLY : 0); return ReAllocMemStrg(pdata, limit_len(len) * sizeof(wchar_t), dwFlags); } // ---------------------------------------------------------------------------- @@ -148,18 +148,16 @@ inline static void FreeBufferW(STRINGW* pstr) { } // ---------------------------------------------------------------------------- -static void ReAllocW(STRINGW* pstr, size_t len, bool bZeroMem) +static void ReAllocW(STRINGW* pstr, size_t len) { len = limit_len(len); size_t const alloc_len = len + 1; if (!pstr->data) { - pstr->data = AllocBuffer(alloc_len, bZeroMem); + pstr->data = AllocBuffer(alloc_len); if (pstr->data) { // init pstr->alloc_length = LengthOfBuffer(pstr->data); - assert("inconsistent data" && (alloc_len != (pstr->alloc_length * sizeof(wchar_t)))); + assert("inconsistent data" && (alloc_len == pstr->alloc_length)); pstr->data_length = 0; - pstr->data[len] = WCHR_NULL; // ensure terminating zero - pstr->data[0] = WCHR_NULL; // ensure empty } else { pstr->alloc_length = 0; @@ -167,17 +165,15 @@ static void ReAllocW(STRINGW* pstr, size_t len, bool bZeroMem) } } else if (pstr->alloc_length < alloc_len) { - pstr->data = ReAllocBuffer(pstr->data, alloc_len, bZeroMem, false); + pstr->data = ReAllocBuffer(pstr->data, alloc_len, false); pstr->alloc_length = LengthOfBuffer(pstr->data); - assert("inconsistent data 1" && (alloc_len != (pstr->alloc_length * sizeof(wchar_t)))); + assert("inconsistent data 1" && (alloc_len == pstr->alloc_length)); /// original memory block is moved, so data_length is not touched assert("inconsistent data 2" && (alloc_len > pstr->data_length)); pstr->data[pstr->data_length] = WCHR_NULL; // ensure terminating zero } else { - if (bZeroMem) { - ZeroMemory(&(pstr->data[pstr->data_length]), (pstr->alloc_length - pstr->data_length) * sizeof(wchar_t)); - } + ZeroMemory(&(pstr->data[pstr->data_length]), (pstr->alloc_length - pstr->data_length) * sizeof(wchar_t)); } } // ---------------------------------------------------------------------------- @@ -187,7 +183,7 @@ static void AllocCopyW(STRINGW* pstr, STRINGW* pDest, size_t copy_len, size_t co size_t new_len = copy_len + extra_len; if (0 < new_len) { - ReAllocW(pDest, new_len, true); + ReAllocW(pDest, new_len); StringCchCopyNW(pDest->data, pDest->alloc_length, (pstr->data + copy_index), copy_len); pDest->data_length = StrlenW(pstr->data); } @@ -196,7 +192,7 @@ static void AllocCopyW(STRINGW* pstr, STRINGW* pDest, size_t copy_len, size_t co static void SetCopyW(STRINGW* pstr, size_t len, LPCWSTR p) { - ReAllocW(pstr, len, false); + ReAllocW(pstr, len); if (pstr->data) { StringCchCopyNW(pstr->data, pstr->alloc_length, p, len); pstr->data_length = StrlenW(pstr->data); @@ -210,7 +206,7 @@ static void SetCopyW(STRINGW* pstr, size_t len, LPCWSTR p) static LPWSTR CopyOldDataW(STRINGW* pstr, size_t* outLen) { size_t const old_siz = StrlenW(pstr->data) + 1; - LPWSTR const ptr = AllocBuffer(old_siz, FALSE); + LPWSTR const ptr = AllocBuffer(old_siz); if (ptr) { StringCchCopyW(ptr, old_siz, pstr->data ? pstr->data : L""); *outLen = wcslen(ptr); @@ -225,7 +221,7 @@ static void FreeUnusedData(STRINGW* pstr, size_t keep_length) { size_t const new_alloc_len = max_s(keep_length + 1, pstr->data_length + 1); if ((pstr->alloc_length > new_alloc_len) ) { - pstr->data = ReAllocBuffer(pstr->data, new_alloc_len, true, false); + pstr->data = ReAllocBuffer(pstr->data, new_alloc_len, false); pstr->alloc_length = LengthOfBuffer(pstr->data); pstr->data_length = StrlenW(pstr->data); } @@ -237,7 +233,7 @@ static void CopyConcatW(STRINGW *pstr, size_t len1, LPCWSTR p1, size_t len2, LPC { size_t const new_len = len1 + len2; if (0 < new_len) { - ReAllocW(pstr, new_len, true); + ReAllocW(pstr, new_len); StringCchCopyNW(pstr->data, pstr->alloc_length, p1, len1); StringCchCatNW(pstr->data, pstr->alloc_length, p2, len2); pstr->data_length = StrlenW(pstr->data); @@ -252,7 +248,7 @@ static void ConcatW(STRINGW* pstr, size_t len, LPCWSTR p) size_t const new_len = pstr->data_length + len; if (pstr->alloc_length <= new_len) { - ReAllocW(pstr, new_len, true); // copies old data + ReAllocW(pstr, new_len); // copies old data } StringCchCatNW(pstr->data, pstr->alloc_length, p, len); pstr->data_length = StrlenW(pstr->data); @@ -410,7 +406,7 @@ static void FormatW(STRINGW* pstr, LPCWSTR fmt, va_list args) max_len += item_len; } - ReAllocW(pstr, max_len, true); + ReAllocW(pstr, max_len); StringCchVPrintfW(pstr->data, pstr->alloc_length, fmt, orig_list); pstr->data_length = StrlenW(pstr->data); @@ -429,7 +425,7 @@ static void FormatW(STRINGW* pstr, LPCWSTR fmt, va_list args) HSTRINGW STRAPI StrgCreate(LPCWSTR str) { - STRINGW *pstr = AllocBuffer(sizeof(STRINGW), true); + STRINGW *pstr = AllocBuffer(sizeof(STRINGW)); if (!pstr) return NULL; if (str) @@ -534,7 +530,7 @@ void STRAPI StrgEmpty(const HSTRINGW hstr, bool truncate) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); return; } (pstr->data)[0] = WCHR_NULL; @@ -552,7 +548,7 @@ void STRAPI StrgSetAt(HSTRINGW hstr, const size_t index, const wchar_t ch) if (!pstr) return; if (!(pstr->data)) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } if (index >= pstr->data_length) { @@ -571,7 +567,7 @@ wchar_t STRAPI StrgGetAt(const HSTRINGW hstr, const size_t index) if (!pstr) return WCHR_NULL; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } if (index >= pstr->data_length) { @@ -632,7 +628,7 @@ size_t STRAPI StrgInsert(HSTRINGW hstr, size_t index, LPCWSTR str) if (!pstr) return STRINGW_INVALID_IDX; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } size_t const ins_len = StrlenW(str); @@ -646,7 +642,7 @@ size_t STRAPI StrgInsert(HSTRINGW hstr, size_t index, LPCWSTR str) new_len += ins_len; if (pstr->alloc_length <= new_len) { - ReAllocW(pstr, new_len, true); + ReAllocW(pstr, new_len); } wmemmove_s((pstr->data + index + ins_len), (pstr->alloc_length - index - ins_len), (pstr->data + index), (new_len - index - ins_len + 1)); @@ -664,14 +660,14 @@ size_t STRAPI StrgInsertCh(HSTRINGW hstr, size_t index, const wchar_t c) if (!pstr) return 0; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } size_t const new_len = pstr->data_length + 1; if (index >= new_len) index = new_len - 1; if (pstr->alloc_length <= new_len) { - ReAllocW(pstr, new_len, true); + ReAllocW(pstr, new_len); } wmemmove_s((pstr->data + index + 1), (pstr->alloc_length - index - 1), (pstr->data + index), (new_len - index)); @@ -689,7 +685,7 @@ size_t STRAPI StrgReplace(HSTRINGW hstr, LPCWSTR pOld, LPCWSTR pNew) if (!pstr) return 0; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } size_t const src_len = StrlenW(pOld); @@ -718,7 +714,7 @@ size_t STRAPI StrgReplace(HSTRINGW hstr, LPCWSTR pOld, LPCWSTR pNew) size_t const new_len = old_len + (repl_len - src_len) * count; if (pstr->alloc_length <= new_len) { - ReAllocW(pstr, new_len, true); + ReAllocW(pstr, new_len); } start = pstr->data; end = pstr->data + pstr->data_length; @@ -757,7 +753,7 @@ size_t STRAPI StrgReplaceCh(HSTRINGW hstr, const wchar_t chOld, const wchar_t ch if (!pstr) return 0; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } size_t count = 0; @@ -786,7 +782,7 @@ size_t STRAPI StrgRemoveCh(HSTRINGW hstr, const wchar_t chRemove) if (!pstr) return 0; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } LPWSTR source = pstr->data; @@ -819,7 +815,7 @@ size_t STRAPI StrgDelete(HSTRINGW hstr, const size_t index, size_t count) if (!pstr) return 0; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } size_t const len = pstr->data_length; @@ -849,7 +845,7 @@ int STRAPI StrgResetFromUTF8(HSTRINGW hstr, const char* str) if (!pstr || !str) return -1; int const len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0) + 1; - ReAllocW(pstr, len, true); + ReAllocW(pstr, len); int const res = MultiByteToWideChar(CP_UTF8, 0, str, -1, pstr->data, (int)pstr->alloc_length); pstr->data_length = StrlenW(pstr->data); return res; @@ -863,7 +859,7 @@ void STRAPI StrgToUpper(HSTRINGW hstr) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } if (pstr->data) _wcsupr_s(pstr->data, pstr->data_length); @@ -877,7 +873,7 @@ void STRAPI StrgToLower(HSTRINGW hstr) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } if (pstr->data) _wcslwr_s(pstr->data, pstr->data_length); @@ -891,7 +887,7 @@ void STRAPI StrgReverse(HSTRINGW hstr) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } _wcsrev(pstr->data); } @@ -904,7 +900,7 @@ void STRAPI StrgTrimRight(HSTRINGW hstr, const wchar_t wch) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } LPWSTR start = pstr->data; @@ -937,7 +933,7 @@ void STRAPI StrgTrimLeft(HSTRINGW hstr, const wchar_t wch) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } LPWSTR start = pstr->data; @@ -1026,7 +1022,7 @@ HSTRINGW STRAPI StrgMid(HSTRINGW hstr, const size_t start, size_t count) if (!pstr) return NULL; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } if (start + count > pstr->data_length) @@ -1056,7 +1052,7 @@ HSTRINGW STRAPI StrgLeft(HSTRINGW hstr, const size_t count) if (!pstr) return NULL; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } HSTRINGW hCopy = StrgCreate(NULL); @@ -1078,7 +1074,7 @@ HSTRINGW STRAPI StrgRight(HSTRINGW hstr, const size_t count) if (!pstr) return NULL; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } HSTRINGW hCopy = StrgCreate(NULL); @@ -1115,7 +1111,7 @@ LPWSTR STRAPI StrgWriteAccessBuf(HSTRINGW hstr, size_t min_len) return NULL; if (pstr->alloc_length <= min_len) { - ReAllocW(pstr, min_len, true); + ReAllocW(pstr, min_len); } return pstr->data; } @@ -1127,15 +1123,13 @@ void STRAPI StrgSanitize(HSTRINGW hstr) if (!pstr) return; if (!pstr->data) { - ReAllocW(pstr, 0, true); + ReAllocW(pstr, 0); } // ensure buffer limits - pstr->alloc_length = LengthOfBuffer(pstr->data); - ptrdiff_t const end = (ptrdiff_t)pstr->alloc_length - 1; - if (end >= 0) { - if (pstr->data) - pstr->data[end] = WCHR_NULL; // terminating zero - } + size_t const buflen = LengthOfBuffer(pstr->data); + if (pstr->data && (buflen > 0)) + pstr->data[buflen - 1] = WCHR_NULL; + pstr->alloc_length = buflen; pstr->data_length = StrlenW(pstr->data); } // -------------------------------------------------------------------------- diff --git a/src/Edit.c b/src/Edit.c index b9bd2a1b7..a68876bd1 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -161,7 +161,7 @@ static int msgcmp(void* mqc1, void* mqc2) return 1; } -static int64_t sortcmp(void *mqc1, void *mqc2) { +static LONG64 sortcmp(void *mqc1, void *mqc2) { const CmdMessageQueue_t *const pMQC1 = (CmdMessageQueue_t *)mqc1; const CmdMessageQueue_t *const pMQC2 = (CmdMessageQueue_t *)mqc2; return (pMQC1->delay - pMQC2->delay); @@ -9682,9 +9682,9 @@ void EditToggleFolds(FOLD_ACTION action, bool bForceAll) void EditFoldClick(DocLn ln, int mode) { static struct { - DocLn ln; - int mode; - int64_t iTickCount; + DocLn ln; + int mode; + LONG64 iTickCount; } prev = { 0, 0, 0 }; bool fGotoFoldPoint = mode & FOLD_SIBLINGS; diff --git a/src/Helpers.h b/src/Helpers.h index 99971899b..30f52dcf3 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -869,14 +869,14 @@ static inline int PointSizeToFontHeight(const float fPtHeight, const HDC hdc) { // ---------------------------------------------------------------------------- -static inline int64_t GetTicks_ms() { +static inline LONG64 GetTicks_ms() { LARGE_INTEGER freq; if (!QueryPerformanceFrequency(&freq)) { - return (int64_t)GetTickCount64(); + return (LONG64)GetTickCount64(); } LARGE_INTEGER ticks; if (!QueryPerformanceCounter(&ticks)) { - return (int64_t)GetTickCount64(); + return (LONG64)GetTickCount64(); } return (ticks.QuadPart * 1000LL) / freq.QuadPart; } diff --git a/src/Notepad3.c b/src/Notepad3.c index 22e9b52bc..2ff500533 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -155,7 +155,7 @@ static int s_iAlignMode = 0; static bool s_bIsAppThemed = true; static UINT s_msgTaskbarCreated = 0; static WCHAR s_wchTitleExcerpt[MIDSZ_BUFFER] = { L'\0' }; -static int64_t s_iLastCopyTime = 0; +static LONG64 s_iLastCopyTime = 0; static bool s_bLastCopyFromMe = false; static bool s_bInMultiEditMode = false; static bool s_bCallTipEscDisabled = false; @@ -445,8 +445,8 @@ static inline void _SplitUndoTransaction() // ---------------------------------------------------------------------------- -static void _DelayClearCallTip(const int64_t delay); -static void _DelaySplitUndoTransaction(const int64_t delay); +static void _DelayClearCallTip(const LONG64 delay); +static void _DelaySplitUndoTransaction(const LONG64 delay); static void _RestoreActionSelection(const LONG token, DoAction doAct); // ---------------------------------------------------------------------------- @@ -527,7 +527,7 @@ static int msgcmp(void* mqc1, void* mqc2) #define _MQ_ms2cycl(T) (((T) + USER_TIMER_MINIMUM) / _MQ_TIMER_CYCLE) -static void _MQ_AppendCmd(CmdMessageQueue_t* const pMsgQCmd, int64_t cycles) +static void _MQ_AppendCmd(CmdMessageQueue_t* const pMsgQCmd, LONG64 cycles) { if (!pMsgQCmd) { return; } @@ -804,7 +804,6 @@ static void _InitGlobals() FocusedView.CodeFoldingAvailable = false; FocusedView.ShowCodeFolding = true; - FileWatching.flagChangeNotify = FWM_DONT_CARE; FileWatching.FileWatchingMode = FWM_DONT_CARE; FileWatching.MonitoringLog = false; @@ -1836,9 +1835,6 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) Encoding_Forced(s_flagSetEncoding); switch (s_flagChangeNotify) { - case FWM_NO_INIT: - FileWatching.FileWatchingMode = Settings.FileWatchingMode; - break; case FWM_DONT_CARE: case FWM_INDICATORSILENT: case FWM_MSGBOX: @@ -1846,8 +1842,9 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) case FWM_EXCLUSIVELOCK: FileWatching.FileWatchingMode = s_flagChangeNotify; break; + case FWM_NO_INIT: default: - FileWatching.FileWatchingMode = FWM_MSGBOX; + FileWatching.FileWatchingMode = Settings.FileWatchingMode; break; } @@ -3707,15 +3704,20 @@ LRESULT MsgCopyData(HWND hwnd, WPARAM wParam, LPARAM lParam) } if (bOpened) { if (params->flagChangeNotify == FWM_MSGBOX) { - FileWatching.FileWatchingMode = FWM_DONT_CARE; + FileWatching.FileWatchingMode = FWM_MSGBOX; InstallFileWatching(true); - } else if (params->flagChangeNotify == FWM_AUTORELOAD) { - if (!FileWatching.MonitoringLog) { + } + else if (params->flagChangeNotify == FWM_AUTORELOAD) { + if (FileWatching.MonitoringLog) { PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); - } else { - FileWatching.FileWatchingMode = FWM_AUTORELOAD; - InstallFileWatching(true); } + else { + FileWatching.FileWatchingMode = FWM_AUTORELOAD; + } + InstallFileWatching(true); + } + else if (params->flagChangeNotify == FWM_INDICATORSILENT) { + InstallFileWatching(true); } if (params->flagSetEncoding != CPI_NONE) { @@ -6210,7 +6212,6 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) _saveChgNotify = FileWatching.FileWatchingMode; } FileWatching.MonitoringLog = !FileWatching.MonitoringLog; // toggle - FileWatching.flagChangeNotify = s_flagChangeNotify; SciCall_SetReadOnly(FileWatching.MonitoringLog); if (FileWatching.MonitoringLog) { @@ -6222,7 +6223,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) SciCall_SetEndAtLastLine(false); } else { FileWatching.FileWatchingMode = _saveChgNotify; - FileWatching.FileCheckInterval = clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); + FileWatching.FileCheckInterval = Settings2.FileCheckInterval; SciCall_SetEndAtLastLine(!Settings.ScrollPastEOF); } Sci_ScrollSelectionToView(); @@ -8563,7 +8564,7 @@ inline static LRESULT _MsgNotifyLean(const SCNotification *const scn, bool* bMod } } if (*bModified) { - int64_t const timeout = Settings2.UndoTransactionTimeout; + LONG64 const timeout = Settings2.UndoTransactionTimeout; if (timeout != 0LL) { if (!bInUndoRedoStep) { _DelaySplitUndoTransaction(max_ll(_MQ_IMMEDIATE, timeout)); @@ -9671,7 +9672,7 @@ static void _DelayUpdateStatusbar(const int delay, const bool bForceRedraw) // // _DelayUpdateToolbar() // -static void _DelayUpdateToolbar(const int64_t delay) +static void _DelayUpdateToolbar(const LONG64 delay) { CmdMessageQueue_t mqc = MQ_WM_CMD_INIT(Globals.hwndMain, IDT_TIMER_UPDATE_TOOLBAR, 0LL); _MQ_AppendCmd(&mqc, _MQ_ms2cycl(delay)); @@ -9682,7 +9683,7 @@ static void _DelayUpdateToolbar(const int64_t delay) // // _DelayUpdateTitlebar() // -static void _DelayUpdateTitlebar(const int64_t delay, const HWND hwnd) +static void _DelayUpdateTitlebar(const LONG64 delay, const HWND hwnd) { CmdMessageQueue_t mqc = MQ_WM_CMD_INIT(Globals.hwndMain, IDT_TIMER_UPDATE_TITLEBAR, (LPARAM)hwnd); _MQ_AppendCmd(&mqc, _MQ_ms2cycl(delay)); @@ -9693,7 +9694,7 @@ static void _DelayUpdateTitlebar(const int64_t delay, const HWND hwnd) // // _DelayClearCallTip() // -static void _DelayClearCallTip(const int64_t delay) +static void _DelayClearCallTip(const LONG64 delay) { CmdMessageQueue_t mqc = MQ_WM_CMD_INIT(Globals.hwndMain, IDT_TIMER_CLEAR_CALLTIP, 0LL); _MQ_AppendCmd(&mqc, _MQ_ms2cycl(delay)); @@ -9704,7 +9705,7 @@ static void _DelayClearCallTip(const int64_t delay) // // _DelaySplitUndoTransaction() // -static void _DelaySplitUndoTransaction(const int64_t delay) +static void _DelaySplitUndoTransaction(const LONG64 delay) { CmdMessageQueue_t mqc = MQ_WM_CMD_INIT(Globals.hwndMain, IDT_TIMER_UNDO_TRANSACTION, 0); _MQ_AppendCmd(&mqc, _MQ_ms2cycl(delay)); @@ -9715,10 +9716,10 @@ static void _DelaySplitUndoTransaction(const int64_t delay) // // MarkAllOccurrences() // -void MarkAllOccurrences(const int64_t delay, const bool bForceClear) +void MarkAllOccurrences(const LONG64 delay, const bool bForceClear) { CmdMessageQueue_t mqc = MQ_WM_CMD_INIT(Globals.hwndMain, IDT_TIMER_CALLBACK_MRKALL, bForceClear); - int64_t const timer = (delay < 0) ? Settings2.UpdateDelayMarkAllOccurrences : delay; + LONG64 const timer = (delay < 0) ? Settings2.UpdateDelayMarkAllOccurrences : delay; _MQ_AppendCmd(&mqc, _MQ_ms2cycl(timer)); } @@ -11199,10 +11200,11 @@ bool ConsistentIndentationCheck(EditFileIOStatus* status) // static inline void _ResetFileWatchingMode() { + FileWatching.FileWatchingMode = (s_flagChangeNotify != FWM_NO_INIT) ? s_flagChangeNotify : Settings.FileWatchingMode; if (FileWatching.MonitoringLog) { + FileWatching.FileWatchingMode = FWM_AUTORELOAD; PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); } - FileWatching.FileWatchingMode = Settings.FileWatchingMode; ResetFileObservationData(true); } @@ -11252,18 +11254,20 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) SetSaveDone(); - // Terminate file watching + // Restart file watching AutoSaveStop(); - InstallFileWatching(false); // terminate + InstallFileWatching(false); // terminate old if (Settings.ResetFileWatching) { _ResetFileWatchingMode(); } + InstallFileWatching(true); + Flags.bSettingsFileSoftLocked = false; UpdateSaveSettingsCmds(); if (SciCall_GetZoom() != 100) { ShowZoomCallTip(); } - + UndoRedoReset(); UpdateToolbar(); @@ -11420,19 +11424,14 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) // Install watching of the current file AutoSaveStop(); - if (!bReloadFile) { - InstallFileWatching(false); // terminate previous - if (Settings.ResetFileWatching) { - _ResetFileWatchingMode(); - } + InstallFileWatching(false); // terminate previous + if (!bReloadFile && Settings.ResetFileWatching) { + _ResetFileWatchingMode(); } // consistent settings file handling (if loaded in editor) Flags.bSettingsFileSoftLocked = (Path_StrgComparePathNormalized(Paths.CurrentFile, Paths.IniFile) == 0); - ResetFileObservationData(true); - InstallFileWatching(true); - // the .LOG feature ... if (SciCall_GetTextLength() >= 4) { char tchLog[5] = { '\0', '\0', '\0', '\0', '\0' }; @@ -11513,6 +11512,10 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) UpdateStatusbar(true); Path_Release(hopen_file); + + ResetFileObservationData(true); + InstallFileWatching(fSuccess); + return fSuccess; } @@ -12612,12 +12615,11 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) static inline void NotifyIfFileHasChanged() { - if (IsFileChangedFlagSet() || IsFileDeletedFlagSet() || RaiseFlagIfCurrentFileChanged()) { PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0); } // reset Timeout interval - s_FileChgObsvrData.iFileChangeNotifyTime = GetTicks_ms(); + InterlockedExchange64(&(s_FileChgObsvrData.iFileChangeNotifyTime), GetTicks_ms()); } // ---------------------------------------------------------------------------- @@ -12630,7 +12632,7 @@ static void CALLBACK WatchTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR UNREFERENCED_PARAMETER(uMsg); UNREFERENCED_PARAMETER(hwnd); - int64_t const diff = (GetTicks_ms() - s_FileChgObsvrData.iFileChangeNotifyTime); + LONG64 const diff = (GetTicks_ms() - InterlockedOr64(&(s_FileChgObsvrData.iFileChangeNotifyTime), 0LL)); // Directory-Observer is not notified for continuously updated (log-)files if (diff > FileWatching.FileCheckInterval) { NotifyIfFileHasChanged(); @@ -12744,7 +12746,7 @@ void InstallFileWatching(const bool bInstall) { BackgroundWorker_Start(&(s_FileChgObsvrData.worker), FileChangeObserver, &s_FileChgObsvrData); } - s_FileChgObsvrData.iFileChangeNotifyTime = GetTicks_ms(); + InterlockedExchange64(&(s_FileChgObsvrData.iFileChangeNotifyTime), GetTicks_ms()); if (Settings2.FileCheckInterval > 0) { SetTimer(Globals.hwndMain, ID_WATCHTIMER, (UINT)FileWatching.FileCheckInterval, WatchTimerProc); diff --git a/src/Notepad3.h b/src/Notepad3.h index 373f5316f..63082cade 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -126,7 +126,7 @@ void CheckAutoLoadMostRecent(); void ShowZoomCallTip(); void ShowWrapAroundCallTip(bool forwardSearch); -void MarkAllOccurrences(const int64_t delay, const bool bForceClear); +void MarkAllOccurrences(const LONG64 delay, const bool bForceClear); void UpdateToolbar(); void UpdateStatusbar(const bool bForceRedraw); diff --git a/src/Notepad3.vcxproj b/src/Notepad3.vcxproj index 5a8c96629..f2d1e436c 100644 --- a/src/Notepad3.vcxproj +++ b/src/Notepad3.vcxproj @@ -40,9 +40,9 @@ v142 v143 true - true + false false - true + false Unicode @@ -72,9 +72,9 @@ v142 v143 true - true + false false - true + false Unicode diff --git a/src/TypeDefs.h b/src/TypeDefs.h index d87e5ee86..1fa49221d 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -330,7 +330,7 @@ typedef struct CmdMessageQueue_t { UINT cmd; WPARAM wparam; LPARAM lparam; - int64_t delay; + LONG64 delay; struct CmdMessageQueue_t* next; struct CmdMessageQueue_t* prev; @@ -735,8 +735,8 @@ typedef struct SETTINGS2_T { int FileLoadWarningMB; int OpacityLevel; int FindReplaceOpacityLevel; - int64_t FileCheckInterval; - int64_t UndoTransactionTimeout; + LONG64 FileCheckInterval; + LONG64 UndoTransactionTimeout; int IMEInteraction; int SciFontQuality; int LaunchInstanceWndPosOffset; @@ -845,7 +845,7 @@ typedef struct BackgroundWorker { typedef struct FCOBSRVDATA_T { - int64_t iFileChangeNotifyTime; + volatile LONG64 iFileChangeNotifyTime; // multi-threaded WIN32_FIND_DATA fdCurFile; HANDLE hEventFileChanged; @@ -865,9 +865,8 @@ typedef struct FCOBSRVDATA_T { typedef struct FILEWATCHING_T { - FILE_WATCHING_MODE flagChangeNotify; // <-> s_flagChangeNotify; FILE_WATCHING_MODE FileWatchingMode; // <-> Settings.FileWatchingMode; - int64_t FileCheckInterval; // <-> clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); + LONG64 FileCheckInterval; // <-> clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL); bool MonitoringLog; } FILEWATCHING_T, *PFILEWATCHING_T;