我有一个无边框的启动画面显示加载进度并包含 最小化 和 关闭 按钮(类似的东西)飞溅在Office 2013中看到的屏幕)。我还想提供窗口的系统菜单,该窗口在窗体的任何位置右键单击打开。
目前我正在通过发送 Alt + Space 键来打开菜单。
System.Windows.Forms.SendKeys.SendWait("% ") 'sending Alt+Space
使用这种方法,窗口系统菜单总是在窗口的左上角打开。
当用户右键单击窗口的标题栏时,是否有一种以与Windows原生方式相同的方式以编程方式打开系统菜单?弹出菜单的API调用或消息?
我想在应用程序中保留系统菜单,因为我已在其中添加了项目“关于”和“设置”。 (此应用程序充当核心应用程序的独立启动器和更新程序。)
平台 WPF ,其中包含 Windows窗体库(由于使用SendWait()
的解决方法)。如果发布一些代码,请随意选择VB或C#。
答案 0 :(得分:3)
没有带烘焙的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; }
请注意,您可以在任何地方显示菜单,我只是选择了窗口的左上角。请注意位置值以像素为单位。