Page 1 of 1

Class Hook

Posted: Sat Jul 27, 2013 2:39 pm
by Josh
I'm trying to subclass all gadgets from the same class. What's wrong with the following code?

Code: Select all

Procedure Hook(hWnd, uMsg, wParam, lParam)
  Debug "HOOK"
EndProcedure

OpenWindow   (0, 0, 0, 200, 100, "Testfenster", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget (0, 10, 10, 80, 25, "Test")

SetClassLongPtr_(GadgetID(0), #GCL_WNDPROC, @Hook())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Class Hook

Posted: Thu Aug 08, 2013 10:26 pm
by tinman
According to MSDN:
Calling SetClassLongPtr with the GCLP_WNDPROC index creates a subclass of the window class that affects all windows subsequently created with the class.
So it looks like you need to apply your hook and then create the gadget. Or possibly create a dummy gadget so you can get the hWnd, then hook, then delete your dummy gadget and create the one you really want. Or you need to manually subclass the WndProc for the first gadget you create, but all further created ones will be modified.

Re: Class Hook

Posted: Thu Aug 08, 2013 11:37 pm
by Josh
tinman wrote:According to MSDN:
Calling SetClassLongPtr with the GCLP_WNDPROC index creates a subclass of the window class that affects all windows subsequently created with the class.
Subsequently was the keyword I ignored :lol:

Interesting detail. If I create another stringgadget after SetClassLongPtr, the hook works for the first stringgadget too.

Thxs
Josh

Re: Class Hook

Posted: Wed Aug 28, 2013 11:11 pm
by Nico
A example:

Code: Select all

Global OriginProc.i
#GCLP_WNDPROC = -24

Procedure.l SuperClassingWindow(hWnd.i, Msg.l, wParam.i, lParam.i)
  Protected ID.l
  
  ID = GetDlgCtrlID_(hwnd)
  
  Select Msg
    Case #BM_SETSTATE
      Select ID
        Case 11
          Select wparam
            Case 0
              Debug "Relaché button 11"
              
            Case 1
              Debug "Appuyé button 11"
              
          EndSelect   
          
        Case 12
          Select wparam
            Case 0
              Debug "Relaché button 12"
              
            Case 1
              Debug "Appuyé button 12"
              
          EndSelect 
          
        Case 13
          Select wparam
            Case 0
              Debug "Relaché button 13"
              
            Case 1
              Debug "Appuyé button 13"
              
          EndSelect 
      EndSelect
  EndSelect
  
  ProcedureReturn CallWindowProc_(OriginProc, hWnd, Msg, wParam, lParam)
EndProcedure

If OpenWindow(0, 0, 0, 222, 200, "ButtonGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 

  ButtonGadget(0, 10,  70, 200, 20, "Texte aligné à droite", #PB_Button_Right)

  ;Doesn't work for the first Button
  OriginProc = SetClassLongPtr_(GadgetID(0), #GCLP_WNDPROC, @SuperClassingWindow())
  Debug OriginProc
  
  ;Destroy the first Button
  FreeGadget(0)
  
  ButtonGadget(11, 10,  70, 200, 20, "Texte aligné à droite", #PB_Button_Right)
  ButtonGadget(12, 10, 100, 200, 60, "Texte sur plusieurs lignes (les textes longs retournent automatiquement à la ligne)", #PB_Button_MultiLine)
  ButtonGadget(13, 10, 170, 200, 20, "Bouton à bascule", #PB_Button_Toggle)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf