Und gleich nochmal mit Images, da kann man die Progressbar leichter selbst gestalten:
Code: Alles auswählen
EnableExplicit
Structure MyProgressBarData
oldCallback.i
imageID.i
backColor.l
vertical.l
EndStructure
Procedure MyProgressBarCallback(hWnd,msg,wParam,lParam)
Protected *mem.MyProgressBarData
Protected w, h, state, range, minValue, p.f
Protected hDC, brush, ps.PAINTSTRUCT
Protected gadget = GetWindowLongPtr_(hWnd,#GWLP_ID)
*mem = GetGadgetData(gadget)
If Not *mem : ProcedureReturn DefWindowProc_(hWnd,msg,wParam,lParam) : EndIf
w = GadgetWidth(gadget)
h = GadgetHeight(gadget)
If msg = #WM_ERASEBKGND
hDC = wParam
If *mem\backColor <> -1
SelectObject_(hDC, GetStockObject_(#NULL_PEN))
brush = CreateSolidBrush_(*mem\backColor)
SelectObject_(hDC, brush)
Rectangle_(hDC,0,0,w,h+1)
DeleteObject_(brush)
ProcedureReturn #True
EndIf
ElseIf msg = #WM_PAINT
hDC = BeginPaint_(hWnd,@ps)
state = GetGadgetState(gadget) - minValue
range = GetGadgetAttribute(gadget,#PB_ProgressBar_Maximum) - minValue
If range < 0 : range = -range : EndIf
p = (state / range)
w = Int(w * p)
If *mem\imageID
brush = CreatePatternBrush_(*mem\imageID)
SelectObject_(hDC, brush)
PatBlt_(hDC,0,0,w,h+1,#PATCOPY)
;Rectangle_(hDC,0,0,w,h+1)
DeleteObject_(brush)
EndIf
EndPaint_(hWnd,@ps)
ProcedureReturn 0
EndIf
If *mem\oldCallback
ProcedureReturn CallWindowProc_(*mem\oldCallback,hWnd,msg,wParam,lParam)
EndIf
EndProcedure
Procedure MyProgressBarGadget(gadget, x, y, Width, Height, Minimum, Maximum, Flags=0)
Protected *mem.MyProgressBarData
Protected g
g = ProgressBarGadget(gadget,x,y,Width,Height,Minimum,Maximum,Flags)
If gadget = #PB_Any
gadget = g
EndIf
*mem = AllocateMemory(SizeOf(MyProgressBarData))
If *mem
*mem\oldCallback = SetWindowLongPtr_(GadgetID(gadget),#GWLP_WNDPROC,@MyProgressBarCallback())
*mem\backColor = -1
*mem\vertical = Flags & #PB_ProgressBar_Vertical
SetGadgetData(gadget,*mem)
EndIf
ProcedureReturn g
EndProcedure
Procedure StyleMyProgressBar(gadget,imageID,backColor=-1)
Protected *mem.MyProgressBarData
If IsGadget(gadget) And GadgetType(gadget)=#PB_GadgetType_ProgressBar
*mem = GetGadgetData(gadget)
If *mem
*mem\backColor = backColor
*mem\imageID = imageID
InvalidateRect_(GadgetID(gadget),0,1)
EndIf
EndIf
EndProcedure
Define EventID, state, bar3
Define i
CreateImage(1,1,20)
If StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_Gradient)
BackColor(RGB($FF,$FF,$FF))
FrontColor(RGB($00,$FF,$00))
GradientColor(0.2,RGB($A0,$FF,$A0))
LinearGradient(0, 0, 0, 20)
Box(0,0,1,20)
StopDrawing()
EndIf
CreateImage(2,1,20)
If StartDrawing(ImageOutput(2))
Box(0,0,1,20,RGB($00,$00,$FF))
For i = 2 To 20 Step 5
Plot(0,i,RGB($FF,$FF,$00))
Next
StopDrawing()
EndIf
CreateImage(3,10,20)
If StartDrawing(ImageOutput(3))
Box(0,0,10,20,RGB($FF,$00,$00))
LineXY(0,0,10,20,RGB($FF,$FF,$FF))
StopDrawing()
EndIf
If OpenWindow(0,0,0,500,400,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
MyProgressBarGadget(1,10,10,WindowWidth(0)-20,20,0,100)
StyleMyProgressBar(1,ImageID(1))
MyProgressBarGadget(2,10,50,WindowWidth(0)-20,20,0,150)
StyleMyProgressBar(2,ImageID(2),RGB($00,$00,$00))
bar3 = MyProgressBarGadget(#PB_Any,10,90,WindowWidth(0)-20,20,0,200)
StyleMyProgressBar(bar3,ImageID(3),RGB($FF,$FF,$80))
AddWindowTimer(0,0,33)
Repeat
EventID=WaitWindowEvent()
If EventID = #PB_Event_CloseWindow
End
ElseIf EventID = #PB_Event_Timer
state + 1
SetGadgetState(1,state)
SetGadgetState(2,state)
SetGadgetState(bar3,state)
If state = 100
RemoveWindowTimer(0,0)
EndIf
EndIf
ForEver
EndIf
Damit sollte auch Deine Methode "abfotografieren" + einfärben gehen, wenn Du den jeweiligen
Style des Windows' behalten möchtest.
Also normale Progressbar erzeugen, GadgetState auf 100, fotografieren, einfärben und danach
MyProgressBarGadget() + StyleMyProgressBar() mit Deinem Bild der originalen Progressbar.
EDIT:
Hier noch eine Version mit 2 Bildern, Hintergrund und Vordergrund. Dabei wird eine originale
Progressbar zweimal "abfotografiert". Einmal im leeren Zustand, dann im vollen.
Beim letzteren Bild werden dann die Farben geändert und danach ein MyProgressBarGadget()
mit den beiden Bildern erstellt.
Code: Alles auswählen
EnableExplicit
Structure MyProgressBarData
oldCallback.i
imageID1.i
imageID2.i
vertical.l
EndStructure
Procedure MyProgressBarCallback(hWnd,msg,wParam,lParam)
Protected *mem.MyProgressBarData
Protected w, h, state, range, minValue, p.f
Protected hDC, brush, ps.PAINTSTRUCT
Protected gadget = GetWindowLongPtr_(hWnd,#GWLP_ID)
*mem = GetGadgetData(gadget)
If Not *mem : ProcedureReturn DefWindowProc_(hWnd,msg,wParam,lParam) : EndIf
w = GadgetWidth(gadget)
h = GadgetHeight(gadget)
If msg = #WM_ERASEBKGND
hDC = wParam
If *mem\imageID2
brush = CreatePatternBrush_(*mem\imageID2)
SelectObject_(hDC, brush)
PatBlt_(hDC,0,0,w,h+1,#PATCOPY)
DeleteObject_(brush)
ProcedureReturn #True
EndIf
ElseIf msg = #WM_PAINT
hDC = BeginPaint_(hWnd,@ps)
state = GetGadgetState(gadget) - minValue
range = GetGadgetAttribute(gadget,#PB_ProgressBar_Maximum) - minValue
If range < 0 : range = -range : EndIf
p = (state / range)
w = Int(w * p)
If *mem\imageID1
brush = CreatePatternBrush_(*mem\imageID1)
SelectObject_(hDC, brush)
PatBlt_(hDC,0,0,w,h+1,#PATCOPY)
DeleteObject_(brush)
EndIf
EndPaint_(hWnd,@ps)
ProcedureReturn 0
EndIf
If *mem\oldCallback
ProcedureReturn CallWindowProc_(*mem\oldCallback,hWnd,msg,wParam,lParam)
EndIf
EndProcedure
Procedure MyProgressBarGadget(gadget, x, y, Width, Height, Minimum, Maximum, Flags=0)
Protected *mem.MyProgressBarData
Protected g
g = ProgressBarGadget(gadget,x,y,Width,Height,Minimum,Maximum,Flags)
If gadget = #PB_Any
gadget = g
EndIf
*mem = AllocateMemory(SizeOf(MyProgressBarData))
If *mem
*mem\oldCallback = SetWindowLongPtr_(GadgetID(gadget),#GWLP_WNDPROC,@MyProgressBarCallback())
*mem\vertical = Flags & #PB_ProgressBar_Vertical
SetGadgetData(gadget,*mem)
EndIf
ProcedureReturn g
EndProcedure
Procedure StyleMyProgressBar(gadget,imageID1,imageID2)
Protected *mem.MyProgressBarData
If IsGadget(gadget) And GadgetType(gadget)=#PB_GadgetType_ProgressBar
*mem = GetGadgetData(gadget)
If *mem
*mem\imageID1 = imageID1
*mem\imageID2 = imageID2
InvalidateRect_(GadgetID(gadget),0,1)
EndIf
EndIf
EndProcedure
Procedure ColorRotation(x, y, Color, Color2)
;ProcedureReturn RGBA(Green(Color), Blue(Color), Red(Color), Alpha(Color));Rot
ProcedureReturn RGBA(Red(Color), Blue(Color), Green(Color), Alpha(Color));Blau
;ProcedureReturn RGBA(Blue(Color), Green(Color), Green(Color), Alpha(Color));Türkis
;ProcedureReturn RGBA(Blue(Color), Blue(Color), Blue(Color), Alpha(Color));Schwarz
;ProcedureReturn RGBA(Green(Color), Green(Color), Red(Color), Alpha(Color));Gelb
EndProcedure
Procedure CaptureGadget(gadget)
Protected img, hDC
img = CreateImage(#PB_Any,GadgetWidth(gadget),GadgetHeight(gadget),24)
hDC = StartDrawing(ImageOutput(img))
If hDC
SendMessage_(GadgetID(gadget),#WM_PRINT,hDC,#PRF_CHILDREN|#PRF_CLIENT|#PRF_ERASEBKGND)
StopDrawing()
ProcedureReturn img
EndIf
EndProcedure
Define EventID, state, bar3
Define img1, img2
If OpenWindow(0,0,0,500,400,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible)
ProgressBarGadget(0,0,0,WindowWidth(0)-20,20,0,1)
While WindowEvent():Wend
img1 = CaptureGadget(0) ; foto von leerer progressbar
SetGadgetState(0,1)
Delay(700) ; delay benötigt wegen progressbar-animation bis es aufgefüllt ist
While WindowEvent():Wend
img2 = CaptureGadget(0) ; foto von voller progressbar
CreateImage(1, GadgetWidth(0),GadgetHeight(0), 24)
If StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_CustomFilter)
CustomFilterCallback(@ColorRotation())
DrawImage(ImageID(img2), 0, 0)
StopDrawing()
EndIf
MyProgressBarGadget(1,10,10,WindowWidth(0)-20,20,0,100)
StyleMyProgressBar(1,ImageID(1),ImageID(img1))
AddWindowTimer(0,0,33)
FreeGadget(0)
HideWindow(0,0)
Repeat
EventID=WaitWindowEvent()
If EventID = #PB_Event_CloseWindow
End
ElseIf EventID = #PB_Event_Timer
state + 1
SetGadgetState(1,state)
If state = 100
RemoveWindowTimer(0,0)
EndIf
EndIf
ForEver
EndIf
Ist es das, was Du wolltest?