SystemMenuManager.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Interop;
  9. namespace WpfStyleableWindow.StyleableWindow
  10. {
  11. public static class SystemMenuManager
  12. {
  13. public static void ShowMenu(Window targetWindow, Point menuLocation)
  14. {
  15. if (targetWindow == null)
  16. throw new ArgumentNullException("TargetWindow is null.");
  17. int x, y;
  18. try
  19. {
  20. x = Convert.ToInt32(menuLocation.X);
  21. y = Convert.ToInt32(menuLocation.Y);
  22. }
  23. catch (OverflowException)
  24. {
  25. x = 0;
  26. y = 0;
  27. }
  28. uint WM_SYSCOMMAND = 0x112, TPM_LEFTALIGN = 0x0000, TPM_RETURNCMD = 0x0100;
  29. IntPtr window = new WindowInteropHelper(targetWindow).Handle;
  30. IntPtr wMenu = NativeMethods.GetSystemMenu(window, false);
  31. int command = NativeMethods.TrackPopupMenuEx(wMenu, TPM_LEFTALIGN | TPM_RETURNCMD, x, y, window, IntPtr.Zero);
  32. if (command == 0)
  33. return;
  34. NativeMethods.PostMessage(window, WM_SYSCOMMAND, new IntPtr(command), IntPtr.Zero);
  35. }
  36. }
  37. internal static class NativeMethods
  38. {
  39. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  40. internal static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
  41. [DllImport("user32.dll")]
  42. internal static extern int TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm);
  43. [DllImport("user32.dll")]
  44. internal static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
  45. [DllImport("user32.dll")]
  46. internal static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
  47. }
  48. }