// Author: Gockner, Simon
// Created: 2021-04-07
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Lib.NotifyIcon.Windows.Native.Types;
namespace Lib.NotifyIcon.Windows.Native
{
internal abstract class NativeWindow
{
private const uint WS_POPUP = 0x80000000;
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly WindowApi.WndProc _wndProc; //We need to store the window proc as a field so that it doesn't get garbage collected away
private readonly string _className = "NativeHelperWindow" + Guid.NewGuid();
///
/// The window handle of the underlying native window
///
public IntPtr Handle { get; }
///
/// Creates a new native (Win32) helper window for receiving window messages
///
protected NativeWindow()
{
_wndProc = WndProc;
WndClassEx wndClassEx = new()
{
cbSize = Marshal.SizeOf(),
lpfnWndProc = _wndProc,
hInstance = WindowApi.GetModuleHandle(null),
lpszClassName = _className
};
ushort atom = WindowApi.RegisterClassEx(ref wndClassEx);
if (atom == 0)
throw new Win32Exception();
Handle = WindowApi.CreateWindowEx(0, atom, null, 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)
WindowApi.PostMessage(Handle, (uint) WindowsMessage.WmDestroy, 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) WindowsMessage.WmClose:
{
WindowApi.DestroyWindow(hWnd);
break;
}
case (uint) WindowsMessage.WmDestroy:
{
WindowApi.PostQuitMessage(0);
break;
}
default:
return WindowApi.DefWindowProc(hWnd, msg, wParam, lParam);
}
return IntPtr.Zero;
}
}
}