Page 1 of 1

WH_SHELL-Hook

Posted: Thu Oct 21, 2004 6:44 am
by Kiffi
Hello @all,

i try to hook the SH_SHELL-Events to determine that a window will be
opened (created) and closed (destroyed). But with this code i get the
messages at the wrong time.

For example: I open a window (in my code nothing happens) and close it
(i get 3(!) Create-Messages). When i move my mouepointer over the
captionbar of my window, i get Destroy-Messages.

Who can help?

Thanks in advance ... Kiffi

Code: Select all

#HookDll = 1

myHook.l

Procedure HookProc(Hooked) 

  Shared myHook           
  
  If Hooked = 1
    myDLL.l = OpenLibrary(#HookDll,"hook.dll")
    myDLLFunction.l = IsFunction(#HookDll,"ShellHook")
    myHook = SetWindowsHookEx_(#WH_SHELL, myDLLFunction, myDLL, 0)
  Else
    UnhookWindowsHookEx_(myHook)
    myHook =0
  EndIf

EndProcedure 

Procedure WindowCallback(WindowID.l, Message.l, wParam.l, lParam.l)

  Shared myHook           

  If myHook > 0

    Select wParam
  
      Case #HSHELL_WINDOWCREATED:        Debug "WINDOWCREATED:   " + Str(WindowID) + " | " + Str(Message) + " | " + Str(wParam) + " | " + Str(lParam)
      Case #HSHELL_WINDOWDESTROYED:      Debug "WINDOWDESTROYED: " + Str(WindowID) + " | " + Str(Message) + " | " + Str(wParam) + " | " + Str(lParam)

    EndSelect

  EndIf

  ProcedureReturn #PB_ProcessPureBasicEvents 

EndProcedure 

OpenWindow(0,250,250,250,250,#PB_Window_SystemMenu,"ShellHookTest")
CreateGadgetList(WindowID())
ButtonGadget(1,10,10,150,30,"Enable Hook")

SetWindowCallback(@WindowCallback())

Repeat

  EventID =  WaitWindowEvent() 
  
  Select EventID

    Case #PB_EventGadget
      If EventGadgetID() = 1
        If GetGadgetText(1)="Disable Hook"
          SetGadgetText(1,"Enable Hook")
          HookProc(0)
        Else
          SetGadgetText(1,"Disable Hook")
          HookProc(1)
        EndIf         
      EndIf

  EndSelect
      
Until EventID = #PB_EventCloseWindow

HookProc(0)

End
and here is my Hook-DLL:

Code: Select all

ProcedureDLL ShellHook(nCode.l, wParam.l, lParam.l) 

  If nCode<0
    ProcedureReturn CallNextHookEx_(@ShellHook, nCode, wParam, lParam)
  EndIf

  If wParam = #HSHELL_WINDOWCREATED Or wParam = #HSHELL_WINDOWDESTROYED 
    WindowName.s = "ShellHookTest"
    ID = FindWindow_(#Null,@WindowName)
    PostMessage_(ID, nCode, wParam, lParam)
  EndIf

  ProcedureReturn CallNextHookEx_(@ShellHook, nCode, wParam, lParam)

EndProcedure 

Posted: Thu Oct 21, 2004 5:00 pm
by Sparkie
See if this works better for you. Changes to code appear just below the commented lines.
Main Code: 3 changes in code

Code: Select all

#HookDll = 1 
  
myHook.l 
Procedure HookProc(Hooked) 
      
Shared myHook            
      
  If Hooked = 1 
    myDLL.l = OpenLibrary(#HookDll,"hook.dll") 
    myDLLFunction.l = IsFunction(#HookDll,"ShellHook") 
    myHook = SetWindowsHookEx_(#WH_SHELL, myDLLFunction, myDLL, 0) 
  Else 
    UnhookWindowsHookEx_(myHook) 
     myHook =0 
  EndIf 
      
EndProcedure 

Procedure WindowCallback(WindowID.l, Message.l, wParam.l, lParam.l) 
      
Shared myHook
      
  If myHook > 0 
        
    ; --> Select wParam 
    Select Message    
      ; --> Case #HSHELL_WINDOWCREATED:        Debug "WINDOWCREATED:   " + Str(WindowID) + " | " + Str(Message) + " | " + Str(wParam) + " | " + Str(lParam) 
      Case #WM_USER + #HSHELL_WINDOWCREATED
        winTitle$ = Space(256)
        GetWindowText_(wParam, @winTitle$, 256)
        Debug "WINDOWCREATED:   " + Str(wParam) + " " + winTitle$
            
      ; --> Case #HSHELL_WINDOWDESTROYED:      Debug "WINDOWDESTROYED: " + Str(WindowID) + " | " + Str(Message) + " | " + Str(wParam) + " | " + Str(lParam) 
      Case #WM_USER + #HSHELL_WINDOWDESTROYED
        Debug "WINDOWDESTROYED: " + Str(wParam)
    EndSelect 
        
  EndIf 
      
ProcedureReturn #PB_ProcessPureBasicEvents 
 
EndProcedure 
    
OpenWindow(0,250,250,250,250,#PB_Window_SystemMenu,"ShellHookTest") 
CreateGadgetList(WindowID()) 
ButtonGadget(1,10,10,150,30,"Enable Hook") 
    
SetWindowCallback(@WindowCallback()) 
    
Repeat 
      
EventID =  WaitWindowEvent() 
      
  Select EventID 
        
    Case #PB_EventGadget 
      If EventGadgetID() = 1 
        If GetGadgetText(1)="Disable Hook" 
          SetGadgetText(1,"Enable Hook") 
          HookProc(0) 
        Else 
          SetGadgetText(1,"Disable Hook") 
          HookProc(1) 
        EndIf          
      EndIf 
          
    EndSelect 
      
Until EventID = #PB_EventCloseWindow 
    
HookProc(0) 
    
End
DLL Code: 4 changes in code.

Code: Select all

ProcedureDLL ShellHook(nCode.l, wParam.l, lParam.l) 
  Shared wintext$
  If nCode<0 
    ; --> ProcedureReturn CallNextHookEx_(@ShellHook, nCode, wParam, lParam) 
    ProcedureReturn CallNextHookEx_(@ShellHook(), nCode, wParam, lParam) 
  EndIf 
  
  ; --> If wParam = #HSHELL_WINDOWCREATED Or wParam = #HSHELL_WINDOWDESTROYED 
  If nCode = #HSHELL_WINDOWCREATED Or nCode = #HSHELL_WINDOWDESTROYED
    WindowName.s = "ShellHookTest" 
    ID = FindWindow_(#Null,@WindowName)
    ; --> PostMessage_(ID, nCode, wParam, lParam) 
    PostMessage_(ID, #WM_USER + nCode, wParam, lParam) 
  EndIf 
  
  
  ; --> ProcedureReturn CallNextHookEx_(@ShellHook, nCode, wParam, lParam)
  ProcedureReturn CallNextHookEx_(@ShellHook(), nCode, wParam, lParam) 
  
EndProcedure 

Posted: Sun Oct 24, 2004 11:11 am
by Kiffi
Sparkie wrote:See if this works better for you. [...]
It works! Thanks a lot! You save my life :)

Greetings ... Kiffi