I have a Form with the FormBorderStyle set to None, and I have also made my own little GUI replacing the Title Bar, I'm trying to find a way to show the Menu that shows up whenever you right click the title bar or click the icon on the title bar
I have tried using this post but after calling the function nothing happened, I'm at a loss now and I cannot find more resources about this.
CodePudding user response:
When the border style of Form
is set to FormBorderStyle.None
, GetSystemMenu()
always returns a NULL
handle.
Because you remove some important Window Styles from HWND
when you set the border style to None
, this function doesn't return a HMENU
.
Probably, it does some checks if the window has a title bar or not. This is why it returns NULL
.
The workaround for the issue is to get the menu handle before setting the FoormBorderStyle
to None
.
using System.Runtime.InteropServices;
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern int TrackPopupMenu(IntPtr hMenu, uint uFlags, int x, int y,
int nReserved, IntPtr hWnd, IntPtr prcRect);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
private IntPtr hMenu;
private const int WM_SYSCOMMAND = 0x112;
protected override void OnHandleCreated(EventArgs e)
{
// Get the system menu and set the border style after that.
hMenu = GetSystemMenu(Handle, false);
FormBorderStyle = FormBorderStyle.None;
}
protected override void onm ouseUp(MouseEventArgs e)
{
int menuIdentifier = TrackPopupMenu(hMenu, 0x102, Control.MousePosition.X, Control.MousePosition.Y, 0, Handle, IntPtr.Zero);
if(menuIdentifier != 0)
{
SendMessage(Handle, WM_SYSCOMMAND, (IntPtr)menuIdentifier, IntPtr.Zero);
}
}
}