TCheckListBox OnDrawItem

Rund um die LCL und andere Komponenten
Antworten
MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

TCheckListBox OnDrawItem

Beitrag von MmVisual »

Hallo,

Ich möchte in einer TCheckListBox mit Hilfe OnDrawItem die Textfarbe einzelner Einträge ändern. Den Style habe ich umgestellt, das Event wird angesprungen.

Was gibt es für eine einfache Möglichkeit, dass mir das ganze gerüst schon gezeichnet wird und ich nur noch den "Canvas.Font.Color" manipuliere?

In den Sourcen / Foren / Google habe ich leider nichts passendes gefunden. So wie ich Lazarus kenne geht das sicher ganz einfach.

Bei einem DB-Grid würde das so aussehen:

Code: Alles auswählen

TDBGrid(Sender).Canvas.FillRect(Rect2);
TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
Aber vergleichbares für die TCheckListBox hab ich leider nicht gefunden.

Ich danke im Vorraus für eure Hilfe.

Grüße Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: TCheckListBox OnDrawItem

Beitrag von Socke »

Da ich denke, dass du die Farbe der einzelnen Check-Boxen nach bestimmten Kriterien einfärben willst, denke ich, dass das schnelle nachbauen mittels TGroupbox und TCheckbox am effizientesten ist. Beachte dabei auch TGroupbox.ChildSizing - damit kann man die Kind-Elemente einfach und schnell gleichmäßig platzieren.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TCheckListBox OnDrawItem

Beitrag von MmVisual »

Ich habe so programmiert:

Code: Alles auswählen

procedure TfrmMain.lstAufzKurvDrawItem(Control: TWinControl; Index: Integer;
   ARect: TRect; State: TOwnerDrawState);
Var clOld: TColor;
    i, iNum: Integer;
    OldBrushStyle: TBrushStyle;
    OldTextStyle: TTextStyle;
    NewTextStyle: TTextStyle;
    BRect: TRect;
    b: Boolean;
    OldStyle: TFontStyles;
//    wg: TWidgetSet;
const
   IsChecked : array[Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED) ;
   ColorSet: Array[0..17] of TColor = (clBlue,  clGreen, clRed,    clGray, clFuchsia, clTeal, clPurple,
                                          clNavy,  clLime,  clMaroon, clAqua, clYellow,
                                          clBlack, clOlive, clSilver,
                                          clLtGray,clDkGray,clWhite);
begin
   b := odSelected In State;
   With TCheckListBox(Control) Do
   Begin
      clOld := Canvas.Font.Color;
      OldBrushStyle := Canvas.Brush.Style;
      OldTextStyle := Canvas.TextStyle;
      OldStyle := Canvas.Font.Style;
 
      Canvas.Brush.Color := Brush.Color;
      Canvas.FillRect(ARect);
      Canvas.Brush.Style := bsClear;
      BRect.Left := ARect.Left + 1;
      BRect.Top := ARect.Top + 1;
      BRect.Bottom := ARect.Bottom+ 2;
      BRect.Right := ARect.Left + (ARect.Bottom - ARect.Top) - 2;
//      wg := TWidgetSet.Create;
      DrawFrameControl(Canvas.Handle, BRect, DFC_BUTTON, IsChecked[Checked[Index]]);
//      wg.Free;
 
      If b Then
         Canvas.Font.Style := [fsBold];
 
      If Checked[Index] Then
      Begin
         iNum := 0;
         For i := 0 To Index - 1 Do
            If Checked[i] Then
            Begin
               Inc(iNum);
               If iNum > High(ColorSet) Then
                  iNum := 0;
            end;
         Canvas.Font.Color := ColorSet[iNum];
      end Else Canvas.Font.Color := Font.Color;
      NewTextStyle := OldTextStyle;
      NewTextStyle.Layout := tlCenter;
      Canvas.TextStyle := NewTextStyle;
      ARect.Left := BRect.Right;
      Canvas.TextRect(ARect, ARect.Left+2, ARect.Top, Items[Index]);
 
      Canvas.Font.Color := clOld;
      Canvas.Brush.Style := OldBrushStyle;
      Canvas.TextStyle := OldTextStyle;
      Canvas.Font.Style := OldStyle;
   End;
end;
Es ist wirklich verdammt schwierig das zu finden.

