I have a borderless splash screen form displaying loading progress and containing Minimize and Close buttons (something similar to splash screens seen in Office 2013). I would also like to provide system menu of the window which opens on right click anywhere in the form.
Currently I'm achieving opening the menu by sending keys Alt+Space.
System.Windows.Forms.SendKeys.SendWait("% ") 'sending Alt+Space
With this approach, window system menu always opens in top-left corner of the window.
Is there a way to programatically open the system menu the same way as Windows does natively when user right-clicks title bar of the window? An API call or message which pops up the menu open?
I would like to keep the system menu available in the app because I have added also items "About" and "Settings" in there. (This app serves as an independent launcher and updater of the core app.)
The platform is WPF with Windows Forms library included, too (due to that workaround using SendWait()
). Feel free to choose VB or C# in case of posting some code.
Those who prefer to use a keyboard shortcut to bring up right-click context menu can hold down the SHIFT key and then press F10. But using the SHIFT + F10 keyboard shortcut is not much fast when you need to access the right-click menu frequently.
Navigate to the bottom of the Action Center and then click or tap on Tablet Mode. It is a two – way toggle between ON and OFF, so do it according to your preference. Once done, test to see if the right-click now works.
There is no baked-in winapi function to display the system menu. You can display it yourself by using pinvoke. The GetSystemMenu() function returns a handle to the system menu, you display it by using TrackPopupMenu(), you execute the selected command by calling SendMessage to send the WM_SYSCOMMAND.
Some sample code that shows how to do this and includes the necessary declarations:
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; }
Note that you can display the menu anywhere you want, I just picked the upper-left corner of the window. Beware that the position values are in pixels.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With