Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Mehrzeiliger Header im VST (https://www.delphipraxis.net/111436-mehrzeiliger-header-im-vst.html)

Trille 3. Apr 2008 14:10


Mehrzeiliger Header im VST
 
Hallo allerseits,
ich komme mal wieder nicht weiter. Ich habe einen VirtualStringTree und möchte, dass die Überschrift (also der Header) mancher Spalten zweizeilig wird, falls es zu lang ist. Wie kann ich das bewerkstelligen?

Vielen Dank im Voraus!

EDIT: Danke, hat sich eben erledigt, ich hatte die HeaderDrawQueryElements vergessen. Deshalb hat es mit advancedHeaderDraw nicht geklappt :)

David Martens 16. Jun 2011 11:17

AW: Mehrzeiliger Header im VST
 
Hallo,

ich habe diesen alten Beitrag gefunden und wollte mal ein sehr ähnliches Problem schildern:

Wie kann ich einen zweispaltigen Header erzeugen. Also quasi eine Überschrift für die Überschriften.

Soll so aussehen:

Code:
|Header Level 1 A ......|Header Level 1 B ......|Header Level 1 C ......|
|Level 2 A.1|Level 2 A.2|Level 2 B.1|Level 2 B.2|Level 2 C.1|Level 2 C.2|
|Column 1   |Column 2   |Column 3   |Column 4   |Column 5   |Column 6   |
Gibt es so eine Möglichkeit?

Danke David

David Martens 20. Jun 2011 14:05

AW: Mehrzeiliger Header im VST
 
Keiner eine Idee?

madas 20. Jun 2011 14:31

AW: Mehrzeiliger Header im VST
 
Zitat:

Zitat von David Martens (Beitrag 1107464)
Keiner eine Idee?

Statt des VST den DrawTree nehmen und den Text selber malen. :)

Dazu im OnHeaderDrawQueryElements folgendes machen:

Delphi-Quellcode:
Include(Elements, hpeText);
und im OnAdvancedHeaderDraw darauf reagieren.

Hier mal ein Beispiel (musst Du für Deine Zwecke anpassen):

Delphi-Quellcode:
procedure TForm.AdvancedHeaderDraw(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
  const Elements: THeaderPaintElements);
var
  rNormalText, rResultText, rBemerkung, rTypWachstum: TRect;
  x, y: Integer;
  Text: WideString;
  Size: TSize;
