1. Herfried K. Wagner’s VB.Any
  2. .NET
  3. Frequently Asked Questions

Aligning a menu item on the right edge of a menu bar

Aligning a menu item on the right edge of a menu bar
<URL:https://dotnet.currifex.org/dotnet/faqs/rightalignmenuitem/en/>
----------------------------------------------------------------------------

Aligning a menu item on the right edge of a menu bar

In Windows 3.11 times, some applications had a right-aligned "Help" menu.
Providing right-aligned menus does not conform with current Windows UI
standards, but there may be some special cases where right-aligned menus
are useful.  The figure below shows a window with a menu bar that contains
a "Help" menu that is aligned at the right edge of the menu:

    +---------------------------------------+
    | % MyTool                        _  X |
    +---------------------------------------+
    | File  Edit                       Help |
    +---------------------------------------+
    |                                       |

The 'RightAlignMenuItem' method defined below expects the top-level menu
item that should be right-aligned and will return 'True' if changing the
alignment is successful:

\\\
Imports System.Runtime.InteropServices
.
.
.
Private Declare Auto Function GetMenu Lib "user32.dll" ( _
    ByVal hWnd As IntPtr _
) As IntPtr

Private Declare Auto Function SetMenuItemInfo Lib "user32.dll" ( _
    ByVal hMenu As IntPtr, _
    ByVal uItem As Int32, _
    ByVal fByPosition As Boolean, _
    ByRef lpmii As MENUITEMINFO _
) As Int32

Private Declare Auto Function GetMenuItemInfo Lib "user32.dll" ( _
    ByVal hMenu As IntPtr, _
    ByVal uItem As Int32, _
    ByVal fByPosition As Boolean, _
    ByRef lpmii As MENUITEMINFO _
) As Int32

Private Declare Auto Function DrawMenuBar Lib "user32.dll" ( _
    ByVal hWnd As IntPtr _
) As Boolean

<StructLayout(LayoutKind.Sequential)> _
Private Structure MENUITEMINFO
    Public cbSize As Int32
    Public fMask As Int32
    Public fType As Int32
    Public fState As Int32
    Public wID As Int32
    Public hSubMenu As IntPtr
    Public hbmpChecked As IntPtr
    Public hbmpUnchecked As IntPtr
    Public dwItemData As IntPtr
    <MarshalAs(UnmanagedType.LPTStr)> Public dwTypeData As String
    Public cch As Int32
    Public hbmpItem As IntPtr
End Structure

Private Const MF_STRING As Int32 = &H0
Private Const MF_HELP As Int32 = &H4000

Private Const MFS_DEFAULT As Int32 = &H1000

Private Const MIIM_ID As Int32 = &H2
Private Const MIIM_SUBMENU As Int32 = &H4
Private Const MIIM_TYPE As Int32 = &H10
Private Const MIIM_DATA As Int32 = &H20

Private Function RightAlignMenuItem( _
    ByVal TopLevelMenuItem As MenuItem _
) As Boolean
    Dim hMenu As IntPtr = GetMenu(Me.Handle)
    Dim mii As MENUITEMINFO
    With mii
        .cbSize = Marshal.SizeOf(mii)
        .dwTypeData = StrDup(80, ControlChars.NullChar)
        .fType = MF_STRING
        .cch = Len(mii.dwTypeData)
        .fState = MFS_DEFAULT
        .fMask = MIIM_ID Or MIIM_DATA Or MIIM_TYPE Or MIIM_SUBMENU
    End With
    If GetMenuItemInfo(hMenu, TopLevelMenuItem.Index, -1, mii) = 0 Then
        Return False
    Else
        mii.fType = mii.fType Or MF_HELP
        If _
            SetMenuItemInfo(hMenu, TopLevelMenuItem.Index, True, mii) = 0 _
        Then
            Return False
        End If
    End If
    If Not DrawMenuBar(Me.Handle) Then
        Return False
    End If
    Return True
End Function
///

Usage:

\\\
Debug.Assert(RightAlignMenuItem(Me.MainMenu1.MenuItems(2)))
///