Skip to content

Tutorial

作者紫汐 edited this page Jul 18, 2025 · 2 revisions

1.Install

It is recommended to install it using the nuget package

屏幕截图 2025-07-18 112701

Open the nuget package manager for the corresponding project in your IDE, search for "Win32Menu", select it and install it

屏幕截图 2025-07-18 112948

If you are using vscode or other editors or ides that do not support the nuget package manager, please install it using the dotnet command. You can see the installation command on the nuget package website.

2.Using namespace

using Win32Menu; This project has only one namespace, "Win32Menu".

3.Usage example

If you can download this project, there are examples of two types of projects: "Win32MenuWinFormsDemo" and "Win32MenuWpfDemo".

The following is the specific usage process:

Create menu bar

// Please declare a field of type NativeMenu in your window class
NativeMenu menu;
// Instantiate the menu at the appropriate time.
menu = new NativeMenu()
{
    Uid = 888,
};

Create menu items

Every object in NativeMenu should have a unique Uid.

There are some configurable attributes on the menu, such as "Text", "Type", "Status", "Checked", "IsRadioCheck", and "RightJustify".

var file = new NativeMenu()
{
    Uid = 1,
    Text = "File"
};

var exit = new NativeMenu()
{
    Uid = 2,
    Text = "Exit"
}

exit.Click += (NativeMenu _, ref bool _) =>
{
    Close();
}; // Click events of the menu can be registered

file.AppendMenu(exit);
menu.AppendMenu(file,true); // The second parameter is set to true because this menu contains submenus

What is the use of clicking on the second parameter of the event?

It indicates whether synchronization is enabled. Synchronization refers to synchronizing the state of the menu item object to the state of the underlying hosted menu. If you change the status of a menu item and find no change, it's because you didn't set it to true.

If there is no status change involved, please do not modify it, especially when the window is closed. The menu behind it will also be destroyed, and at this time, synchronization will cause an exception!

Handle WndProc

If you want to use the Click event, you must take this step.

WinForm Project

protected override void WndProc(ref Message m)
{
    // If you use menu.SetupForSystemMenu(Handle); So, please change conditions to (int)WndProcMsgType.WmSystemCommand
    if (m.Msg is (int)WndProcMsgType.WmCommand)
    {
        if (menu is not null)
        {
            menu.ProcessWndProcParams(m.WParam)
        }
        
    }
        
    base.WndProc(ref m);
}

Wpf Project

// Call the following method at the appropriate time
var hs = PresentationSource.FromVisual(this) as HwndSource;
if (hs is null) throw new NullReferenceException(nameof(hs));
hs.AddHook(WndProc);

// Customize WndProc
private nint WndProc(nint hWnd, int msg, nint wParam, nint lParam, ref bool handled)
{
    // If you use menu.SetupForSystemMenu(Handle); So, please change conditions to (int)WndProcMsgType.WmSystemCommand
    if (msg is (int)WndProcMsgType.WmCommand) 
    {
        menu.ProcessWndProcParams(wParam);
    }

    return 0;
}

Setup menu

For a window

menu.SetMenu(Handle);

SetMenu should only be used on NativeMenu objects that serve as window menu bars.

For system menu

menu.SetupForSystemMenu(Handle);

Use menu.SetupForSystemMenu(Handle); With menu.SetMenu(Handle); They conflict with each other. Please do not try to mix them up, or strange problems will arise.

Remove menu

NativeMenu.SetNullMenu(Handle);

After providing the handle, the menu will be removed.

Please note that it is not destroyed. You can reuse it in the original way you set the menu.

Destroy menu

menu.Dispose()

Usually, there is no need to destroy it, unless you prefer to manage it independently.