From 1b0ff07133851b32f853d6815a7cc17612475f0e Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Fri, 13 Nov 2020 13:21:23 +0100 Subject: [PATCH 1/4] Fixes Issue 4980: Message loop exit when GetMessage < 0 --- src/Avalonia.Base/Logging/LogArea.cs | 5 +++++ .../Avalonia.Win32/Interop/UnmanagedMethods.cs | 4 ++-- src/Windows/Avalonia.Win32/Win32Platform.cs | 11 ++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Base/Logging/LogArea.cs b/src/Avalonia.Base/Logging/LogArea.cs index 3c19b47a05..ce330247f3 100644 --- a/src/Avalonia.Base/Logging/LogArea.cs +++ b/src/Avalonia.Base/Logging/LogArea.cs @@ -34,5 +34,10 @@ namespace Avalonia.Logging /// The log event comes from the control system. /// public const string Control = "Control"; + + /// + /// The log evevnt come from Win32Platform + /// + public const string Win32Platform = nameof(Win32Platform); } } diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index f88c57cf59..85938829f6 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -931,8 +931,8 @@ namespace Avalonia.Win32.Interop [DllImport("user32.dll", EntryPoint = "MapVirtualKeyW")] public static extern uint MapVirtualKey(uint uCode, uint uMapType); - [DllImport("user32.dll", EntryPoint = "GetMessageW")] - public static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); + [DllImport("user32.dll", EntryPoint = "GetMessageW",SetLastError = true)] + public static extern int GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); [DllImport("user32.dll")] public static extern int GetMessageTime(); diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 5b16cae26e..209cb63603 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -137,13 +137,18 @@ namespace Avalonia.Win32 public void RunLoop(CancellationToken cancellationToken) { - while (!cancellationToken.IsCancellationRequested) + var result = 0; + while (!cancellationToken.IsCancellationRequested + && (result = UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0)) > 0) { - UnmanagedMethods.MSG msg; - UnmanagedMethods.GetMessage(out msg, IntPtr.Zero, 0, 0); UnmanagedMethods.TranslateMessage(ref msg); UnmanagedMethods.DispatchMessage(ref msg); } + if (result < 0) + { + Logging.Logger.TryGet(Logging.LogEventLevel.Error, Logging.LogArea.Win32Platform) + ?.Log(this, "Unmanaged error in message loop. Error Code: {0}", Marshal.GetLastWin32Error()); + } } public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action callback) From b31b6d68c9791085766550cdc29bcde12b1608a0 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Fri, 13 Nov 2020 16:17:03 +0100 Subject: [PATCH 2/4] Fixes ProcessMessage --- src/Windows/Avalonia.Win32/Win32Platform.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 209cb63603..1ed4d8dc9c 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -129,10 +129,18 @@ namespace Avalonia.Win32 public void ProcessMessage() { - UnmanagedMethods.MSG msg; - UnmanagedMethods.GetMessage(out msg, IntPtr.Zero, 0, 0); - UnmanagedMethods.TranslateMessage(ref msg); - UnmanagedMethods.DispatchMessage(ref msg); + + if (UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0) > 0) + { + UnmanagedMethods.TranslateMessage(ref msg); + UnmanagedMethods.DispatchMessage(ref msg); + } + else + { + Logging.Logger.TryGet(Logging.LogEventLevel.Error, Logging.LogArea.Win32Platform) + ?.Log(this, "Unmanaged error in {0}. Error Code: {1}", nameof(ProcessMessage), Marshal.GetLastWin32Error()); + + } } public void RunLoop(CancellationToken cancellationToken) @@ -147,7 +155,7 @@ namespace Avalonia.Win32 if (result < 0) { Logging.Logger.TryGet(Logging.LogEventLevel.Error, Logging.LogArea.Win32Platform) - ?.Log(this, "Unmanaged error in message loop. Error Code: {0}", Marshal.GetLastWin32Error()); + ?.Log(this, "Unmanaged error in {0}. Error Code: {1}" ,nameof(RunLoop), Marshal.GetLastWin32Error()); } } From cfb81aedcaae7d501017a4224f18ffc8348ae4de Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 14 Nov 2020 00:44:44 +0100 Subject: [PATCH 3/4] fixes typo. --- src/Avalonia.Base/Logging/LogArea.cs | 2 +- src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs | 2 +- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Base/Logging/LogArea.cs b/src/Avalonia.Base/Logging/LogArea.cs index ce330247f3..2ad220dddd 100644 --- a/src/Avalonia.Base/Logging/LogArea.cs +++ b/src/Avalonia.Base/Logging/LogArea.cs @@ -36,7 +36,7 @@ namespace Avalonia.Logging public const string Control = "Control"; /// - /// The log evevnt come from Win32Platform + /// The log event comes from Win32Platform. /// public const string Win32Platform = nameof(Win32Platform); } diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index 85938829f6..b164bcc611 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -931,7 +931,7 @@ namespace Avalonia.Win32.Interop [DllImport("user32.dll", EntryPoint = "MapVirtualKeyW")] public static extern uint MapVirtualKey(uint uCode, uint uMapType); - [DllImport("user32.dll", EntryPoint = "GetMessageW",SetLastError = true)] + [DllImport("user32.dll", EntryPoint = "GetMessageW", SetLastError = true)] public static extern int GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); [DllImport("user32.dll")] diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 1ed4d8dc9c..345c825a5d 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -155,7 +155,7 @@ namespace Avalonia.Win32 if (result < 0) { Logging.Logger.TryGet(Logging.LogEventLevel.Error, Logging.LogArea.Win32Platform) - ?.Log(this, "Unmanaged error in {0}. Error Code: {1}" ,nameof(RunLoop), Marshal.GetLastWin32Error()); + ?.Log(this, "Unmanaged error in {0}. Error Code: {1}", nameof(RunLoop), Marshal.GetLastWin32Error()); } } From 7ff860c8ef54c5ce38b2e6c672297e651c1142c2 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 14 Nov 2020 14:40:21 +0100 Subject: [PATCH 4/4] fix ProcessMessage issue --- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 345c825a5d..e854ceae0b 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -130,7 +130,7 @@ namespace Avalonia.Win32 public void ProcessMessage() { - if (UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0) > 0) + if (UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0) > -1) { UnmanagedMethods.TranslateMessage(ref msg); UnmanagedMethods.DispatchMessage(ref msg);