begin
  inherited;
  if (hpeText in Elements) then
  begin
    // Trennlinien zeichnen
    if (PaintInfo.Column.Index >= abDieserSpalte) then
    begin
      rNormalText := PaintInfo.PaintRectangle;
      InflateRect(rNormalText, 0, -1);
      OffsetRect(rNormalText, -1, -1);
      if (PaintInfo.IsDownIndex) then
        OffsetRect(rNormalText, 1, 1);
      PaintInfo.TargetCanvas.Pen.Color := clInactiveBorder;
      PaintInfo.TargetCanvas.Pen.Width := 1;
      // Trennlinie Ansatz und typ. Wachstum
      y := rNormalText.Top;
      y := y + ((rNormalText.Bottom - rNormalText.Top) div 3);
      PaintInfo.TargetCanvas.MoveTo(rNormalText.Left, y);
      PaintInfo.TargetCanvas.LineTo(rNormalText.Right, y);
      // Trennlinie typ. Wachstum und Rest
      y := rNormalText.Top;
      y := y + (((rNormalText.Bottom - rNormalText.Top) div 3) * 2) + (FrameVSTTestItemList.Tree.TextMargin div 2);
      PaintInfo.TargetCanvas.MoveTo(rNormalText.Left, y);
      PaintInfo.TargetCanvas.LineTo(rNormalText.Right, y);
      x := rNormalText.Left + leftPartWidth;
      PaintInfo.TargetCanvas.MoveTo(x, y);
      PaintInfo.TargetCanvas.LineTo(x, rNormalText.Bottom);
    end;

    // Bereiche berechnen
    rNormalText := PaintInfo.PaintRectangle;
    InflateRect(rNormalText, -PaintInfo.Column.Margin, 0);
    if (PaintInfo.IsDownIndex) then
      OffsetRect(rNormalText, 1, 1);

    // Normalen Text bestimmen und berechnen
    Text := PaintInfo.Column.Text;
    GetTextExtentPoint32W(PaintInfo.TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
    if (PaintInfo.Column.Index > -1) and (Size.cx > (rNormalText.Right - rNormalText.Left)) then
      Text := ShortenString(PaintInfo.TargetCanvas.Handle, Text, (rNormalText.Right - rNormalText.Left), 0);

    SetBkMode(PaintInfo.TargetCanvas.Handle, TRANSPARENT);
    SetTextColor(PaintInfo.TargetCanvas.Handle, ColorToRGB(clWindowText));

    if (PaintInfo.Column.Index >= abDieserSpalte) then
    begin
      Windows.DrawTextW(PaintInfo.TargetCanvas.Handle, PWideChar(Text),
        Length(Text), rNormalText, DT_LEFT or DT_TOP or DT_NOPREFIX or DT_SINGLELINE);
      OffsetRect(rNormalText, 0, -2);

      // typ. Wachstum zeichnen
      rTypWachstum := rNormalText;
      Text := 'typ. Wachstum';
      GetTextExtentPoint32W(PaintInfo.TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
      if (PaintInfo.Column.Index > -1) and (Size.cx > (rTypWachstum.Right - rTypWachstum.Left)) then
        Text := ShortenString(PaintInfo.TargetCanvas.Handle, Text, (rTypWachstum.Right - rTypWachstum.Left), 0);
      Windows.DrawTextW(PaintInfo.TargetCanvas.Handle, PWideChar(Text),
        Length(Text), rTypWachstum, DT_LEFT or DT_VCENTER or DT_NOPREFIX or DT_SINGLELINE);

      // unteren Bereich zeichnen
      rResultText := rNormalText;
      //rResultText.Right := rResultText.Left + ((rResultText.Right-rResultText.Left) div 2) - PaintInfo.Column.Margin;
      rResultText.Right := rResultText.Left + leftPartWidth - PaintInfo.Column.Margin;
      Text := 'Kultur';
      GetTextExtentPoint32W(PaintInfo.TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
      if (PaintInfo.Column.Index > -1) and (Size.cx > (rResultText.Right - rResultText.Left)) then
        Text := ShortenString(PaintInfo.TargetCanvas.Handle, Text, (rResultText.Right - rResultText.Left), 0);
      Windows.DrawTextW(PaintInfo.TargetCanvas.Handle, PWideChar(Text),
        Length(Text), rResultText, DT_LEFT or DT_BOTTOM or DT_NOPREFIX or DT_SINGLELINE);

      rBemerkung := rNormalText;
      //rBemerkung.Left := rBemerkung.Left + ((rBemerkung.Right-rBemerkung.Left) div 2) + PaintInfo.Column.Margin;
      rBemerkung.Left := rBemerkung.Left + leftPartWidth + PaintInfo.Column.Margin;
      Text := 'Bemerkung';
      GetTextExtentPoint32W(PaintInfo.TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
      if (PaintInfo.Column.Index > -1) and (Size.cx > (rBemerkung.Right - rBemerkung.Left)) then
        Text := ShortenString(PaintInfo.TargetCanvas.Handle, Text, (rBemerkung.Right - rBemerkung.Left), 0);
      Windows.DrawTextW(PaintInfo.TargetCanvas.Handle, PWideChar(Text),
        Length(Text), rBemerkung, DT_LEFT or DT_BOTTOM or DT_NOPREFIX or DT_SINGLELINE);
    end else
    begin
      // Normalen Text ausgeben
      Windows.DrawTextW(PaintInfo.TargetCanvas.Handle, PWideChar(Text),
        Length(Text), rNormalText, DT_LEFT or DT_VCENTER or DT_NOPREFIX or DT_SINGLELINE);
    end;
  end;
end;
So oder so ähnlich sollte es klappen.

jaenicke 20. Jun 2011 17:14

AW: Mehrzeiliger Header im VST
 
Dafür braucht man den DrawTree nicht, ich habe das auch im TVirtualStringTree selbst gezeichnet. Und zwar alles. ;-)

Ob er sinnvoller dafür ist, weiß ich nicht.

madas 21. Jun 2011 12:24

AW: Mehrzeiliger Header im VST
 
Zitat:

Zitat von jaenicke (Beitrag 1107497)
Dafür braucht man den DrawTree nicht, ich habe das auch im TVirtualStringTree selbst gezeichnet. Und zwar alles. ;-)

Da wir auch die Zellen mit den Daten in der gleichen Unterteilung anzeigen, wie beim Header, hatten wir uns für den VirtuakDrawTree entschieden. Ob das nun auch alles mit dem VST geht kann ich leider nicht sagen. Aber wie Du ja schreibst, hast Du es hingekriegt.

Also wenn Du so ein "Alles"-Könner bist, dann kannst Du ja sicher David od. Trille mit Deinem Quell-Code beglücken, denn Aussagen wie "ich habe das auch im TVirtualStringTree selbst gezeichnet. Und zwar alles." werden den beiden nicht viel weiterhelfen. :)

Grüße.

jaenicke 21. Jun 2011 22:03

AW: Mehrzeiliger Header im VST
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das ist kein großes Problem, da das ganze selbstverständlich gekapselt ist. Die aktuellen Quelltexte möchte ich nicht posten, da es sich nicht um ein Open Source Projekt handelt. Ich poste aber einmal die alte, noch nicht so schön geschriebene Variante von vor 5 Jahren. Die entsprechende Unit liegt im Anhang.

Benutzung:
Die Unit GraphicUtilities in die uses, in Header.Options des VirtualStringTrees hoOwnerDraw aktivieren und diese beiden Events füllen:
Delphi-Quellcode:
procedure TYourForm.YourVirtualStringTreeAdvancedHeaderDraw(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
  const Elements: THeaderPaintElements);
begin
  DrawListViewHeader(Sender, PaintInfo, Elements, HOVER_TYPE_DOUBLE);
end;

procedure TYourForm.YourVirtualStringTreeHeaderDrawQueryElements(Sender: TVTHeader;
  var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements);
begin
  Elements := [hpeBackground, hpeText];
end;
Ich denke das zeigt wie es funktioniert, mehrzeilig usw. müsste noch eingebaut werden.

madas 22. Jun 2011 10:37

AW: Mehrzeiliger Header im VST
 
Zitat:

Zitat von jaenicke (Beitrag 1107637)
Das ist kein großes Problem, da das ganze selbstverständlich gekapselt ist. Die aktuellen Quelltexte möchte ich nicht posten, da es sich nicht um ein Open Source Projekt handelt. Ich poste aber einmal die alte, noch nicht so schön geschriebene Variante von vor 5 Jahren. Die entsprechende Unit liegt im Anhang.

Benutzung:
Die Unit GraphicUtilities in die uses, in Header.Options des VirtualStringTrees hoOwnerDraw aktivieren und diese beiden Events füllen:
Delphi-Quellcode:
procedure TYourForm.YourVirtualStringTreeAdvancedHeaderDraw(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
  const Elements: THeaderPaintElements);
begin
  DrawListViewHeader(Sender, PaintInfo, Elements, HOVER_TYPE_DOUBLE);
end;

procedure TYourForm.YourVirtualStringTreeHeaderDrawQueryElements(Sender: TVTHeader;
  var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements);
begin
  Elements := [hpeBackground, hpeText];
end;
Ich denke das zeigt wie es funktioniert, mehrzeilig usw. müsste noch eingebaut werden.

Also wenn ich beim Überfliegen Deiner Unit nichts übersehen habe, dann frag ich mich, wo der Teil mit dem mehrzeiligen Header sein soll. :?:

Mehr als einen Gradient als Hintergrundbild zu zeichnen macht die Unit doch nicht.

Grüße.

PS: Hier was rauskommt, wenn man obigen Quelltext verwendet (Header und eine Datenzelle).

http://img847.imageshack.us/img847/4314/vstheader.jpg

madas 1. Jul 2011 07:01

AW: Mehrzeiliger Header im VST
 
@David: Konntest Du zu einer Lösung Deines Problems kommen?

jaenicke 1. Jul 2011 07:17

AW: Mehrzeiliger Header im VST
 
Zitat:

Zitat von madas (Beitrag 1107684)
Also wenn ich beim Überfliegen Deiner Unit nichts übersehen habe, dann frag ich mich, wo der Teil mit dem mehrzeiligen Header sein soll. :?:

Mehr als einen Gradient als Hintergrundbild zu zeichnen macht die Unit doch nicht.

Ich habe doch geschrieben, dass das noch eingebaut werden muss. Ich wollte nur zeigen wie man generell selbst den Header zeichnet. Und die eine Methode auszutauschen, damit der Text eben mehrzeilig ist, ist ja nun keine große Sache...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz