From 83d1bc2a9c25825517deeeace84b520121475d16 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sat, 24 Jul 2021 21:15:28 +0200 Subject: [PATCH] + fix: remove multiple file Notification, if current file has been deleted --- src/Edit.c | 12 ++--- src/Helpers.c | 2 +- src/Notepad3.c | 136 ++++++++++++++++++++++++------------------------- src/Notepad3.h | 6 +-- src/TypeDefs.h | 9 ++++ 5 files changed, 86 insertions(+), 79 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index fc8b521d9..f16e911cd 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -406,11 +406,11 @@ static LPCH EditReInterpretText(LPCCH pchSource, const int szSrc, cpi_enc_t from LPCH pchConvText = NULL; int cwch = MultiByteToWideChar(Encoding_GetCodePage(fromCP), 0, pchSource, szSrc, NULL, 0); - WCHAR *pwchText = (WCHAR *)AllocMem((cwch + 1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); + WCHAR *pwchText = (WCHAR *)AllocMem(((size_t)cwch + 1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); if (pwchText) { cwch = MultiByteToWideChar(Encoding_GetCodePage(fromCP), 0, pchSource, szSrc, pwchText, cwch); cmbch = WideCharToMultiByte(Encoding_GetCodePage(asCP), 0, pwchText, cwch, NULL, 0, NULL, NULL); - pchConvText = (LPCH)AllocMem(cmbch + 1, HEAP_ZERO_MEMORY); + pchConvText = (LPCH)AllocMem((size_t)cmbch + 1, HEAP_ZERO_MEMORY); if (pchConvText) { cmbch = WideCharToMultiByte(Encoding_GetCodePage(asCP), 0, pwchText, cwch, pchConvText, cmbch, NULL, NULL); } else { @@ -1946,7 +1946,7 @@ void EditReplaceAllChr(const WCHAR chSearch, const WCHAR chReplace) { const char *pchText = SciCall_GetRangePointer(iSelStart, iSelSize); int const reqsize = MultiByteToWideChar(Encoding_SciCP, 0, pchText, (int)iSelSize, NULL, 0); - LPWSTR const pwchText = AllocMem((reqsize + 1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); + LPWSTR const pwchText = AllocMem(((size_t)reqsize + 1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); if (pwchText == NULL) { return; } @@ -1955,7 +1955,7 @@ void EditReplaceAllChr(const WCHAR chSearch, const WCHAR chReplace) { StrReplChr(pwchText, chSearch, chReplace); int const cchRepl = WideCharToMultiByte(Encoding_SciCP, 0, pwchText, reqsize, NULL, 0, NULL, NULL); - char * const pchReplace = (char *)AllocMem((cchRepl + 1), HEAP_ZERO_MEMORY); + char *const pchReplace = (char *)AllocMem(((size_t)cchRepl + 1), HEAP_ZERO_MEMORY); if (pchReplace == NULL) { FreeMem(pwchText); return; @@ -5978,7 +5978,7 @@ static INT_PTR CALLBACK EditFindReplaceDlgProc(HWND hwnd, UINT umsg, WPARAM wPar } #endif - pTimerIdentifier = SetTimer(NULL, 0, _MQ_TIMER_CYCLE, MQ_ExecuteNext); + pTimerIdentifier = SetTimer(hwnd, 0, _MQ_TIMER_CYCLE, MQ_ExecuteNext); SET_INITIAL_ANCHORS() s_InitialTopLine = SciCall_GetFirstVisibleLine(); @@ -6140,7 +6140,7 @@ static INT_PTR CALLBACK EditFindReplaceDlgProc(HWND hwnd, UINT umsg, WPARAM wPar case WM_DESTROY: { - KillTimer(NULL, pTimerIdentifier); + KillTimer(hwnd, pTimerIdentifier); pTimerIdentifier = 0; _SetSearchFlags(hwnd, s_pEfrDataDlg); // sync diff --git a/src/Helpers.c b/src/Helpers.c index c5fc20ba0..479d166d4 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -2227,7 +2227,7 @@ void UrlUnescapeEx(LPWSTR lpURL, LPWSTR lpUnescaped, DWORD* pcchUnescaped) #if (NTDDI_VERSION >= NTDDI_WIN8) UrlUnescape(lpURL, lpUnescaped, pcchUnescaped, URL_UNESCAPE_AS_UTF8); #else - char* outBuffer = AllocMem(*pcchUnescaped + 1, HEAP_ZERO_MEMORY); + char *outBuffer = AllocMem((size_t)*pcchUnescaped + 1, HEAP_ZERO_MEMORY); if (!outBuffer) { return; } diff --git a/src/Notepad3.c b/src/Notepad3.c index aadda1de3..d9c2a63f2 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -386,17 +386,14 @@ static void _DelaySplitUndoTransaction(const int delay); // ---------------------------------------------------------------------------- -static HANDLE s_hEventNotifyFileChanged = INVALID_HANDLE_VALUE; - -static __forceinline bool isFileChangeNotifyAllowed() { - return (WaitForSingleObject(s_hEventNotifyFileChanged, 0) == WAIT_OBJECT_0); -} -static __forceinline void disableFileChangeNotify() { - ResetEvent(s_hEventNotifyFileChanged); -} -static __forceinline void enableFileChangeNotify() { - SetEvent(s_hEventNotifyFileChanged); +#if 0 +static HANDLE s_hEvent = INVALID_HANDLE_VALUE; +// SetEvent(s_hEvent); +// ResetEvent(s_hEvent); +static __forceinline bool IsEventSignaled() { + return (WaitForSingleObject(s_hEvent, 0) == WAIT_OBJECT_0); } +#endif // ---------------------------------------------------------------------------- @@ -879,7 +876,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, HGLOBAL const hMem = LoadResource(hInstance, hRes); DWORD const size = SizeofResource(hInstance, hRes); const char * const resText = (const char *)LockResource(hMem); - Globals.pStdDarkModeIniStyles = (char *)AllocMem((size + 1), 0); + Globals.pStdDarkModeIniStyles = (char *)AllocMem(((size_t)size + 1), 0); if (Globals.pStdDarkModeIniStyles) { memcpy(Globals.pStdDarkModeIniStyles, resText, size); Globals.pStdDarkModeIniStyles[size] = '\0'; // zero termination @@ -1365,12 +1362,12 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow) SetWindowPos(Globals.hwndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } - // manual reset und initially signaled (TRUE , TRUE) - s_hEventNotifyFileChanged = CreateEvent(NULL, TRUE, TRUE, NULL); - SetDialogIconNP3(Globals.hwndMain); InitWindowCommon(Globals.hwndMain, true); + // manual reset und initially not signaled (TRUE , FALSE) + // s_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); + if (Settings.TransparentMode) { SetWindowTransparentMode(Globals.hwndMain, true, Settings2.OpacityLevel); } @@ -1521,7 +1518,7 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow) // Encoding if (s_flagSetEncoding != CPI_NONE) { - SendMessage(Globals.hwndMain, WM_COMMAND, MAKELONG(IDM_ENCODING_SELECT, IDM_ENCODING_SELECT + s_flagSetEncoding), 0); + SendMessage(Globals.hwndMain, WM_COMMAND, (WPARAM)MAKELONG(IDM_ENCODING_SELECT, IDM_ENCODING_SELECT + s_flagSetEncoding), 0); s_flagSetEncoding = CPI_NONE; } @@ -1700,8 +1697,8 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case WM_NOTIFY: return MsgNotify(hwnd, wParam, lParam); - case WM_CHANGENOTIFY: - return MsgChangeNotify(hwnd, wParam, lParam); + case WM_FILECHANGEDNOTIFY: + return MsgFileChangeNotify(hwnd, wParam, lParam); //case WM_PARENTNOTIFY: // if (iLoWParam & WM_DESTROY) { @@ -2727,7 +2724,6 @@ void CreateBars(HWND hwnd, HINSTANCE hInstance) // // MsgEndSession() - Handle WM_ENDSESSION,WM_DESTROY // -// LRESULT MsgEndSession(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(wParam); @@ -2761,9 +2757,9 @@ LRESULT MsgEndSession(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) // Remove tray icon if necessary ShowNotifyIcon(hwnd, false); - if (IS_VALID_HANDLE(s_hEventNotifyFileChanged)) { - CloseHandle(s_hEventNotifyFileChanged); - } + //if (IS_VALID_HANDLE(s_hEvent)) { + // CloseHandle(s_hEvent); + //} bShutdownOK = true; } @@ -3315,18 +3311,19 @@ LRESULT MsgContextMenu(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) //============================================================================= // -// MsgChangeNotify() - Handles WM_CHANGENOTIFY +// MsgFileChangeNotify() - Handles WM_FILECHANGEDNOTIFY // -LRESULT MsgChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) +LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); + + SET_FCT_GUARD(TRUE); InstallFileWatching(false); // terminate DocPos const iCurPos = SciCall_GetCurrentPos(); - if ((FileWatching.FileWatchingMode == FWM_MSGBOX) || GetDocModified()) { SetForegroundWindow(hwnd); } @@ -3364,6 +3361,7 @@ LRESULT MsgChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) InstallFileWatching(true); } + RESET_FCT_GUARD(); return TRUE; } @@ -11167,7 +11165,7 @@ void CALLBACK PasteBoardTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTi static WIN32_FIND_DATA s_fdCurFile = { 0 }; -static inline bool IsCurrentFileChanged() { +static inline bool HasCurrentFileChanged() { if (StrIsEmpty(Paths.CurrentFile)) { return false; } @@ -11185,27 +11183,54 @@ static inline bool IsCurrentFileChanged() { static DWORD s_dwFileChangeNotifyTime = 0UL; -static inline void NotifyFileChangeEvent(const bool bCheckChg) { - if (isFileChangeNotifyAllowed()) { - if (!bCheckChg || IsCurrentFileChanged()) { - disableFileChangeNotify(); - KillTimer(NULL, ID_WATCHTIMER); - PostMessage(Globals.hwndMain, WM_CHANGENOTIFY, 0, 0); - } +static inline void NotifyIfFileHasChanged(const bool forcedNotify) { + + if (forcedNotify || HasCurrentFileChanged()) { + PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0); } - // reset AutoReloadTimeout interval - if (s_dwFileChangeNotifyTime) { - s_dwFileChangeNotifyTime = GetTickCount(); + // reset Timeout interval + s_dwFileChangeNotifyTime = GetTickCount(); +} +// ---------------------------------------------------------------------------- + + +static void CALLBACK WatchTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { + + UNREFERENCED_PARAMETER(dwTime); + UNREFERENCED_PARAMETER(idEvent); + UNREFERENCED_PARAMETER(uMsg); + UNREFERENCED_PARAMETER(hwnd); + + DWORD const diff = GetTickCount() - s_dwFileChangeNotifyTime; + + //if (HasDirChanged()) { + // ResetEventDirChanged(); + // NotifyIfFileHasChanged(false); + //} else + if (diff > Settings2.FileCheckInverval) { + // FWM_MSGBOX (polling: FileWatching.FileCheckInverval) + // Directory-Observer is not notified for continously updated (log-)files + NotifyIfFileHasChanged(false); + } else if (diff > FileWatching.AutoReloadTimeout) { + // FWM_AUTORELOAD (also FileWatching.MonitoringLog) + if (FileWatching.MonitoringLog) { + // monitoring: reload only on change + NotifyIfFileHasChanged(false); + } else { + // unconditional reload + NotifyIfFileHasChanged(false); + } } } // ---------------------------------------------------------------------------- -static DWORD const dwObservingTimeout = 240UL; // then check for done +DWORD const dwObservingTimeout = 250UL; // then check for done static HANDLE s_hEventObserverDone = INVALID_HANDLE_VALUE; static unsigned __stdcall FileChangeObserver(void * pArg) { + if (!pArg) { _endthreadex(0); return 0; @@ -11230,8 +11255,9 @@ static unsigned __stdcall FileChangeObserver(void * pArg) { break; case WAIT_OBJECT_0: - // Check if the changes affect the current file - NotifyFileChangeEvent(true); + if (HasCurrentFileChanged()) { + PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0); + } FindNextChangeNotification(*pChangeHandle); break; @@ -11257,31 +11283,6 @@ static unsigned __stdcall FileChangeObserver(void * pArg) { // ---------------------------------------------------------------------------- -static void CALLBACK WatchTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { - - UNREFERENCED_PARAMETER(dwTime); - UNREFERENCED_PARAMETER(idEvent); - UNREFERENCED_PARAMETER(uMsg); - UNREFERENCED_PARAMETER(hwnd); - - if (s_dwFileChangeNotifyTime == 0UL) { - // FWM_MSGBOX (polling: FileWatching.FileCheckInverval) - // Directory-Observer is not notified for continously updated (log-)files - NotifyFileChangeEvent(true); - } else if ((GetTickCount() - s_dwFileChangeNotifyTime) > FileWatching.AutoReloadTimeout) { - // FWM_AUTORELOAD (also FileWatching.MonitoringLog) - if (FileWatching.MonitoringLog) { - // monitoring: reload only on change - NotifyFileChangeEvent(true); - } else { - // unconditional reload ??? -> NotifyFileChangeEvent(false); - NotifyFileChangeEvent(true); - } - } -} -// ---------------------------------------------------------------------------- - - void InstallFileWatching(const bool bInstall) { static HANDLE _hChangeHandle = INVALID_HANDLE_VALUE; // observer @@ -11292,8 +11293,6 @@ void InstallFileWatching(const bool bInstall) { bool const bExclusiveLock = (FileWatching.FileWatchingMode == FWM_EXCLUSIVELOCK); bool const bWatchFile = (FileWatching.FileWatchingMode != FWM_DONT_CARE) && !bExclusiveLock; - disableFileChangeNotify(); - // always release exclusive file lock in any case if (IS_VALID_HANDLE(_hCurrFileHandle)) { CloseHandle(_hCurrFileHandle); @@ -11308,12 +11307,12 @@ void InstallFileWatching(const bool bInstall) { // Terminate previous watching if (bTerminate) { - KillTimer(NULL, ID_WATCHTIMER); + KillTimer(Globals.hwndMain, ID_WATCHTIMER); if (IS_VALID_HANDLE(_hObserverThread)) { if (IS_VALID_HANDLE(s_hEventObserverDone)) { DWORD const wait = SignalObjectAndWait(s_hEventObserverDone, _hObserverThread, - /*INFINITE*/ (dwObservingTimeout << 3), FALSE); + /*INFINITE*/ (dwObservingTimeout << 1), FALSE); if (wait == WAIT_OBJECT_0) { CloseHandle(_hObserverThread); // ok } @@ -11360,8 +11359,7 @@ void InstallFileWatching(const bool bInstall) { } s_dwFileChangeNotifyTime = (FileWatching.FileWatchingMode == FWM_AUTORELOAD) ? GetTickCount() : 0UL; - SetTimer(NULL, ID_WATCHTIMER, min_dw(Settings2.FileCheckInverval, FileWatching.AutoReloadTimeout), WatchTimerProc); - enableFileChangeNotify(); + SetTimer(Globals.hwndMain, ID_WATCHTIMER, min_dw(Settings2.FileCheckInverval, FileWatching.AutoReloadTimeout), WatchTimerProc); } else if (bExclusiveLock) { diff --git a/src/Notepad3.h b/src/Notepad3.h index b44580b6c..631664f84 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -87,8 +87,8 @@ typedef enum { //==== Notifications ========================================================== -#define WM_TRAYMESSAGE WM_USER // Callback Message from System Tray -#define WM_CHANGENOTIFY (WM_USER+1) // Change Notifications +#define WM_TRAYMESSAGE WM_USER // Callback Message from System Tray +#define WM_FILECHANGEDNOTIFY (WM_USER+1) // Change Notifications //#define WM_CHANGENOTIFYCLEAR (WM_USER+2) //==== Timer ================================================================== @@ -178,7 +178,7 @@ LRESULT MsgEnterMenuLoop(HWND hwnd, WPARAM wParam); LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam); LRESULT MsgExitMenuLoop(HWND hwnd, WPARAM wParam); LRESULT MsgNotify(HWND hwnd, WPARAM wParam, LPARAM lParam); -LRESULT MsgChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam); +LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam); LRESULT MsgTrayMessage(HWND hwnd, WPARAM wParam, LPARAM lParam); LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam); diff --git a/src/TypeDefs.h b/src/TypeDefs.h index 88011b39c..49765366f 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -758,4 +758,13 @@ typedef struct _themeFiles // ---------------------------------------------------------------------------- +#define SET_FCT_GUARD(RET) { \ + static bool _fctguard = false; \ + if (_fctguard) { return (RET); } \ + { _fctguard = true; + +#define RESET_FCT_GUARD() } _fctguard = false; } + +// ---------------------------------------------------------------------------- + //=============================================================================