Launch window's System Menu on custom window

前端 未结 2 535
执念已碎
执念已碎 2021-01-12 11:26

I would like to call the ContextMenu when you click on application\'s icon or right mouse click on the title bar of application.

This is the Conte

相关标签:
2条回答
  • 2021-01-12 12:08

    The menu that you want to show is system ContextMenu. To work with that you need to import some user32 functions as shown in the code below. I have launched the system menu on button click. You can launch it on any action, right mouse click etc

    GetSystemMenu gets the system menu and TrackPopupMenuEx is used to display it. PostMessage is the send system command on menuitem click.

    public partial class Window3 : Window
    {
    
         private const int WM_SYSCOMMAND = 0x112;
        uint TPM_LEFTALIGN = 0x0000;
        uint TPM_RETURNCMD = 0x0100;
         const UInt32 MF_ENABLED = 0x00000000;
         const UInt32 MF_GRAYED = 0x00000001;
         internal const UInt32 SC_MAXIMIZE = 0xF030;
         internal const UInt32 SC_RESTORE = 0xF120;
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
    
        [DllImport("user32.dll")]
        static extern int TrackPopupMenuEx(IntPtr hmenu, uint fuFlags,
          int x, int y, IntPtr hwnd, IntPtr lptpm);
    
        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    
        [DllImport("user32.dll")]
        static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem,
           uint uEnable);
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            WindowInteropHelper helper = new WindowInteropHelper(this);
            IntPtr callingWindow = helper.Handle;
            IntPtr wMenu = GetSystemMenu(callingWindow, false);
            // Display the menu
            if (this.WindowState == System.Windows.WindowState.Maximized)
            {
                EnableMenuItem(wMenu, SC_MAXIMIZE, MF_GRAYED);
            }
            else
            {
                EnableMenuItem(wMenu, SC_MAXIMIZE, MF_ENABLED);
            }
    
            int command = TrackPopupMenuEx(wMenu, TPM_LEFTALIGN | TPM_RETURNCMD, 100, 100, callingWindow, IntPtr.Zero);
            if (command == 0)
                return;
    
            PostMessage(callingWindow, WM_SYSCOMMAND, new IntPtr(command), IntPtr.Zero);
        }
    
    0 讨论(0)
  • 2021-01-12 12:16

    In your custom control like the image you shared, make the Visual Studio (icon) a imagebutton/button and show the ContextMenu from there when it is clicked.

    <Button Click="SomeEventHandler">
      <Button.ContextMenu>
         <ContextMenu>
          <!-- DO WHATEVER -->
         </ContextMenu>
      </Button.ContextMenu>
    </Button>
    

    Then on the Click handler, just say buttonName.ContextMenu.IsOpen = true

    More on how you can achieve this can be found here

    There is already a dependency property that you can set to show the context menu. I am not sure what you mean by "Do you need to make one yourself or you can call directly this one"

    Edit: I don't understand though why you are recreating the Window behavior instead of inheriting your custom window to the Window class and overwrite what you need to customize.

    0 讨论(0)
提交回复
热议问题