Nun habe ich das Problem, dass die Checkbox nicht mit der Windows Theme gezeichnet wird. Ich habe versucht das mit TWidgetSet, aber zeichnet dennoch nicht richtig.
Am liebsten wäre mir eine Checkbox-Zeichnen Funktion, die auch unter Linux funktioniert. Ich bin mir nicht sicher ob diese Funktion unabhängig vom Betriebssystem ist.

Es wäre toll, wenn mir jemand einen Tipp geben könnte. Vielen Dank im Voraus.

Grüße Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: TCheckListBox OnDrawItem

Beitrag von Socke »

Versuchs mal mit InterfaceBase.Widgetset.DrawFrameControl(). Aus deinem Quelltext kann ich nicht erraten, welches DrawFrameControl du verwendest.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TCheckListBox OnDrawItem

Beitrag von MmVisual »

Geht leider nicht. Sieht immer noch "alt" aus.
Wenn ich mit Strg+Klick auf "DrawFrameControl" mache springt er nach "winapih.inc"
EleLa - Elektronik Lagerverwaltung - www.elela.de

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TCheckListBox OnDrawItem

Beitrag von pluto »

Schau dir mal das THeaderControl an. Das verwenden den Thmenmanger. Vielleicht hilft das hier auch weiter.
MFG
Michael Springwald

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TCheckListBox OnDrawItem

Beitrag von MmVisual »

@plute: Danke, dass war der richtige Tipp !!! Jetzt gehts.
EleLa - Elektronik Lagerverwaltung - www.elela.de

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TCheckListBox OnDrawItem

Beitrag von pluto »

Kannst du mal den Code davon posten ?
MFG
Michael Springwald

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TCheckListBox OnDrawItem

Beitrag von MmVisual »

Code: Alles auswählen

Const ColorSet: Array[0..12] of TColor = (clBlue,  clGreen, clRed,    clGray, clFuchsia, clTeal, clPurple,
                                          clNavy,  clLime,  clMaroon, clAqua, clYellow,  clOlive);
 
procedure TfrmMain.lstAufzKurvDrawItem(Control: TWinControl; Index: Integer;
   ARect: TRect; State: TOwnerDrawState);
Var clOld: TColor;
    i, iNum: Integer;
    OldBrushStyle: TBrushStyle;
    OldTextStyle: TTextStyle;
    NewTextStyle: TTextStyle;
    BRect: TRect;
    b: Boolean;
    OldStyle: TFontStyles;
    te: TThemedElementDetails;
const
   IsChecked : array[Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED) ;
begin
   b := odSelected In State;
   With TCheckListBox(Control) Do
   Begin
      clOld := Canvas.Font.Color;
      OldBrushStyle := Canvas.Brush.Style;
      OldTextStyle := Canvas.TextStyle;
      OldStyle := Canvas.Font.Style;
 
      Canvas.Brush.Color := Brush.Color;
 
      If Checked[Index] Then
         Canvas.GradientFill(ARect, Brush.Color, clMoneyGreen, gdHorizontal)
      Else Canvas.FillRect(ARect);
 
      Canvas.Brush.Style := bsClear;
      BRect.Left := ARect.Left + 1;
      BRect.Top := ARect.Top;
      BRect.Bottom := ARect.Bottom;
      BRect.Right := ARect.Left + (ARect.Bottom - ARect.Top) - 2;
 
      If Checked[Index] Then
         te := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal)
      Else te := ThemeServices.GetElementDetails(tbCheckBoxUncheckedNormal);
      ThemeServices.DrawElement(Canvas.Handle, te, BRect);
 
      If b Then
         Canvas.Font.Style := [fsBold];
 
      If Checked[Index] Then
      Begin
         iNum := 0;
         For i := 0 To Index - 1 Do
            If Checked[i] Then
            Begin
               Inc(iNum);
               If iNum > High(ColorSet) Then
                  iNum := 0;
            end;
         Canvas.Font.Color := ColorSet[iNum];
      end Else Canvas.Font.Color := Font.Color;
      NewTextStyle := OldTextStyle;
      NewTextStyle.Layout := tlCenter;
      Canvas.TextStyle := NewTextStyle;
      ARect.Left := BRect.Right;
      Canvas.TextRect(ARect, ARect.Left+2, ARect.Top, Items[Index]);
 
      Canvas.Font.Color := clOld;
      Canvas.Brush.Style := OldBrushStyle;
      Canvas.TextStyle := OldTextStyle;
      Canvas.Font.Style := OldStyle;
   End;
end;
Dateianhänge
Und so sieht es aus
Und so sieht es aus
Bild1.png (1.9 KiB) 1607 mal betrachtet
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten