using System.ComponentModel; using System.Runtime.InteropServices; namespace System { /// /// A native Win32 window encapsulation for receiving window messages. /// internal class NativeWindow { readonly UnmanagedMethods.WndProc _wndProc; readonly string _className = "NativeHelperWindow" + Guid.NewGuid(); /// /// The window handle of the underlying native window. /// public IntPtr Handle { get; set; } /// /// Creates a new native (Win32) helper window for receiving window messages. /// public NativeWindow() { // We need to store the window proc as a field so that // it doesn't get garbage collected away. _wndProc = new UnmanagedMethods.WndProc(WndProc); UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX { cbSize = Marshal.SizeOf(), lpfnWndProc = _wndProc, hInstance = UnmanagedMethods.GetModuleHandle(null), lpszClassName = _className }; ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx); if (atom == 0) { throw new Win32Exception(); } Handle = UnmanagedMethods.CreateWindowEx(0, atom, null, UnmanagedMethods.WS_POPUP, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if (Handle == IntPtr.Zero) { throw new Win32Exception(); } } /// /// Destructs the object and destroys the native window. /// ~NativeWindow() { if (Handle != IntPtr.Zero) { UnmanagedMethods.PostMessage(Handle, (uint)UnmanagedMethods.WindowsMessage.WM_DESTROY, IntPtr.Zero, IntPtr.Zero); } } /// /// This function will receive all the system window messages relevant to our window. /// protected virtual IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { switch (msg) { case (uint)UnmanagedMethods.WindowsMessage.WM_CLOSE: UnmanagedMethods.DestroyWindow(hWnd); break; case (uint)UnmanagedMethods.WindowsMessage.WM_DESTROY: UnmanagedMethods.PostQuitMessage(0); break; default: return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); } return IntPtr.Zero; } } }