SystemMenuHook.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows;
  4. using System.Windows.Interop;
  5. using HandyControl.Tools.Interop;
  6. namespace HandyControl.Tools;
  7. public class SystemMenuHook
  8. {
  9. private static readonly Dictionary<int, HwndSource> DataDic = new();
  10. public static event Action<int> Click;
  11. public static void Insert(int index, int id, string text, Window window)
  12. {
  13. var hookId = window.GetHandle();
  14. var source = HwndSource.FromHwnd(hookId);
  15. if (source != null)
  16. {
  17. DataDic[id] = source;
  18. InteropMethods.InsertMenu(InteropMethods.GetSystemMenu(hookId, false), index, InteropValues.MF_BYPOSITION, id, text);
  19. source.AddHook(WinProc);
  20. }
  21. }
  22. public static void InsertSeperator(int index, Window window) => InteropMethods.InsertMenu(
  23. InteropMethods.GetSystemMenu(window.GetHandle(), false), index,
  24. InteropValues.MF_BYPOSITION | InteropValues.MF_SEPARATOR, 0, "");
  25. public static void Remove(int id)
  26. {
  27. if (DataDic.TryGetValue(id, out var data))
  28. {
  29. data.RemoveHook(WinProc);
  30. DataDic.Remove(id);
  31. }
  32. }
  33. private static IntPtr WinProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
  34. {
  35. if (msg == InteropValues.WM_SYSCOMMAND)
  36. {
  37. var id = wparam.ToInt32();
  38. if (DataDic.ContainsKey(id))
  39. {
  40. Click?.Invoke(id);
  41. }
  42. }
  43. return IntPtr.Zero;
  44. }
  45. }