如何右键单击打开窗口系统菜单?

mir*_*lav 5 .net user-interface

我有一个无边界的初始屏幕表单,显示加载进度并包含“ 最小化”和“ 关闭”按钮(类似于Office 2013中的初始屏幕)。我还想提供该窗口的系统菜单,该菜单在右键单击表单中的任何位置时将打开。

窗口的经典系统菜单

目前,我通过发送Alt + Space键来打开菜单。

    System.Windows.Forms.SendKeys.SendWait("% ")   'sending Alt+Space
Run Code Online (Sandbox Code Playgroud)

通过这种方法,窗口系统菜单始终在窗口的左上角打开。

当用户右键单击窗口的标题栏时,有没有办法像Windows一样以编程方式打开系统菜单?弹出菜单打开的API调用或消息?

我想在应用程序中保持系统菜单可用,因为我还在其中添加了“关于”“设置”项。(此应用充当核心应用的独立启动器和更新器。)

该平台是WPFWindows窗体库在内,太(由于使用的解决方法SendWait())。如果发布一些代码,请随意选择VB或C#。

Han*_*ant 6

没有内置的 winapi 功能来显示系统菜单。您可以使用 pinvoke 自己显示它。GetSystemMenu() 函数返回系统菜单的句柄,通过使用 TrackPopupMenu() 显示它,通过调用 SendMessage 发送 WM_SYSCOMMAND 来执行选定的命令。

一些示例代码显示了如何执行此操作并包含必要的声明:

using System.Runtime.InteropServices;
...
    private void Window_MouseDown(object sender, MouseButtonEventArgs e) {
        if (e.ChangedButton == MouseButton.Right) {
            IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
            RECT pos;
            GetWindowRect(hWnd, out pos);
            IntPtr hMenu = GetSystemMenu(hWnd, false);
            int cmd = TrackPopupMenu(hMenu, 0x100, pos.left, pos.top, 0, hWnd, IntPtr.Zero);
            if (cmd > 0) SendMessage(hWnd, 0x112, (IntPtr)cmd, IntPtr.Zero);
        }
    }
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
    [DllImport("user32.dll")]
    static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
    [DllImport("user32.dll")]
    static extern int TrackPopupMenu(IntPtr hMenu, uint uFlags, int x, int y,
       int nReserved, IntPtr hWnd, IntPtr prcRect);
    [DllImport("user32.dll")]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
    struct RECT { public int left, top, right, bottom; }
Run Code Online (Sandbox Code Playgroud)

请注意,您可以在任何地方显示菜单,我只是选择了窗口的左上角。请注意,位置值以像素为单位。