Load Dynamic Link Library Created by VC++ as Resource-Only DLL by 'LoadLibrary' API Function, load Menu from Resource DLL by 'LoadMenu' API Function, Set Resource Menu as MainMenu of the Form by 'SetMenu' API Function. Frees the loaded dynamic-link library (DLL) module by 'FreeLibrary' API Function.
Introduction
Why do we need to load Menu from Resource-only DLL?
Resource Menus can be shared in several applications.
Use a resource-only DLL to Load Menu from that by Resource ID.
You need to know how to Create a resource-only DLL at first to make your own resource DLL and also Resource Menu.
- After Make Resource-Only DLL Project to create Resource Menu:
- Choose Add->Resource Menu Item by Right-Click on the Project.
- Choose Menu Resource Type From Add Resource Dialog and Click on the New Button.
- Modify your New Resource Menu:
Background
Using API Functions:
- Load Resource DLL by
LoadLibrary
API Function.
Private Declare Function LoadLibrary Lib "kernel32" _
Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
- Load Resource Menu by LoadMenu API Function.
Private Declare Function LoadMenu Lib "user32" Alias "LoadMenuA" (
ByVal hInstance As Long,
ByVal lpString As String) As Long
- Use
SetMenu
API Function to set Form
's MainMenu
.
Public Declare Function SetMenu Lib "user32" (
ByVal hwnd As Long,
ByVal hMenu As Long) As Boolean
- Create
Select
and Click
Events and Raise those for Resource MenuItem
s by WndProc
overridable method of the Form
:
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
- Use
FreeLibrary
API Function, when form
is closing.
Private Declare Function FreeLibrary Lib "kernel32.dll" (
ByVal hLibModule As Long) As Boolean
Using the Code
You need to Define the above API Functions at Form General Declaration Section, and also these two variables: hMenu
and hInstance
.
Dim hMenu As Long
Dim hInstance As Long
And also needs to copy the Created Resource-Only DLL in the root(Startup
) Application Directory:
Then Load that Resource DLL by using LoadLibrary
API Function to set hInstance General Variable
at Form Load
Event:
hInstance = LoadLibrary("Resources")
And also call resource Menu by using LoadMenu
API Function via Resource ID to set hMenu
General Variable:
hMenu = LoadMenu(hInstance, "#101")
Finally, to create Form
MainMenu by Resource Menu using SetMenu API Function:
Me.Text = SetMenu(Me.Handle.ToInt64, hMenu)
Quote:
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
To know when user Select MenuItem or clicked need to use WndProc
method of the Form:
- Define this Constant at Form General Declaration Section:
Public Const WM_MENUSELECT = &H11F
- Create Events for Select and Click Resource MenuItems:
Event MenuItemSelected(ID As Integer)
Event MenuItemClicked(ID As Integer)
- Type Overrides Keyword and press Space key to choose
WndProc
Method:
- and use these below statements at this method:
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
But for Write and Invoke your Commands by clicking on each MenuItem
, you need to know MenuItem ID
s:
Go to Resource-Only DLL project and double-click on the Resources.rc to view Resources and Select Created Resource Menu, Right-click and choose Resource Symbols MenuItem
:
And use each statement you want with any ID at MenuItemClicked
Event Procedure:
Private Sub ResourceMenu_MenuItemClicked(ID As Integer) Handles Me.MenuItemClicked
Select Case ID
Case 40001
Case 40002
Case 40003
Case 40004
Case 40005
Application.Exit()
End Select
End Sub
Use FreeLibrary
API Function at Form Closed Event to free the loaded dynamic-link library (DLL) module:
Private Sub ResourceMenu_Closed(sender As Object, e As EventArgs) Handles Me.Closed
FreeLibrary(hInstance)
End Sub
History
- 15th December, 2022: Initial version