this alternative way of doing the subclass maybe interesting as well.
Code: Select all
EnableExplicit
; Forum Link: https://www.purebasic.fr/english/viewtopic.php?t=81714
Import "Comctl32.lib"
; use the PureBasic Syntax (Windows API procedures using trailing underscore)
;
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "SetWindowSubclass"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "GetWindowSubclass"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "RemoveWindowSubclass"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "DefSubclassProc"
CompilerElse
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "_SetWindowSubclass@16"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "_GetWindowSubclass@16"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "_RemoveWindowSubclass@12"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "_DefSubclassProc@16"
CompilerEndIf
EndImport
Enumeration EWindow
#WND_Main
EndEnumeration
Enumeration EGadget
EndEnumeration
; ---------------------------------------------------------------------------------------------------------------------
Macro WMDebug(Message)
Debug " " +
#PB_Compiler_Procedure + "() " +
LSet(Message, 20) +
RSet(Str(uIdSubclass), 4) +
RSet(Str(dwRefData), 6)
EndMacro
; --- first subclass procedure ---
;
Procedure SubclassWindowProc1(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData)
Select uMsg
Case #WM_NCDESTROY : WMDebug("WM_NCDESTROY")
RemoveWindowSubclass_(hWnd, @SubclassWindowProc1(), uIdSubclass)
Case #WM_LBUTTONDOWN : WMDebug("WM_LBUTTONDOWN")
Case #WM_RBUTTONDOWN : WMDebug("WM_RBUTTONDOWN")
EndSelect
ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam)
EndProcedure
; --- second subclass procedure ---
;
Procedure SubclassWindowProc2(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData)
Select uMsg
Case #WM_NCDESTROY : WMDebug("WM_NCDESTROY")
RemoveWindowSubclass_(hWnd, @SubclassWindowProc2(), uIdSubclass)
Case #WM_LBUTTONDOWN : WMDebug("WM_LBUTTONDOWN")
Case #WM_RBUTTONDOWN : WMDebug("WM_RBUTTONDOWN")
EndSelect
ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam)
EndProcedure
; --- third subclass procedure ---
;
Procedure SubclassWindowProc3(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData)
Select uMsg
Case #WM_NCDESTROY : WMDebug("WM_NCDESTROY")
RemoveWindowSubclass_(hWnd, @SubclassWindowProc3(), uIdSubclass)
Case #WM_LBUTTONDOWN : WMDebug("WM_LBUTTONDOWN")
Case #WM_RBUTTONDOWN : WMDebug("WM_RBUTTONDOWN")
EndSelect
ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam)
EndProcedure
; --- main procedure ---
;
Procedure Main()
Protected hwndMain, RefData ; for testing
If OpenWindow(#WND_Main, 0, 0, 320, 240, "Click on window (left or right mouse button) ... ", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
StickyWindow(#WND_Main, 1) ; always on top :)
; No Gadgets
hwndMain = WindowID(#WND_Main)
; Window Subclass -> different procedure names, same uIdSubclass -> unique
SetWindowSubclass_(hwndMain, @SubclassWindowProc1(), 1, 101) ;
SetWindowSubclass_(hwndMain, @SubclassWindowProc2(), 1, 102) ; removed early by app
SetWindowSubclass_(hwndMain, @SubclassWindowProc3(), 1, 103) ;
; Window Subclass -> same procedure name, different uIdSubclass -> unique
SetWindowSubclass_(hwndMain, @SubclassWindowProc3(), 2, 104) ;
SetWindowSubclass_(hwndMain, @SubclassWindowProc3(), 3, 105) ; removed early by app
SetWindowSubclass_(hwndMain, @SubclassWindowProc3(), 4, 106) ;
; remove any proc from chain
If GetWindowSubclass_(hwndMain, @SubclassWindowProc2(), 1, @RefData) ; we can get the RefData
Debug "Remove SubclassWindowProc2() with " + RefData + " -> " + RemoveWindowSubclass_(hwndMain, @SubclassWindowProc2(), 1)
EndIf
; remove any proc from chain
If GetWindowSubclass_(hwndMain, @SubclassWindowProc3(), 3, @RefData) ; we can get the RefData
Debug "Remove SubclassWindowProc3() with " + RefData + " -> " + RemoveWindowSubclass_(hwndMain, @SubclassWindowProc3(), 3)
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break ; say good bye.
EndSelect
ForEver
EndIf
EndProcedure
End Main()