From 75d7341fa114da0a260085e272871cb218199f23 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 12 Feb 2018 21:45:50 +0300 Subject: [PATCH] "Cherry-picked" EmbeddedWindowImpl.cs from single win32 assembly PR --- .../Avalonia.Win32.Shared.projitems | 1 + .../Avalonia.Win32/Avalonia.Win32.csproj | 1 - .../Avalonia.Win32/EmbeddedWindowImpl.cs | 90 +++++++++++++++++++ .../Embedding/EmbeddedWindowImpl.cs | 43 --------- src/Windows/Avalonia.Win32/Win32Platform.cs | 4 - 5 files changed, 91 insertions(+), 48 deletions(-) create mode 100644 src/Windows/Avalonia.Win32/EmbeddedWindowImpl.cs delete mode 100644 src/Windows/Avalonia.Win32/Embedding/EmbeddedWindowImpl.cs diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.Shared.projitems b/src/Windows/Avalonia.Win32/Avalonia.Win32.Shared.projitems index 6f13747cb6..cca6f5acf1 100644 --- a/src/Windows/Avalonia.Win32/Avalonia.Win32.Shared.projitems +++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.Shared.projitems @@ -11,6 +11,7 @@ + diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj index 92d973238e..14f6211d68 100644 --- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj +++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj @@ -53,7 +53,6 @@ - Component diff --git a/src/Windows/Avalonia.Win32/EmbeddedWindowImpl.cs b/src/Windows/Avalonia.Win32/EmbeddedWindowImpl.cs new file mode 100644 index 0000000000..538a51c01e --- /dev/null +++ b/src/Windows/Avalonia.Win32/EmbeddedWindowImpl.cs @@ -0,0 +1,90 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using Avalonia.Platform; +using Avalonia.Win32.Interop; + +namespace Avalonia.Win32 +{ + class EmbeddedWindowImpl : WindowImpl, IEmbeddableWindowImpl + { + private static IntPtr DefaultParentWindow = CreateParentWindow(); + private static UnmanagedMethods.WndProc _wndProcDelegate; + + protected override IntPtr CreateWindowOverride(ushort atom) + { + var hWnd = UnmanagedMethods.CreateWindowEx( + 0, + atom, + null, + (int)UnmanagedMethods.WindowStyles.WS_CHILD, + 0, + 0, + 640, + 480, + DefaultParentWindow, + IntPtr.Zero, + IntPtr.Zero, + IntPtr.Zero); + return hWnd; + } + + protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + { + if (msg == (uint)UnmanagedMethods.WindowsMessage.WM_KILLFOCUS) + LostFocus?.Invoke(); + return base.WndProc(hWnd, msg, wParam, lParam); + } + + public event Action LostFocus; + + private static IntPtr CreateParentWindow() + { + _wndProcDelegate = new UnmanagedMethods.WndProc(ParentWndProc); + + var wndClassEx = new UnmanagedMethods.WNDCLASSEX + { + cbSize = Marshal.SizeOf(), + hInstance = UnmanagedMethods.GetModuleHandle(null), + lpfnWndProc = _wndProcDelegate, + lpszClassName = "AvaloniaEmbeddedWindow-" + Guid.NewGuid(), + }; + + var atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx); + + if (atom == 0) + { + throw new Win32Exception(); + } + + var hwnd = UnmanagedMethods.CreateWindowEx( + 0, + atom, + null, + (int)UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW, + UnmanagedMethods.CW_USEDEFAULT, + UnmanagedMethods.CW_USEDEFAULT, + UnmanagedMethods.CW_USEDEFAULT, + UnmanagedMethods.CW_USEDEFAULT, + IntPtr.Zero, + IntPtr.Zero, + IntPtr.Zero, + IntPtr.Zero); + + if (hwnd == IntPtr.Zero) + { + throw new Win32Exception(); + } + + return hwnd; + } + + private static IntPtr ParentWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + { + return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); + } + } +} diff --git a/src/Windows/Avalonia.Win32/Embedding/EmbeddedWindowImpl.cs b/src/Windows/Avalonia.Win32/Embedding/EmbeddedWindowImpl.cs deleted file mode 100644 index d27c28cb67..0000000000 --- a/src/Windows/Avalonia.Win32/Embedding/EmbeddedWindowImpl.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using Avalonia.Platform; -using Avalonia.Win32.Interop; - -namespace Avalonia.Win32 -{ - class EmbeddedWindowImpl : WindowImpl, IEmbeddableWindowImpl - { - private static readonly System.Windows.Forms.UserControl WinFormsControl = new System.Windows.Forms.UserControl(); - - public static IntPtr DefaultParentWindow = WinFormsControl.Handle; - - protected override IntPtr CreateWindowOverride(ushort atom) - { - var hWnd = UnmanagedMethods.CreateWindowEx( - 0, - atom, - null, - (int)UnmanagedMethods.WindowStyles.WS_CHILD, - 0, - 0, - 640, - 480, - DefaultParentWindow, - IntPtr.Zero, - IntPtr.Zero, - IntPtr.Zero); - return hWnd; - } - - protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) - { - if(msg == (uint)UnmanagedMethods.WindowsMessage.WM_KILLFOCUS) - LostFocus?.Invoke(); - return base.WndProc(hWnd, msg, wParam, lParam); - } - - public event Action LostFocus; - } -} diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index e265749249..a490e59cb7 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -196,13 +196,9 @@ namespace Avalonia.Win32 public IEmbeddableWindowImpl CreateEmbeddableWindow() { -#if NETSTANDARD - throw new NotSupportedException(); -#else var embedded = new EmbeddedWindowImpl(); embedded.Show(); return embedded; -#endif } public IPopupImpl CreatePopup()