并列(多列)菜单的问题,菜单像浏览器的收藏夹菜单一样,并列起来
msdn上有个vb的例子,我操作了一下,的确可以实现,但是在bcb中,死活没有效果,请问,有什么办法移植过来吗?
如何在 Visual Basic 中使用 WIN32 API 创建多列菜单
按步骤示例的步骤
打开一个新的标准 EXE 项目。默认情况下创建 Form1。
向 Form1 中添加命令按钮。
在工具菜单上单击菜单编辑器。创建包含至少两个包含至少四个子菜单项每个的最上层菜单的菜单。
将 下面的代码添加到 Form1 的通用声明部分中:
Option Explicit
Private Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type
Private Const MF_MENUBARBREAK = &H20& ' columns with a separator line
Private Const MF_MENUBREAK = &H40& ' columns w/o a separator line
Private Const MF_STRING = &H0&
Private Const MF_HELP = &H4000&
Private Const MFS_DEFAULT = &H1000&
Private Const MIIM_ID = &H2
Private Const MIIM_SUBMENU = &H4
Private Const MIIM_TYPE = &H10
Private Const MIIM_DATA = &H20
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemInfo Lib "user32" _
Alias "GetMenuItemInfoA" _
(ByVal hMenu As Long, ByVal un As Long, ByVal B As Boolean, _
lpMenuItemInfo As MENUITEMINFO) As Long
Private Declare Function SetMenuItemInfo Lib "user32" _
Alias "SetMenuItemInfoA" _
(ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, _
lpcMenuItemInfo As MENUITEMINFO) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) _
As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, _
ByVal nPos As Long) As Long
Private Sub Command1_Click()
' Splitting a menu here demonstrates that this can be done dynamically.
Dim mnuItemInfo As MENUITEMINFO, hMenu As Long, hSubMenu As Long
Dim BuffStr As String * 80 ' Define as largest possible menu text.
hMenu = GetMenu(Me.hwnd) ' retrieve menu handle.
BuffStr = Space(80)
With mnuItemInfo ' Initialize the UDT.
.cbSize = Len(mnuItemInfo) ' 44
.dwTypeData = BuffStr & Chr(0)
.fType = MF_STRING
.cch = Len(mnuItemInfo.dwTypeData) ' 80
.fState = MFS_DEFAULT
.fMask = MIIM_ID Or MIIM_DATA Or MIIM_TYPE Or MIIM_SUBMENU
End With
' Use item break point position for the '3' below (zero-based list).
hSubMenu = GetSubMenu(hMenu, 0)
If GetMenuItemInfo(hSubMenu, 2, True, mnuItemInfo) = 0 Then
MsgBox "GetMenuItemInfo failed. Error: " & Err.LastDllError, , _
"Error"
Else
mnuItemInfo.fType = mnuItemInfo.fType Or MF_MENUBARBREAK
If SetMenuItemInfo(hSubMenu, 2, True, mnuItemInfo) = 0 Then
MsgBox "SetMenuItemInfo failed. Error: " & Err.LastDllError, , _
"Error"
End If
End If
DrawMenuBar (Me.hwnd) ' Repaint top level Menu.
End Sub
Private Sub Form_Load()
' This works for either an API-created menu or a native VB Menu.
Dim mnuItemInfo As MENUITEMINFO, hMenu As Long, hSubMenu As Long
Dim BuffStr As String * 80 ' Define as largest possible menu text.
hMenu = GetMenu(Me.hwnd) ' Retrieve menu handle.
BuffStr = Space(80)
With mnuItemInfo ' Initialize the UDT
.cbSize = Len(mnuItemInfo) ' 44
.dwTypeData = BuffStr & Chr(0)
.fType = MF_STRING
.cch = Len(mnuItemInfo.dwTypeData) ' 80
.fState = MFS_DEFAULT
.fMask = MIIM_ID Or MIIM_DATA Or MIIM_TYPE Or MIIM_SUBMENU
End With
' Use item break point position for the '3' below (zero-based list).
hSubMenu = GetSubMenu(hMenu, 1)
If GetMenuItemInfo(hSubMenu, 2, True, mnuItemInfo) = 0 Then
MsgBox "GetMenuItemInfo failed. Error: " & Err.LastDllError, , _
"Error"
Else
mnuItemInfo.fType = mnuItemInfo.fType Or MF_MENUBREAK
If SetMenuItemInfo(hSubMenu, 2, True, mnuItemInfo) = 0 Then
MsgBox "SetMenuItemInfo failed. Error: " & Err.LastDllError, , _
"Error"
End If
End If
DrawMenuBar (Me.hwnd) ' Repaint top level Menu.
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbRightButton Then
PopupMenu Aaa ' Use the name of one of your menus.
End If
End Sub
"aaa"在上面最后一个过程中更改为其中一个最上层菜单的名称。
运 行该项目,然后单击菜单项上的。
结果: 按通常的方式删除垂直向下的第一个菜单,但第二个具有两列。此外,用鼠标右键单击窗体,第一项会作为一个正常的弹出式菜单。然后单击命令按钮,然后重试这 些测试。现在在第一个菜单项和弹出窗口必须与它们之间的分隔线的两个列。如果要动态地划分列您可以使用 API 函数 GetMenuItemCount 获取的项的数目和然后循环访问它们。您可以搜索特定字符串以确定断点或您只是可以断开每个 X 项。
#Visual Basic Vb
[解决办法]
在C++Builder中实现这个效果很容易的。在菜单设计器的界面上,选中要作为分隔的菜单项(MenuItem),然后设置其Break属性即可。
mbNone: 无分隔效果
mbBreak: 没有线的分隔效果
mbBarBreak: 有线的分隔效果
自己试试就知道了。