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

问题描述 投票:0回答:1

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

我尝试过使用这篇文章,但调用该函数后什么也没发生,我现在不知所措,我找不到更多关于此的资源。

c# winforms winapi
1个回答
3
投票

Form
的边框样式设置为
FormBorderStyle.None
时,
GetSystemMenu()
始终返回
NULL
句柄。

因为当您将边框样式设置为

HWND
时,您从
None
中删除了一些重要的窗口样式,因此此函数不会返回
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 PostMessage(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);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.