SetGadgetCallback (Windows Only)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

SetGadgetCallback (Windows Only)

Beitrag von mk-soft »

Hier mal ein kleines Module um vereinfacht die Window Proceduren von den Gadget Controls umzuleiten.

Wäre schön wenn Purebasic dieses direkt unterstützt.

Code: Alles auswählen

;-TOP

; Comment : Module SetGadgetCallback (Windows Only)
; Author  : mk-soft
; Version : v0.02
; Created : 10.06.2018
; Updated : 
;
; Syntax Callback:
;           Procedure GadgetCB(hWnd,uMsg,wParam,lParam)
;             Select uMsg
;               ;TODO
;             EndSelect
;             ; Call previous gadget procedure
;             ProcedureReturn CallGadgetProc(hWnd,uMsg,wParam,lParam)
;           EndProcedure
;
; *****************************************************************************

DeclareModule GadgetCallback
  
  Declare SetGadgetCallback(Gadget, *lpNewFunc) 
  Declare CallGadgetProc(hWnd, uMsg, wParam, lParam)
  
EndDeclareModule

Module GadgetCallback
  
  EnableExplicit
  
  Global NewMap *lpPrevFunc()
  Global MutexCB = CreateMutex()
  
  ; ---------------------------------------------------------------------------
  
  Procedure SetGadgetCallback(Gadget, *lpNewFunc)
    Protected GadgetID, GadgetKey.s
    
    GadgetID = GadgetID(Gadget)
    GadgetKey = Hex(GadgetID)
    
    ; Remove exists Callback
    If FindMapElement(*lpPrevFunc(), GadgetKey)
      SetWindowLongPtr_(GadgetID, #GWL_WNDPROC, *lpPrevFunc())
      DeleteMapElement(*lpPrevFunc())
    EndIf
    
    If *lpNewFunc
      If AddMapElement(*lpPrevFunc(), GadgetKey)
        *lpPrevFunc() = SetWindowLongPtr_(GadgetID, #GWL_WNDPROC, *lpNewFunc)
        ProcedureReturn *lpPrevFunc()
      EndIf
    EndIf
    
    ProcedureReturn 0
    
  EndProcedure
  
  ; ---------------------------------------------------------------------------
  
  Procedure CallGadgetProc(hWnd, uMsg, wParam, lParam)
    Protected result
    
    LockMutex(MutexCB)
    If FindMapElement(*lpPrevFunc(), Hex(hWnd))
      result = CallWindowProc_(*lpPrevFunc(), hWnd, uMsg, wParam, lParam)
    EndIf
    UnlockMutex(MutexCB)
    
    ProcedureReturn result
    
  EndProcedure
  
EndModule

; *****************************************************************************

; Example

CompilerIf #PB_Compiler_IsMainFile
  
  UseModule GadgetCallback
  
  Procedure RichEditProc(hWnd,uMsg,wParam,lParam)
    Select uMsg
      Case #WM_CHAR
        If wParam = #VK_TAB
          SetFocus_(GetWindow_(hWnd,#GW_HWNDNEXT))
          ProcedureReturn 1
        EndIf
    EndSelect
    ProcedureReturn CallGadgetProc(hWnd,uMsg,wParam,lParam)
  EndProcedure
  
  If OpenWindow(0,0,0,500,250,"Example SetGadgetCallback",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    EditorGadget(1,10,10,230,200,0)
    EditorGadget(2,250,10,230,200,0)
    
    SetGadgetCallback(1, @RichEditProc())
    SetGadgetCallback(2, @RichEditProc())
    
    ; SetGadgetCallback(1, 0)
    ; SetGadgetCallback(2, 0)
    
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
  
CompilerEndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive