Class Hook

Windows specific forum
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Class Hook

Post 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
sorry for my bad english
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Re: Class Hook

Post 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.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Class Hook

Post 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
sorry for my bad english
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Re: Class Hook

Post 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
Post Reply