Ich hab da mal (um API-, und Pointerkenntnisse zu erlangen) ein Gadget auf Basis eines ImageGadgets gebastelt.
Es ist auch möglich, durch auskommentieren der #CompileAsUserlib bei Tailbite die IDE-Debug Funktion zu erhalten.
Ich hoffe mal das funktioniert im Einsatz

Der HauptTeil : "U4IB.pb"
Code: Alles auswählen
;@____________________________________________________________________________
; »»» Projekt : Universal 4-State ImageButtonGadget
; »»» Author : George Bisonte (mit Hilfe von netmaestro (Maustracking)
; »»» Date : 01 Aug, 2012
; »»» OS : WindowsOnly
; »»» PB : V4.61 (tested x86)
; »»» CPU : x86 (getestet, sollte eigentlich auch mit x64 laufen)
; »»» Unicode : Ja, sollte eigentlich, da keine Strings genutzt werden
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
EnableExplicit
;
; Wenn diese Include als oder in eine(r) Userlib genutzt werden soll,
; folgende Zeile auskommentieren um DEBUG Funktionen zu erhalten (Nur TailBite)
; #CompileAsUserlib = #True
;
CompilerIf Defined(CompileAsUserlib, #PB_Constant) = #True
CompilerIf #CompileAsUserlib = #True
XIncludeFile #PB_Compiler_Home+"TailBite/Helper Libraries/TB_Debugger.pb"
CompilerEndIf
CompilerEndIf
; ____________________________________________________________________________
; »»» Externe Ressourcen
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Enumeration 0 ; Die 4 Zustands Images als Konstante (für ChangeImage)
#PB_U4IButton_Normal
#PB_U4IButton_Hoover
#PB_U4IButton_Selected
#PB_U4IButton_Disabled
EndEnumeration
; ____________________________________________________________________________
; »»» Intern
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
#PROP_UNIVERSAL4STATE_IMAGEBUTTONGADGET = "UNIVERSAL4STATE_IMAGEBUTTONGADGET"
;
Structure struct_universal_imagebuttongadget
Gadget.i ; »»» PB Gadget Objektnummer
OldProc.i ; »»» Alter Callback des ImageGadgets
State.i ; »»» Welchen Zustand hat das Gadget
Disabled.i ; »»» Ist das Gadget Disabled ?
Tracking.i ; »»» Für die Mausüberwachung (thx Netmaestro)
Image.i[4] ; »»» Die 4 Images
EndStructure
Procedure priv_callback_universal_imagebuttongadget(hWnd, uMsg, wParam, lParam)
Protected OldProc, i
Protected *p.struct_universal_imagebuttongadget
Protected tm.TRACKMOUSEEVENT
*p = GetProp_(hWnd, #PROP_UNIVERSAL4STATE_IMAGEBUTTONGADGET)
If *p
OldProc = *p\OldProc
Else
ProcedureReturn 0
EndIf
Select uMsg
Case #WM_NCDESTROY ; FreeGadget() wurde aufgerufen
FreeMemory(*p) ; den erstellten Speicher freigeben
Case #WM_ENABLE ; DisableGadget() wurde aufgerufen
If wParam = 0
*p\Disabled = #True
*p\State = 3
Else
*p\Disabled = #False
*p\State = 0
EndIf
If IsGadget(*p\Gadget) And IsImage(*p\Image[*p\State])
SetGadgetState(*p\Gadget, ImageID(*p\Image[*p\State]))
EndIf
Case #WM_MOUSEMOVE ; Mouse wurde bewegt
If Not *p\tracking ; Mousetracking starten
*p\tracking = #True
With tm.TRACKMOUSEEVENT
\cbSize = SizeOf(TRACKMOUSEEVENT)
\dwFlags = #TME_LEAVE
\hwndTrack = hWnd
EndWith
TrackMouseEvent_(@tm)
CallWindowProc_(OldProc, hWnd, uMsg, wParam, lParam)
If *p\State = 0
*p\State = 1
SetGadgetState(*p\Gadget, ImageID(*p\Image[*p\State]))
EndIf
ProcedureReturn 0
Else ; Mousetracking läuft bereits
If *p\State = 0
*p\State = 1
SetGadgetState(*p\Gadget, ImageID(*p\Image[*p\State]))
EndIf
EndIf
Case #WM_MOUSELEAVE ; Maus verlässt Gadget
*p\tracking = #False
If *p\State >0 And *p\State < 3
*p\State = 0
SetGadgetState(*p\Gadget, ImageID(*p\Image[*p\State]))
EndIf
ProcedureReturn 0
Case #WM_LBUTTONDOWN ; Nur auf Linken Mauskopf reagieren wenn Maus auch über Gadget ist
If *p\State = 1
*p\State = 2
EndIf
SetGadgetState(*p\Gadget, ImageID(*p\Image[*p\State]))
Case #WM_LBUTTONUP ; Linker Mausknopf hoch stellt Hoover Image wieder her wenn selected ist
If *p\State = 2
If *p\tracking = #True
*p\State = 1
EndIf
EndIf
SetGadgetState(*p\Gadget, ImageID(*p\Image[*p\State]))
EndSelect
If OldProc
ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wParam, lParam)
Else
ProcedureReturn 0
EndIf
EndProcedure
; ____________________________________________________________________________
; »»»
; »»» Externe Funktionen
; »»»
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
ProcedureDLL U4I_ButtonGadget(Gadget, x, y, ImageNormal, ImageHoover, ImageSelected, ImageDisabled) ; Erstellt ein ButtonGadget mit den 4 Images
Protected *p.struct_universal_imagebuttongadget
Protected ID = #False, Error = #False
If Not IsImage(ImageNormal) Or Not IsImage(ImageHoover) Or Not IsImage(ImageSelected) Or Not IsImage(ImageDisabled)
ProcedureReturn #False
EndIf
*p = AllocateMemory(SizeOf(struct_universal_imagebuttongadget))
If Not *p : ProcedureReturn #False : EndIf
*p\Image[0] = ImageNormal
*p\Image[1] = ImageHoover
*p\Image[2] = ImageSelected
*p\Image[3] = ImageDisabled
*p\State = 0
*p\tracking = #False
*p\Disabled = #False
ID = ImageGadget(Gadget, x, y, ImageWidth(ImageNormal), ImageHeight(ImageNormal), ImageID(ImageNormal))
If Gadget = #PB_Any : Gadget = ID : EndIf
*p\Gadget = Gadget
*p\OldProc = SetWindowLongPtr_(GadgetID(Gadget), #GWLP_WNDPROC, @priv_callback_universal_imagebuttongadget())
SetProp_(GadgetID(Gadget), #PROP_UNIVERSAL4STATE_IMAGEBUTTONGADGET, *p)
ProcedureReturn ID
EndProcedure
ProcedureDLL U4I_ChangeButtonImage(Gadget, ImageType, Image) ; Aendert ein Image in der Imageliste des Gadgets
Protected *p.struct_universal_imagebuttongadget
If Not IsImage(Image) : ProcedureReturn #False : EndIf
If Not IsGadget(Gadget) : ProcedureReturn #False : EndIf
*p = GetProp_(GadgetID(Gadget), #PROP_UNIVERSAL4STATE_IMAGEBUTTONGADGET)
If *p
If ImageType >= 0 And ImageType <= 3
*p\Image[ImageType] = Image
SetGadgetState(Gadget, ImageID(*p\Image[*p\State]))
ProcedureReturn #True
EndIf
Else
ProcedureReturn #False
EndIf
EndProcedure
; ____________________________________________________________________________
; »»» Debug Funktionen
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
CompilerIf Defined(CompileAsUserlib, #PB_Constant) = #True
CompilerIf #CompileAsUserlib = #True
ProcedureCDLL U4IButtonGadget_DEBUG(Gadget, x, y, ImageNormal, ImageHoover, ImageSelected, ImageDisabled)
If Not IsImage(ImageNormal)
TB_DebugError("#ImageNormal is not initialized")
EndIf
If Not IsImage(ImageHoover)
TB_DebugError("#ImageHoover is not initialized")
EndIf
If Not IsImage(ImageSelected)
TB_DebugError("#ImageSelected is not initialized")
EndIf
If Not IsImage(ImageDisabled)
TB_DebugError("#ImageDisabled is not initialized")
EndIf
EndProcedure
ProcedureCDLL U4I_ChangeButtonImage_DEBUG(Gadget, ImageType, Image)
If Not IsGadget(Gadget)
TB_DebugError("#Gadget is not initialized")
EndIf
If Not IsImage(Image)
TB_DebugError("#Image is not initialized")
EndIf
If ImageType < #PB_U4IButton_Normal And ImageType > #PB_U4IButton_Disabled
TB_DebugError("ImageType is out of range (0-3) , hint : use for example #PB_U4IButton_Hoover")
EndIf
EndProcedure
CompilerEndIf
CompilerEndIf
;
DisableExplicit
Code: Alles auswählen
Enumeration 0 ; Die 4 Zustands Images als Konstante (für ChangeImage)
#PB_U4IButton_Normal
#PB_U4IButton_Hoover
#PB_U4IButton_Selected
#PB_U4IButton_Disabled
EndEnumeration
Man sollte nur über 4 Images verfügen und dann die Pfade anpassen...
Code: Alles auswählen
CompilerIf Defined(U4I_ButtonGadget, #PB_Function) = #False
XIncludeFile "U4IB.pb"
CompilerEndIf
UsePNGImageDecoder()
; PFADE DER BILDER ANPASSEN (ALLE SOLLTEN GLEICH GROSS SEIN)
Im1 = LoadImage(#PB_Any, "ImageNormal.png")
Im2 = LoadImage(#PB_Any, "ImageHoover.png")
Im3 = LoadImage(#PB_Any, "ImageSelected.png")
Im4 = LoadImage(#PB_Any, "ImageDisabled.png")
OpenWindow(0,200,300,800,600,"TestWindow")
U4I_ButtonGadget(1,10,10,im1,im2,im3,im4)
U4I_ButtonGadget(2,70,10,im1,im2,im3,im4)
DisableGadget(1,1)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 2
Debug "Gadget 2"
EndSelect
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Quit > 0
Verbesserungsvorschläge sind sehr willkommen !