This code should get you started:
Hook dll:
Code:
; This is the hook procedure. It must be compiled to a dll.
; Every process on which this hook is installed will load
; this dll and execute the procedure.
;
; Even though you also load this dll from the program that installes
; the hook, you have to keep in mind that this code is mostly excecuted
; inside a foreign process, not the one of your program.
;
; For this example, all the code does is catch a #WM_CREATE message
; and broadcast our own message, so the original program can read
; it. Usually, whatever task needs to be done can be done right here
; inside the procedure, so that extra message is not needed.
;
Global CreateMessage.l
ProcedureDLL AttachProcess(Instance)
CreateMessage = RegisterWindowMessage_("MyHook_Window_Created")
EndProcedure
; This is the hook procedure
; The parameters depend on what type of hook you install.
; This is a hook which is called before the window procedure of the
; process is called.
;
ProcedureDLL MyHookProcedure(nCode.l, wParam.l, *lParam.CWPSTRUCT)
; Just catch this one message.
If *lParam\message = #WM_CREATE
PostMessage_(#HWND_BROADCAST, CreateMessage, *lParam\hwnd, 0)
EndIf
; This is very important to allow multiple hooks to work side by side.
ProcedureReturn CallNextHookEx_(@MyHookProcedure(), nCode, wParam, *lParam)
EndProcedure
Program:
Code:
; This is the program that installes the hook.
; Note: it also needs to load the hook dll, even if it itself is not hooked.
; little gui stuff
Enumeration
#GADGET_List
#GADGET_Start
#GADGET_Stop
EndEnumeration
#Hook_Path = "b:\test.dll" ; the hook dll
#LIBRARY_Hook = 0 ; PB id for our dll.
If OpenWindow(0, 0, 0, 400, 400, #PB_Window_SystemMenu|#PB_Window_Screencentered, "Hook example")
If CreateGadgetList(WindowID())
ListViewGadget(#GADGET_List, 5, 5, 390, 365)
ButtonGadget(#GADGET_Start, 5, 375, 120, 20, "Install Hook")
ButtonGadget(#GADGET_Stop, 130, 375, 120, 20, "Remove Hook")
EndIf
DisableGadget(#GADGET_Stop, 1)
CreateMessage = RegisterWindowMessage_("MyHook_Window_Created")
Repeat
Event = WaitWindowEvent()
; here we received our create message..
;
If Event = CreateMessage
hwnd = EventwParam()
Name$ = Space(500)
GetWindowText_(hwnd, @Name$, 500)
AddGadgetItem(#GADGET_List, -1, "WM_CREATE: "+RSet(Hex(hwnd), 8, "0")+" -> "+Name$)
SetGadgetState(#GADGET_List, CountGadgetItems(#GADGET_List)-1)
ElseIf Event = #PB_EventCloseWindow
Quit = 1
ElseIf Event = #PB_EventGadget
Select EventGadgetID()
Case #GADGET_Start
; This code installes the hook.
If OpenLibrary(#LIBRARY_Hook, #Hook_Path)
dllInstance = LibraryID(#LIBRARY_Hook)
dllFunction = IsFunction(#LIBRARY_Hook, "MyHookProcedure")
; If you set the last parameter to a threadid, only this thread will get
; hooked. Like this, every thread is hooked.
HookID = SetWindowsHookEx_(#WH_CALLWNDPROC, dllFunction, dllInstance, #NULL)
If HookID
DisableGadget(#GADGET_Start, 1)
DisableGadget(#GADGET_Stop, 0)
AddGadgetItem(#GADGET_List, -1, "=====> Hook installed")
SetGadgetState(#GADGET_List, CountGadgetItems(#GADGET_List)-1)
EndIf
EndIf
Case #GADGET_Stop
; This removes the hook.. quite simple.
If HookID
UnhookWindowsHookEx_(HookID)
CloseLibrary(#LIBRARY_Hook)
DisableGadget(#GADGET_Start, 0)
DisableGadget(#GADGET_Stop, 1)
AddGadgetItem(#GADGET_List, -1, "=====> Hook removed")
SetGadgetState(#GADGET_List, CountGadgetItems(#GADGET_List)-1)
HookID = 0
EndIf
EndSelect
EndIf
Until Quit
EndIf
; unhook if not allready done.
If HookID
UnhookWindowsHookEx_(HookID)
CloseLibrary(#LIBRARY_Hook)
EndIf
End
For your calculator problem, this should work well, because #WM_CREATE
is send after the window is created, but before it is displayed.
So if you move it from inside the hook procedure, it should work, and also
look good
