here is a little tutorial
most of the code is based on the code wrote by daniel (msn fanatic)
wrote by Stigmata/jackasswanabe
http://www.plasticangels.com
jackasswanabe@gmail.com
please me and the world do not want a bunch loads of new addons comming at once
this is for information only
if you do include it in your program i would like my name in the credits thank you
firstly u need 1 form and 1 module.
and 2 .dll files which will be included in the zip attachment
add 1 lable to the form and in the form you will have this code
code:
Private Sub Form_Load()
Call SetCBTSHLHook(-1, AddressOf hookfind, 0)
form1.visible = false
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call SetCBTSHLHook(0, 0, 0)
Call SetCWPMSGHook(0, 0, 0)
End Sub
in the form load you are calling the hook to take place. by calling setcbtshlhook its telling the .dll to find the messenger window class.
also ive added to hide the form becuase there is no real point of seeing it
form unload it is unloaded everything that have taken place. the finding of the window and the hook itself.
then moving on to the module
code:
Option Explicit
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function AppendMenu Lib "user32.dll" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function CreatePopupMenu Lib "user32.dll" () As Long
Private Declare Function InsertMenu Lib "user32.dll" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function GetMenu Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Declare Function DrawMenuBar Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Const HCBT_CREATEWND As Long = 3
Private Const HCBT_DESTROYWND As Long = 4
Private Const MF_BYCOMMAND As Long = &H0&
Private Const MF_BYPOSITION As Long = &H400&
Private Const MF_POPUP As Long = &H10&
Private Const MF_STRING As Long = &H0&
Private Const WM_COMMAND As Long = &H111
basicly thats the api calls you need to make for the menu. normal nothing special about that. you have the mf_popup etc which are the flags for u to choose what type of menu you are using
also in the declerations you will need
code:
Public Declare Function SetCBTSHLHook Lib "dscbtshl" (ByVal Hook As Long, ByVal AdrCBT As Long, ByVal AdrSHL As Long) As Long
Public Declare Function SetCWPMSGHook Lib "dscwpmsg" (ByVal hWnd As Long, ByVal AdrCWP As Long, ByVal AdrMSG As Long) As Long
and
code:
Public Const Offset& = 2000
the 2 declare functions are declaring the .dll that are needed for the hook
and the const is saying the number which will be needed later to make a menu click do something.
the first function is hookfind
code:
Public Function hookfind(ByVal hWnd As Long, ByVal nCode As Long) As Long
Dim hHiddenWindowClass As Long
Dim sClassName As String
Dim lRetVal As Long
Dim lProcessId As Long
If Not nCode = HCBT_CREATEWND Then
If Not nCode = HCBT_DESTROYWND Then
Exit Function
End If
End If
sClassName = Space(256)
lRetVal = GetClassName(hWnd, sClassName, 256)
sClassName = Left$(sClassName, lRetVal)
lProcessId = GetWindowThreadProcessId(hWnd, 0)
If sClassName = "MSNHiddenWindowClass" Then
If nCode = HCBT_CREATEWND Then
Call OnMessengerStart(lProcessId, hWnd)
ElseIf nCode = HCBT_DESTROYWND Then
Call OnMessengerClose(lProcessId, hWnd)
End If
Exit Function
End If
'**********note rest does not work with polygamy***********
hHiddenWindowClass = FindWindow("MSNHiddenWindowClass", vbNullString)
'If an instance is open
If Not hHiddenWindowClass = 0 Then
If lProcessId = GetWindowThreadProcessId(hHiddenWindowClass, 0) Then
If nCode = HCBT_CREATEWND Then
Call OnWindowOpen(lProcessId, hWnd, sClassName)
ElseIf nCode = HCBT_DESTROYWND Then
Call OnWindowClose(lProcessId, hWnd, sClassName)
End If
End If
End If
End Function
thats basicly readable if u want to know whats happening.
its looking for msnhiddenwindowclass and when it finds it it places the menu hook on it
code:
Public Sub OnMessengerStart(ByRef r_lProcessId As Long, ByRef r_hHiddenWnd As Long)
Call SetCWPMSGHook(r_hHiddenWnd, 0, AddressOf hookmenu)
msgbox "messenger opened"
End Sub
Public Sub OnMessengerClose(ByRef r_lProcessId As Long, ByRef r_hHiddenWnd As Long)
msgbox "messenger closed"
End Sub
after finding the main window. the hookfind function calls 'onmessengerstart' which calls the menu hook
now here is the fun part, you decide what goes where
code:
Public Sub OnWindowOpen(ByRef r_lProcessId As Long, ByRef r_hWnd As Long, ByRef r_sClassName As String)
Dim hMenu As Long
Dim hSubMenu As Long
Select Case r_sClassName
Case "MSNMSBLClass"
msgbox "messenger main window opened"
Do
hMenu = GetMenu(r_hWnd)
Loop While hMenu = 0
hSubMenu = CreatePopupMenu
Call AppendMenu(hSubMenu, MF_STRING, Offset + 1, "&Open Log Files")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 2, "&Event Log Window")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 3, "&Lock Messenger")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 4, "S&cheduler...")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 5, "Contact &Manager...")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 6, "&Sounds Settings...")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 7, "&Preferences...")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 8, "&Help")
Call AppendMenu(hSubMenu, MF_STRING, Offset + 9, "&About")
Call AppendMenu(hMenu, MF_BYPOSITION Or MF_POPUP, hSubMenu, "&Plus")
Call DrawMenuBar(r_hWnd)
End Select
End Sub
**sorry patchou, coudlnt think of menu names
***
ok uve have got this far. now its searching for a class name (msnmsblclass <=== messenger main window classname)
now u are adding (call appendmenu) to the messenger main window in the form of a menu
lets have a look at the appendmenu
Call AppendMenu(hSubMenu, MF_STRING, Offset + 9, "&Plus")
hsubmenu = where to put it, you define hsubmenu earlyer in the sub as long
mf_string = you say what flag it is, eg string so it is used as a string
offset+# = the number of the menu, you see we are using the offset with we declared in the declerations
"&Plus" = the name of the Menu
, what text will appear. & underlines first work and will open with alt+that letter..(sorry n00b
)
also if u want to add a menu on the side, eg little arrow into another menu
after dim hsubmenu add dim hsubsubmenu, or something along those lines
then repeat at hsubmenu = createpopupmenu by putting after hsubsubmenu = createpopupmenu.
then in the call append menu put " call appendmenu(hsubmenu, MF_BYPOSITION Or MF_POPUP, hsubsubMenu, "SUBSUB menu name") "
then to insert into that menu put
"call appendmenu(hsubsubmenu, mf_string, offset + 10, "inside subsubmenu name") "
then like repeating code onmessengerclose
code:
Public Sub OnWindowClose(ByRef r_lProcessId As Long, ByRef r_hWnd As Long, ByRef r_sClassName As String)
Select Case r_sClassName
Case "MSNMSBLClass"
msgbox "main messenger window closed"
End Select
End Sub
now the bit that most coders dont have the return code
code:
Public Function hookmenu(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case wMsg
Case WM_COMMAND
Debug.Print wParam
If wParam = 2001 Then MsgBox " sorry cant open messenger chat logs......"
If wParam > Offset Then
Form1.Label1 = "SubMenu" & Trim$(wParam - Offset) & " was selected"
Beep
End If
End Select
End Function
wparam contains the menu id. where it says 2001. that is the offset plus the menu number.
for each menu item u have just do
if wparam = (2000 + your menu item number) then
so if ur menu item was 10, then it would be
wparam = 2010 then msgbox "you clicked item 10"