123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- using System;
- using System.Runtime.InteropServices;
- using HandyControl.Tools.Interop;
- namespace HandyControl.Data;
- public abstract class HwndWrapper : DisposableObject
- {
- private IntPtr _handle;
- private bool _isHandleCreationAllowed = true;
- private ushort _wndClassAtom;
- private Delegate _wndProc;
- protected ushort WindowClassAtom
- {
- get
- {
- if (_wndClassAtom == 0) _wndClassAtom = CreateWindowClassCore();
- return _wndClassAtom;
- }
- }
- public IntPtr Handle
- {
- get
- {
- EnsureHandle();
- return _handle;
- }
- }
- protected virtual bool IsWindowSubclassed => false;
- protected virtual ushort CreateWindowClassCore() => RegisterClass(Guid.NewGuid().ToString());
- protected virtual void DestroyWindowClassCore()
- {
- if (_wndClassAtom != 0)
- {
- var moduleHandle = InteropMethods.GetModuleHandle(null);
- InteropMethods.UnregisterClass(new IntPtr(_wndClassAtom), moduleHandle);
- _wndClassAtom = 0;
- }
- }
- protected ushort RegisterClass(string className)
- {
- var wndClass = default(InteropValues.WNDCLASS);
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hbrBackground = IntPtr.Zero;
- wndClass.hCursor = IntPtr.Zero;
- wndClass.hIcon = IntPtr.Zero;
- wndClass.lpfnWndProc = _wndProc = new InteropValues.WndProc(WndProc);
- wndClass.lpszClassName = className;
- wndClass.lpszMenuName = null;
- wndClass.style = 0u;
- return InteropMethods.RegisterClass(ref wndClass);
- }
- private void SubclassWndProc()
- {
- _wndProc = new InteropValues.WndProc(WndProc);
- InteropMethods.SetWindowLong(_handle, -4, Marshal.GetFunctionPointerForDelegate(_wndProc));
- }
- protected abstract IntPtr CreateWindowCore();
- protected virtual void DestroyWindowCore()
- {
- if (_handle != IntPtr.Zero)
- {
- InteropMethods.DestroyWindow(_handle);
- _handle = IntPtr.Zero;
- }
- }
- protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) =>
- InteropMethods.DefWindowProc(hwnd, msg, wParam, lParam);
- public void EnsureHandle()
- {
- if (_handle == IntPtr.Zero)
- {
- if (!_isHandleCreationAllowed) return;
- _isHandleCreationAllowed = false;
- _handle = CreateWindowCore();
- if (IsWindowSubclassed) SubclassWndProc();
- }
- }
- protected override void DisposeNativeResources()
- {
- _isHandleCreationAllowed = false;
- DestroyWindowCore();
- DestroyWindowClassCore();
- }
- }
|