From 03cb7bdda61acdf3290fff8529d6950646dee944 Mon Sep 17 00:00:00 2001 From: dahall Date: Mon, 8 Feb 2021 15:31:59 -0700 Subject: [PATCH] Fixed issues with BasicMessageWindow that caused creation failures and WndProc call failures. --- PInvoke/User32/BasicMessageWindow.cs | 37 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/PInvoke/User32/BasicMessageWindow.cs b/PInvoke/User32/BasicMessageWindow.cs index db1703ae..8026dc8d 100644 --- a/PInvoke/User32/BasicMessageWindow.cs +++ b/PInvoke/User32/BasicMessageWindow.cs @@ -19,31 +19,28 @@ namespace Vanara.PInvoke public delegate bool BasicMessageWindowFilter(HWND hwnd, uint msg, IntPtr wParam, IntPtr lParam, out IntPtr lReturn); /// Simple window to process messages. - /// - /// - /// + /// + /// + /// public class BasicMessageWindow : MarshalByRefObject, IDisposable, IHandle { private readonly SafeHWND hwnd; + private readonly WeakReference weakSelfRef; private bool isDisposed; + private WindowClass wCls; /// Initializes a new instance of the class. /// Specifies the callback method to use to process messages. public BasicMessageWindow(BasicMessageWindowFilter callback = null) { MessageFilter = callback; - ClassName = $"{GetType().Name}+{Guid.NewGuid()}"; - + weakSelfRef = new WeakReference(this); hwnd = CreateWindow(); } /// Finalizes an instance of the class. ~BasicMessageWindow() => Dispose(false); - /// Gets the name of the class. - /// The name of the class. - public string ClassName { get; private set; } - /// Gets the handle. /// The handle. public HWND Handle => hwnd; @@ -52,6 +49,10 @@ namespace Vanara.PInvoke /// The callback method. public BasicMessageWindowFilter MessageFilter { get; set; } + /// Gets the name of the class. + /// The name of the class. + public string ClassName => wCls?.ClassName; + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public void Dispose() { @@ -68,10 +69,9 @@ namespace Vanara.PInvoke /// protected virtual SafeHWND CreateWindow() { - var hInst = GetModuleHandle(); - var wcx = new WNDCLASSEX { cbSize = (uint)Marshal.SizeOf(typeof(WNDCLASSEX)), lpfnWndProc = WndProc, hInstance = hInst, lpszClassName = ClassName }; - var atom = Win32Error.ThrowLastErrorIfNull(Macros.MAKEINTATOM(RegisterClassEx(wcx))); - return Win32Error.ThrowLastErrorIfInvalid(CreateWindowEx(lpClassName: atom, hWndParent: HWND.HWND_MESSAGE, hInstance: hInst)); + HINSTANCE hInst = GetModuleHandle(); + wCls = new WindowClass($"{GetType().Name}+{Guid.NewGuid()}", hInst, WndProc); + return Win32Error.ThrowLastErrorIfInvalid(CreateWindowEx(0, wCls.Atom, hWndParent: HWND.HWND_MESSAGE, hInstance: hInst)); } /// Releases unmanaged and - optionally - managed resources. @@ -85,13 +85,16 @@ namespace Vanara.PInvoke isDisposed = true; hwnd?.Dispose(); // Calls DestroyWindow - UnregisterClass(ClassName, GetModuleHandle()); - ClassName = null; + wCls?.Unregister(); } - private IntPtr WndProc(HWND hwnd, uint msg, IntPtr wParam, IntPtr lParam) => - MessageFilter is null || !MessageFilter.Invoke(hwnd, msg, wParam, lParam, out var lRet) + private IntPtr WndProc(HWND hwnd, uint msg, IntPtr wParam, IntPtr lParam) + { + if (msg == (uint)WindowMessage.WM_NCCREATE) + return (IntPtr)1; + return !weakSelfRef.IsAlive || weakSelfRef.Target is null || MessageFilter is null || !MessageFilter.Invoke(hwnd, msg, wParam, lParam, out IntPtr lRet) ? DefWindowProc(hwnd, msg, wParam, lParam) : lRet; + } } } \ No newline at end of file