winforms FormBorderStyle为None时如何以编程方式显示窗口的系统菜单?

thigvfpy  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(189)

我有一个FormBorderStyle设置为None的窗体,并且我还制作了自己的小GUI来代替标题栏,我正在尝试找到一种方法来显示菜单,每当右键单击标题栏或单击标题栏上的图标时,就会显示该菜单

我试过使用this post,但是在调用函数后没有任何React,我现在不知所措,我找不到更多关于这个的资源。

ghhaqwfi

ghhaqwfi1#

Form的边框样式设置为FormBorderStyle.None时,GetSystemMenu()始终返回NULL句柄。
因为在将边框样式设置为None时,从HWND中删除了一些重要的窗口样式,所以此函数不会返回HMENU
它可能会检查窗口是否有标题栏,这就是为什么它返回NULL
此问题的解决方法是在将FoormBorderStyle设置为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 OnMouseUp(MouseEventArgs e)
    {
        int menuIdentifier = TrackPopupMenu(hMenu, 0x102, Control.MousePosition.X, Control.MousePosition.Y, 0, Handle, IntPtr.Zero);
        if(menuIdentifier != 0)
        {
            PostMessage(Handle, WM_SYSCOMMAND, (IntPtr)menuIdentifier, IntPtr.Zero);
        }
    }
}

相关问题