Seite 2 von 2

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 00:29
von NicTheQuick
Ich mag mich irren, aber kann man nicht einfach mittels API die Farben des ProgressbarGadgets ändern?
Mein erster Google-Link führte mich zu dieser Klasse: Progressbar
Dort gibt es Eigenschaften wie 'Background', 'BitmapEffect', 'Effect', 'FlowDirection', 'FocusVisualStyle', 'Foreground', 'Opacity', 'Style', usw.

Kann man damit nichts machen?

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 09:11
von Danilo
NicTheQuick hat geschrieben:Ich mag mich irren, aber kann man nicht einfach mittels API die Farben des ProgressbarGadgets ändern?
Mein erster Google-Link führte mich zu dieser Klasse: Progressbar
Dort gibt es Eigenschaften wie 'Background', 'BitmapEffect', 'Effect', 'FlowDirection', 'FocusVisualStyle', 'Foreground', 'Opacity', 'Style', usw.

Kann man damit nichts machen?
Diese Klasse ist aus dem .NET Framework, da geht das alles viel besser.

Hier mal ein Anfang zum selber zeichnen. Ist nicht für vertikale Progressbars und bei diesem
Beispiel wird der Balken einfach nur mit 2 Farben gezeichnet - wodurch es natürlich nicht so schön hübsch ist.
Farbe 3 ist für den Hintergrund, -1 ist transparent. Kann ja jeder in #WM_PAINT verhübschen wie er will.

Code: Alles auswählen

EnableExplicit

Structure MyProgressBarData
    oldCallback.i
    color1.l
    color2.l
    color3.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\color3 <> -1
                SelectObject_(hDC, GetStockObject_(#NULL_PEN))
                brush = CreateSolidBrush_(*mem\color3)
                    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)
            SetBkMode_(hDC,#TRANSPARENT)
            SelectObject_(hDC, GetStockObject_(#NULL_PEN))
            brush = CreateSolidBrush_(*mem\color1)
                SelectObject_(hDC, brush)
                Rectangle_(hDC,0,0,w,h+1)
            DeleteObject_(brush)
            brush = CreateSolidBrush_(*mem\color2)
                SelectObject_(hDC, brush)
                Rectangle_(hDC,0,0,w,Int(h*0.4))
            DeleteObject_(brush)
        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\color1      = RGB($00,$FF,$00)
        *mem\color2      = RGB($A0,$FF,$A0)
        *mem\color3      = -1
        *mem\vertical    = Flags & #PB_ProgressBar_Vertical
        SetGadgetData(gadget,*mem)
    EndIf
    ProcedureReturn g
EndProcedure

Procedure MyProgressBarColor(gadget,color1,color2,color3=-1)
    Protected *mem.MyProgressBarData
    If IsGadget(gadget) And GadgetType(gadget)=#PB_GadgetType_ProgressBar
        *mem = GetGadgetData(gadget)
        If *mem
            *mem\color1 = color1
            *mem\color2 = color2
            *mem\color3 = color3
            InvalidateRect_(GadgetID(gadget),0,1)
        EndIf
    EndIf
EndProcedure


Define EventID, state, bar3

If OpenWindow(0,0,0,500,400,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  MyProgressBarGadget(1,10,10,WindowWidth(0)-20,20,0,100)

  MyProgressBarGadget(2,10,50,WindowWidth(0)-20,20,0,150)
  MyProgressBarColor(2,RGB($FF,$00,$00),RGB($FF,$A0,$A0),RGB($00,$00,$00))

  bar3 = MyProgressBarGadget(#PB_Any,10,90,WindowWidth(0)-20,20,0,200)
  MyProgressBarColor(bar3,RGB($00,$00,$FF),RGB($80,$80,$FF),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

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 09:48
von Danilo
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?

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 12:36
von Pelagio
Habe ich da was überlesen? :praise:

es ist doch möglich das ProgressBarGadget mit SetGadgetColor() einzufärben,
ich darf nur nicht die XP-Skin Unterstützung einschalten.

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 12:52
von RSBasic
@Danilo
Vielen herzlichen Dank für deine Hilfe und für deine Codes. Genau sowas habe ich gesucht. Vielen Dank nochmal für deine Hilfe. :)
Und das mit dem Umfärben kann ich dann später anders umsetzen, so dass die Ausgangsfarbe bei jedem Skin gleich ist.

@Pelagio
Ja, genau darum gehts ja. Dass das Einfärben ohne XP-Skin funktioniert, weiß man ja. Steht ja auch in der Hilfe. Aber gesucht war ja mit Skin.

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 20:23
von Danilo
RSBasic hat geschrieben:@Danilo
Vielen herzlichen Dank für deine Hilfe und für deine Codes. Genau sowas habe ich gesucht. Vielen Dank nochmal für deine Hilfe. :)
Und das mit dem Umfärben kann ich dann später anders umsetzen, so dass die Ausgangsfarbe bei jedem Skin gleich ist.
Mit Deinem originalen Code geht es auch, nach kleinen Anpassungen - und dann
sogar eingefärbt mit der Progressbar-Animation (Win7, Smooth Style, da kommt
ein animierter "Leuchteffekt" der immer über die Progressbar läuft).

Die originale Progressbar ist versteckt mit HideWindow, dadurch kein flackern.
Und Foto mit SendMessage & #WM_PRINT statt PrintWindow_().
Durch die verzögerte Animation der Progressbar muss man nach SetGadgetState(1,100)
noch paar male mehr zeichnen, bis die Progressbar animiert "voll" ist.

Code: Alles auswählen

EnableExplicit

Define EventID

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(Gadgetnummer)
  Protected width, height
  Protected hdc
  
  width = GadgetWidth(Gadgetnummer)
  height = GadgetHeight(Gadgetnummer)

  CreateImage(0, width, height, 24)
  hdc = StartDrawing(ImageOutput(0))
  ;PrintWindow_(GadgetID(Gadgetnummer), hdc, #Null)
  SendMessage_(GadgetID(Gadgetnummer),#WM_PRINT,hDC,#PRF_CHILDREN|#PRF_CLIENT|#PRF_ERASEBKGND)
  StopDrawing()
 
  CreateImage(1,  width, height, 24)
  StartDrawing(ImageOutput(1))
  DrawingMode(#PB_2DDrawing_CustomFilter)
  CustomFilterCallback(@ColorRotation())
  DrawImage(ImageID(0), 0, 0)
  StopDrawing()
 
EndProcedure

Procedure Thread(z);Beispiel
  Protected a
  Repeat
    a+1
    If a <= 100
      SetGadgetState(1,a)
    EndIf
    CaptureGadget(1)
    SetGadgetState(2,ImageID(1))
    Delay(30)
  Until a = 200
EndProcedure

If OpenWindow(0,0,0,500,400,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ProgressBarGadget(1,10,10,WindowWidth(0)-20,20,0,100,0)
  HideGadget(1,1)
 
  ImageGadget(2,10,10,0,0,0,0)
 
  CreateThread(@Thread(),0)

  Repeat
    EventID=WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
      End
    EndIf
  ForEver
EndIf
Mußt mal damit rumspielen, wie Du es benötigst.

Re: ProgressBarGadget einfärben

Verfasst: 16.09.2011 20:25
von RSBasic
Cool, vielen Dank. :allright: