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调用或消息?
我想在应用程序中保持系统菜单可用,因为我还在其中添加了“关于”和“设置”项。(此应用充当核心应用的独立启动器和更新器。)
该平台是WPF与Windows窗体库在内,太(由于使用的解决方法SendWait())。如果发布一些代码,请随意选择VB或C#。
没有内置的 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)
请注意,您可以在任何地方显示菜单,我只是选择了窗口的左上角。请注意,位置值以像素为单位。