【问题标题】:Adding an entry to the System Menu (Left-Upper-Corner Icon Menu) in WinForms?在 WinForms 的系统菜单(左上角图标菜单)中添加一个条目?
【发布时间】:2009-08-05 19:31:17
【问题描述】:

我有一个 WinForms 应用程序,我想在菜单中添加一个菜单项,当用户单击窗口左上角(图标)或按 ALT+SPACE 时打开该菜单项。

Form 只显示一个 MainMenu 和一个 ContextMenu,但没有显示 SystemMenu 或类似的东西。有没有一种简单的方法可以在 WinForms 应用上进行修改?

我想添加一个简单的“关于”条目,供人们从应用程序中检查版本和 URL。在通常的 UI 中没有好地方(没有主菜单)。

【问题讨论】:

标签: .net winforms systemmenu


【解决方案1】:

当您将 FormBorderStyle 设置为“无”以外的任何内容时,此菜单会添加到表单中。当窗体边框样式改变时,调用一个名为 AdjustSystemMenu 的例程。此例程使用 GetSystemMenu 方法来检索 SystemMenu?从某处。 “某处”是问题所在。似乎在任何地方都没有可以访问的 SystemMenu 对象。

编辑: 刚刚找到这个link,看起来它可以满足你的需求。

public partial class Form1 : Form
{
    #region Win32 API Stuff

    // Define the Win32 API methods we are going to use
    [DllImport("user32.dll")]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

    [DllImport("user32.dll")]
    private static extern bool InsertMenu(IntPtr hMenu, Int32 wPosition, Int32 wFlags, Int32 wIDNewItem, string lpNewItem);

    /// Define our Constants we will use
    public const Int32 WM_SYSCOMMAND = 0x112;
    public const Int32 MF_SEPARATOR = 0x800;
    public const Int32 MF_BYPOSITION = 0x400;
    public const Int32 MF_STRING = 0x0;

    #endregion

    // The constants we'll use to identify our custom system menu items
    public const Int32 _SettingsSysMenuID = 1000;
    public const Int32 _AboutSysMenuID = 1001;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        /// Get the Handle for the Forms System Menu
        IntPtr systemMenuHandle = GetSystemMenu(this.Handle, false);

        /// Create our new System Menu items just before the Close menu item
        InsertMenu(systemMenuHandle, 5, MF_BYPOSITION | MF_SEPARATOR, 0, string.Empty); // <-- Add a menu seperator
        InsertMenu(systemMenuHandle, 6, MF_BYPOSITION, _SettingsSysMenuID, "Settings...");
        InsertMenu(systemMenuHandle, 7, MF_BYPOSITION, _AboutSysMenuID, "About...");
    }

    protected override void WndProc(ref Message m)
    {
        // Check if a System Command has been executed
        if (m.Msg == WM_SYSCOMMAND)
        {
            // Execute the appropriate code for the System Menu item that was clicked
            switch (m.WParam.ToInt32())
            {
                case _SettingsSysMenuID:
                    MessageBox.Show("\"Settings\" was clicked");
                    break;
                case _AboutSysMenuID:
                    MessageBox.Show("\"About\" was clicked");
                    break;
            }
        }

        base.WndProc(ref m);
    }
}

【讨论】:

  • 谢谢,GetSystemMenu 是我找不到的那个位,因为我不知道它叫什么。
【解决方案2】:

有一组 Windows API 函数可以获取和操作该菜单。

对于 C#,请查看以下示例:

http://www.codeguru.com/csharp/csharp/cs_misc/userinterface/article.php/c9327

【讨论】:

  • 谢谢!那篇文章有帮助。我接受 Stewbob 的文章,因为它列出了功能(并且使用 GetSystemMenu 我同时找到了同一篇文章:))
【解决方案3】:

AFAIK 没有 .Net 方法可以做到这一点。

要使您能够做到这一点,您必须使用 Windows API,我建议您查看 WinMain 和 WndProc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多