VB .NET/WinForms: 通过从仅资源 DLL 加载菜单来创建窗体的 MainMenu





5.00/5 (10投票s)
通过 API 函数从仅资源 DLL(由 VC++ 创建)加载菜单,并将其设置为窗体的 MainMenu。
引言
为什么我们需要从仅资源 DLL 加载菜单?
资源菜单可以在多个应用程序中共享。
使用仅资源 DLL 通过资源 ID 从该 DLL 加载菜单。
您需要首先了解如何创建仅资源 DLL,以制作您自己的资源 DLL 和资源菜单。
- 创建仅资源 DLL 项目后创建资源菜单
- 通过右键单击“项目”选择添加->资源菜单项。
- 从添加资源对话框中选择菜单资源类型,然后单击新建按钮。
- 修改您的新建资源菜单
- 通过右键单击“项目”选择添加->资源菜单项。
背景
使用 API 函数
- 使用
LoadLibrary
API 函数加载资源 DLL。Private Declare Function LoadLibrary Lib "kernel32" _ Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
- 使用 LoadMenu API 函数加载资源 菜单。
Private Declare Function LoadMenu Lib "user32" Alias "LoadMenuA" ( ByVal hInstance As Long, ByVal lpString As String) As Long
- 使用
SetMenu
API 函数设置Form
的MainMenu
。Public Declare Function SetMenu Lib "user32" ( ByVal hwnd As Long, ByVal hMenu As Long) As Boolean
- 创建
Select
和Click
事件,并通过Form
的WndProc
可重写方法为这些资源MenuItem
触发事件Protected Overrides Sub WndProc(ByRef m As Message) Static MenuID As Long = 0 If (m.Msg = WM_MENUSELECT) And m.LParam <> hMenu Then If CBool(m.LParam) Then MenuID = m.WParam.ToInt64 And &HFFFF& RaiseEvent MenuItemSelected(MenuID) Else If MenuID > 0 Then RaiseEvent MenuItemClicked(MenuID) MenuID = 0 End If End If ElseIf m.Msg = WM_MENUSELECT Then MenuID = 0 End If MyBase.WndProc(m) End Sub
- 当
form
关闭时,使用FreeLibrary
API 函数。Private Declare Function FreeLibrary Lib "kernel32.dll" ( ByVal hLibModule As Long) As Boolean
Using the Code
您需要在窗体常规声明部分定义上述 API 函数,以及这两个变量:hMenu
和 hInstance
。
Dim hMenu As Long
Dim hInstance As Long
并且还需要将创建的仅资源 DLL 复制到根(启动
)应用程序目录中
然后使用 LoadLibrary
API 函数加载该资源 DLL,以在 Form Load
事件中设置 hInstance
常规变量
hInstance = LoadLibrary("Resources")
并且还通过资源 ID 使用 LoadMenu
API 函数调用资源 菜单,以设置 hMenu
常规变量
hMenu = LoadMenu(hInstance, "#101")
最后,使用 SetMenu API 函数通过资源 菜单创建 Form
MainMenu
Me.Text = SetMenu(Me.Handle.ToInt64, hMenu)
引用Private Sub ResourceMenu_Load(sender As Object, e As EventArgs) Handles Me.Load hInstance = LoadLibrary("Resources") hMenu = LoadMenu(hInstance, "#101") Me.Text = SetMenu(Me.Handle.ToInt64, hMenu) End Sub
要了解用户何时选择菜单项或点击了菜单项,需要使用窗体的 WndProc
方法
- 在窗体常规声明部分定义此常量
Public Const WM_MENUSELECT = &H11F
- 为选择和点击资源菜单项创建事件
Event MenuItemSelected(ID As Integer) Event MenuItemClicked(ID As Integer)
- 键入 Overrides 关键字并按空格键选择
WndProc
方法 - 并在该方法中使用以下语句
Protected Overrides Sub WndProc(ByRef m As Message) Static MenuID As Long = 0 If (m.Msg = WM_MENUSELECT) And m.LParam <> hMenu Then If CBool(m.LParam) Then MenuID = m.WParam.ToInt64 And &HFFFF& RaiseEvent MenuItemSelected(MenuID) Else If MenuID > 0 Then RaiseEvent MenuItemClicked(MenuID) MenuID = 0 End If End If ElseIf m.Msg = WM_MENUSELECT Then MenuID = 0 End If MyBase.WndProc(m) End Sub
但是要通过单击每个 MenuItem
来编写和调用您的命令,您需要知道 MenuItem ID
转到仅资源 DLL 项目并双击 Resources.rc 以查看资源并选择创建的资源菜单,右键单击并选择资源符号 菜单项
并在 MenuItemClicked
事件过程中使用您想要的每个语句和任何 ID
Private Sub ResourceMenu_MenuItemClicked(ID As Integer) Handles Me.MenuItemClicked
Select Case ID
Case 40001 'New
Case 40002 'Open
Case 40003 'Import
Case 40004 'Export
Case 40005 'Exit
Application.Exit()
End Select
End Sub
在窗体关闭事件中使用 FreeLibrary
API 函数以释放加载的动态链接库 (DLL) 模块
Private Sub ResourceMenu_Closed(sender As Object, e As EventArgs) Handles Me.Closed
FreeLibrary(hInstance)
End Sub
历史
- 2022 年 12 月 15 日:初始版本