In this article you will learn - How to use LoadLibraryEx and FreeLibrary APIs to load/unload Dll/Exe resources - How to use LoadMenuIndirect API to load menu from memory buffer - How to use LoadMenu API to load menu stored in DLL or Exe resource - How to use TrackPopupMenu to display popup menu anywhere on the screen
Before we implement actual code lets take a look how to create menu resource file.
Visual Basic resource file editor does not support resource menu so we have to create script (*.rc)and then we can compile it using RC.exe which is generally located at \VB98\Wizards
Step-By-Step Example
- Create a standard exe project - Add two commandbuttons and two textbox on the form1 - For demo purpose create the following Resource Script file
Menu.rc |
Click here to copy the following block | #defineMFS_DEFAULT0x1000L#defineMFT_SEPARATOR0x800L#defineMFT_STRING0L#defineRESMNU_Pop1100#defineRESMNU_Pop2101Note:popupscanbepartofsingleMENUoreachintheirownDonotassignmenuitemresultitem0sinceitsalsoreturnedwhennoselectionismade.RESMNU_Pop1MENUDiscardableBeginPOPUPFileemptyisOkBeginMENUITEMOpen1MENUITEMNew2POPUPViewBeginMENUITEMZoomIn3CHECKEDMENUITEMZoomOut4MENUITEMFullScreen5GRAYEDEndMENUITEMSEPARATORMENUITEMClose6EndPOPUPEditBeginMENUITEMSmall1MENUITEMMedium2MENUITEMLarge3EndEn |
- Now next step is compile Menu.rc using the following command which will create Menu.res file which you can add into your Visual Basic project |
Note: You might need to set path for the \VB98\Wizards directory to use RC command without using full path
- Once you compile the Menu.rc file you should see Menu.res file in the same folder - Add the following code in form1 |
Click here to copy the following block | Private Const RT_MENU = 4&
Private Declare Function FreeLibrary Lib "kernel32" ( _ ByVal hLibModule As Long) As Long
Private Declare Function LoadLibraryEx Lib "kernel32" Alias "LoadLibraryExA" ( _ ByVal lpLibFileName As String, _ ByVal hFile As Long, _ ByVal dwFlags As Long) As Long
Private Declare Function ClientToScreen Lib "user32" ( _ ByVal hwnd As Long, _ lpPoint As POINTAPI) As Long
Private Declare Function DestroyMenu Lib "user32" ( _ ByVal hMenu As Long) As Long
Private Declare Function LoadMenu Lib "user32" Alias "LoadMenuA" ( _ ByVal hInstance As Long, _ ByVal lpString As String) As Long
Private Declare Function LoadMenuFromBuffer Lib "user32" Alias "LoadMenuIndirectA" ( _ lpBuffer As Byte) As Long
Private Declare Function GetSubMenu Lib "user32" ( _ ByVal hMenu As Long, _ ByVal nPos As Long) As Long
Private Declare Function TrackPopupMenu Lib "user32" ( _ ByVal hMenu As Long, _ ByVal wFlags As Long, _ ByVal X As Long, _ ByVal Y As Long, _ ByVal nReserved As Long, _ ByVal hwnd As Long, _ ByVal lprc As Long) As Long
Private Const MF_SEPARATOR = &H800& Private Const MF_STRING = &H0&
Private Const TPM_NONOTIFY = &H80& Private Const TPM_RETURNCMD = &H100& Private Const TPM_LEFTBUTTON = &H0& Private Const TPM_RIGHTBUTTON = &H2&
Private Const DONT_RESOLVE_DLL_REFERENCES = &H1 Private Const LOAD_LIBRARY_AS_DATAFILE = &H2
Private Const RESMNU_Pop1 = 100
Private Type POINTAPI X As Long Y As Long End Type
Private Sub Command1_Click()
Dim Buffer() As Byte Dim hMenu As Long, hPop As Long, Ret As Long, nPopUp As Integer Dim PT As POINTAPI
Me.ScaleMode = vbPixels PT.X = Me.ScaleWidth / 3 PT.Y = Me.ScaleHeight / 3 ClientToScreen Me.hwnd, PT
nPopUp = 0
Buffer = LoadResData(RESMNU_Pop1, RT_MENU) hMenu = LoadMenuFromBuffer(Buffer(0))
If hMenu Then hPop = GetSubMenu(hMenu, nPopUp) If hPop Then Ret = TrackPopupMenu(hPop, TPM_RETURNCMD, PT.X, PT.Y, 0, Me.hwnd, 0) MsgBox "Clicked on Item ID#" & Ret DestroyMenu hPop End If DestroyMenu hMenu End If End Sub
Private Sub Command2_Click() Dim hModule As Long, hMenu As Long, hPop As Long, Ret As Long, nPopUp As Integer Dim PT As POINTAPI
hModule = LoadLibraryEx(Text1, 0, LOAD_LIBRARY_AS_DATAFILE)
Me.ScaleMode = vbPixels PT.X = Me.ScaleWidth / 4 PT.Y = Me.ScaleHeight / 3 ClientToScreen Me.hwnd, PT
nPopUp = 0
hMenu = LoadMenu(hModule, Text2)
If hMenu Then hPop = GetSubMenu(hMenu, nPopUp) If hPop Then Ret = TrackPopupMenu(hPop, TPM_RETURNCMD, PT.X, PT.Y, 0, Me.hwnd, 0) MsgBox "Clicked on Item ID#" & Ret DestroyMenu hPop End If DestroyMenu hMenu End If
If hModule > 0 Then FreeLibrary hModule End Sub
Private Sub Form_Load() Command1.Caption = "Load Menu From Buffer" Command2.Caption = "Load Menu From Library" Text1.Text = "shell32.dll" Text2.Text = "#215" End Sub |
- Press F5 to run the project |
|