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 TTabControl, XP-Style, OwnerDraw (https://www.delphipraxis.net/78247-ttabcontrol-xp-style-ownerdraw.html)

EConvertError 1. Okt 2006 19:18


TTabControl, XP-Style, OwnerDraw
 
Hallo!

Ich verwende ein TTabControl mit XP-Style.
Jetzt möchte ich hinter einige Labels (die tabellenförmig angeordnet sind) mit FillRect() einen Hintergrund malen. Stelle ich ich die OwnerDraw-Property auf true, funktioniert das auch, aber das TabControl wird ohne XP-Style gemalt. Gezeichnet wird im OnDraw-Ereignis.

Die Zeichenoperation in MainForm.OnPain zu verschieben hat ebenfalls nicht zum gewünschten Erfolg geführt, da dann zwar das TabControl noch mit XP-Style gezeichnet wurde, meine Zeichenbefehle aber ignoriert wurden.

Hier [codeproject] wird zwar eine Lösung angeboten, aber ich bin der Sprache C++ leider nicht so mächtig. Vielleicht kann da jemand helfen oder hat eine andere Lösung...

Vielen Dank,
Andreas

EConvertError 3. Okt 2006 15:26

Re: TTabControl, XP-Style, OwnerDraw
 
Keiner eine Idee, wie man OwnerDraw gemeinsam mit XP-Style verwenden könnte?

Olli 3. Okt 2006 15:44

Re: TTabControl, XP-Style, OwnerDraw
 
Zitat:

Zitat von EConvertError
Die Zeichenoperation in MainForm.OnPain zu verschieben hat ebenfalls nicht zum gewünschten Erfolg geführt, da dann zwar das TabControl noch mit XP-Style gezeichnet wurde, meine Zeichenbefehle aber ignoriert wurden.

Sicher? Vielleicht mußt du nur stattdessen WM_ERASEBKGND überschreiben nicht WM_PAINT?!

EWeiss 3. Okt 2006 15:48

Re: TTabControl, XP-Style, OwnerDraw
 
Zitat:

Zitat von EConvertError
Keiner eine Idee, wie man OwnerDraw gemeinsam mit XP-Style verwenden könnte?

Wie der Name schon sagt OwnerDraw
Der Programmiere zeichnet selbst oder bestimmt was an x,y position geschieht.
Wenn du das Property einschaltest wird die interne Draw funktion des Control ausgeschaltet.

Was bedeutet wirds es eingeschaltet mußt du selbst dafür sorgen was dort gezeichnet wird
das schließ den XP-Style mit ein.

Das von dir gezeigte Sample macht nichts anderes.
Es stellt den container für die eigens kreierten Drawfunktionen dar.

Gruß

EConvertError 4. Okt 2006 18:57

Re: TTabControl, XP-Style, OwnerDraw
 
Vielen Dank!

Ich weiß wirklich nicht, was ich diesmal anders gemacht habe, als zuvor, aber jetzt zeichnet er auch, wenn es im OnPaint-Event passiert. Ich versteh die Welt nicht mehr. :?

Mein Code:
Delphi-Quellcode:
procedure TfrmMain.FormPaint(Sender: TObject);
var
  ARect: TRect;
begin
  with AdapterTabControl.Canvas do
  begin
    ARect.TopLeft := CurrentRateLabel.BoundsRect.TopLeft;           //die beiden labels befinden
    ARect.BottomRight := CurrentUploadLabel.BoundsRect.BottomRight; //sich in einer "Zeile"

    Brush.Style := bsClear;
    Brush.Color := clSkyBlue;

    FillRect(ARect); //Sollte eigentlich hinter den Labels malen, nicht sie übermalen
  end;
end;
Leider gibt es noch ein Problem: Obiger Code übermalt die Labels anstatt ihnen einen Hintergrund zu verpassen. Dies geschieht auch, wenn ich OwnerDraw aktiviere und im dementsprechenden Event male.

Wisst ihr diesbezüglich Rat?

Zitat:

Wie der Name schon sagt OwnerDraw
Der Programmiere zeichnet selbst oder bestimmt was an x,y position geschieht.
Wenn du das Property einschaltest wird die interne Draw funktion des Control ausgeschaltet.
Dem stimme ich grundsätzlich zu, aber da ich nicht das gesamte Control selbst zeichnen muss, war es für mich nicht ersichtlich, dass auch der XP-Style abgeschaltet wird.

Hoffentlich wisst ihr eine Lösung,
Andreas

EConvertError 5. Okt 2006 19:10

Re: TTabControl, XP-Style, OwnerDraw
 
Niemand eine Idee?

Olli 6. Okt 2006 00:06

Re: TTabControl, XP-Style, OwnerDraw
 
Zitat:

Zitat von EConvertError
Niemand eine Idee?

Also Labels sind mal grundsätzlich keine Fenster, haben also weder eigenes Handle noch eigene Fensterfunktion. Entsprechend muß die Verarbeitung in der Fensterfunktion des Forms geschehen. Eine Methode wäre also alle TLabel durch TStatic zu ersetzen ...

... andererseits kannst du die Ursprungsfunktion ja malen lassen und hängst dich einfach dahinter.

EConvertError 6. Okt 2006 17:35

Re: TTabControl, XP-Style, OwnerDraw
 
Delphi-Quellcode:
Also Labels sind mal grundsätzlich keine Fenster, haben also weder eigenes Handle noch eigene Fensterfunktion. Entsprechend muß die Verarbeitung in der Fensterfunktion des Forms geschehen. Eine Methode wäre also alle TLabel durch TStatic zu ersetzen ...
Die Verarbeitung im OnPaint-Event ist eigentlich ok für mich, aber die Labels werden übermalt und sind gar nicht mehr zu sehen. Ich will aber nur einen Hintergrund zu den Labels malen.

Zitat:

.. andererseits kannst du die Ursprungsfunktion ja malen lassen und hängst dich einfach dahinter.
Ich verstehe nicht ganz, was du damit meinst?

Wenn du Überschreiben der Paint Methode in Verbindung mit einer neuen Komponenten meinst, so sieht es hierbei nicht so gut aus, denn der Hintergrund soll sich ja über mehrere Labels erstrecken.

Wenn es gar keine andere Möglichkeit gibt, werde ich allerdings einmal ein Control schreiben, das meine tabellenförmig angeordneten Labels erstetzt. Aber eben erst irgendwann einmal...
Deshalb wäre ich froh, wenn es eine einfachere Lösung gibt.

Vielen Dank,
Andreas

Olli 6. Okt 2006 19:35

Re: TTabControl, XP-Style, OwnerDraw
 
Zitat:

Zitat von EConvertError
Zitat:

Zitat von Olli
Also Labels sind mal grundsätzlich keine Fenster, haben also weder eigenes Handle noch eigene Fensterfunktion. Entsprechend muß die Verarbeitung in der Fensterfunktion des Forms geschehen. Eine Methode wäre also alle TLabel durch TStatic zu ersetzen ...

Die Verarbeitung im OnPaint-Event ist eigentlich ok für mich, aber die Labels werden übermalt und sind gar nicht mehr zu sehen. Ich will aber nur einen Hintergrund zu den Labels malen.

... und genau deshalb schlug ich vor, daß du den Hintergrund dann malst wenn er gemalt werden sollte, nämlich im Erase-Event. Siehe oben!

EConvertError 8. Okt 2006 18:23

Re: TTabControl, XP-Style, OwnerDraw
 
Die Verarbeitung im Erase-Event funktioniert leider ebenfalls nicht.
Mein Code:
Delphi-Quellcode:
procedure TfrmMain.WMEraseBkgnd(var Msg: TWMEraseBkgnd);
var
  ARect: TRect;
begin
 with AdapterTabControl.Canvas do
  begin
    ARect.TopLeft := CurrentRateLabel.BoundsRect.TopLeft;
    ARect.BottomRight := CurrentUploadLabel.BoundsRect.BottomRight;

    Brush.Style := bsClear;
    Brush.Color := clSkyBlue;

    FillRect(ARect);
  end;
Die Labels werden trotzdem einfach übermalt (außer wenn man die Größe der Form verändert, danach aber wieder das -leider- gewohnte Bild der übermalten Labels).

Andreas

EConvertError 10. Okt 2006 15:48

Re: TTabControl, XP-Style, OwnerDraw
 
*push*

Sidorion 10. Okt 2006 16:39

Re: TTabControl, XP-Style, OwnerDraw
 
Bleib beim Owner-Draw und benutze für die anderen Tabs die Funktionen aus der Unit Themes. Da gibbet den ThemeManager, der Dir für (fast) jedes zu zeichnende Element die passende XP-Bitmap malt. Auch Texte lassen sich so im XP-Style darstellen.
Muss quasi den ThemeManager frage, ob XP-Themes aktiviert sind. Wenn nein rufst Du inherited, wenn ja, zeichnest Du die XP-Elemente. Kannst ja auch mal in die Quellen von TTabSheet reinschaun, weil bei den VCL-Komponenten malen die Borlands den XP-Style auch selber.

EConvertError 11. Okt 2006 17:03

Re: TTabControl, XP-Style, OwnerDraw
 
Hmmm, danke!

Ich muss ehrlich sagen, dass ich mit dem Thememanager (und der Themes Unit) noch nie gearbeitet habe. Das hört sich nach viel Arbeit an. Vor allem wenn man bedenkt, dass es hier nur um Eye-Candy geht und nicht um wichtige Funktionalität.

Zitat:

Kannst ja auch mal in die Quellen von TTabSheet reinschaun, weil bei den VCL-Komponenten malen die Borlands den XP-Style auch selber.
In welcher Methode wird da gemalt? Ich habe das nicht gefunden...
Weil zur Zeit habe ich keinen Plan, wie das funktionieren soll...

Alles in allem scheint es mir auch etwas viel Aufwand sein, nur für ein wenig Eye-Candy.

Ich hoffe allerdings, dass die TPainBox mit XP-Styles funktioniert, denn das brauche ich wirklich...

Vielen Dank,
Andreas

DGL-luke 11. Okt 2006 17:18

Re: TTabControl, XP-Style, OwnerDraw
 
TPainBox? :lol:

Aber dass die TPaintbox nicht funktioniert, kann ich mir nicht vorstellen, die repräsentiert ja nur ienen Ausschnitt des Form-Canvas.

EConvertError 11. Okt 2006 17:41

Re: TTabControl, XP-Style, OwnerDraw
 
Nein, nein, bitte nicht missverstehen!

Ich habe nicht behauptet, dass die TPaintBox nicht funktioniert. Allerdings sind mir in Zusammenhang mit den XP-Styles schon die unglaublichsten Sachen passiert...

Deshalb hoffe ich, dass es da kein Problem geben wird....

Ansonsten melde ich mich natürlich,
Andreas

oki 11. Okt 2006 19:20

Re: TTabControl, XP-Style, OwnerDraw
 
Zitat:

Zitat von EConvertError
Ich muss ehrlich sagen, dass ich mit dem Thememanager (und der Themes Unit) noch nie gearbeitet habe. Das hört sich nach viel Arbeit an. Vor allem wenn man bedenkt, dass es hier nur um Eye-Candy geht und nicht um wichtige Funktionalität.
Andreas

keine Panik, einfach ThemeManager runter laden, istallieren, Kompo auf Mainform, fertig.

Hab selbst gedacht ist hölle schwer, aber echt kein Problem!

probier mal unter Soft Gems

Gruß oki

edit: uuups, wenn du D7 hast, ist das eh schon dabei (hab ich gehört).

Sidorion 11. Okt 2006 19:30

Re: TTabControl, XP-Style, OwnerDraw
 
Und die Zeichenroutinen beim ThemeManager ähneln stark den normalen, wie z.B.:DrawEdge, nur dass die Parameter verständlicher sind und man nicht so viel zeichnen muss, wie bei den oldscool 3d effekten.
Im Endeffekt ists weniger code.
Hier mal ein Bleistift:
Delphi-Quellcode:
  Procedure DrawBtn( _sText: String;
                     _bDown: Boolean);
  Var
    oEleDet: TThemedElementDetails;
  Begin
    If ThemeServices.ThemesEnabled //hier mit Themes
    Then Begin
// ab her wird das Element ermittelt
      If _bDown
      Then oEleDet:=ThemeServices.GetElementDetails(tbPushButtonPressed)
      Else Begin
        If _iIndex=iMouseOver
        Then oEleDet:=ThemeServices.GetElementDetails(tbPushButtonHot)
        Else oEleDet:=ThemeServices.GetElementDetails(tbPushButtonNormal);
      End;
//hier ist dann das Zeichnen
      ThemeServices.DrawElement(Canvas.Handle,oEleDet,oRect);
      ThemeServices.DrawText(Canvas.Handle,oEleDet,
                             _sText,oRect,DT_CENTER Or DT_VCENTER,0);
    End Else Begin //Hier ohne
      If _bDown
      Then DrawEdge(Canvas.Handle,oRect,BDR_SUNKEN,
                    BF_RECT Or BF_SOFT Or BF_ADJUST Or BF_MIDDLE)
      Else DrawEdge(Canvas.Handle,oRect,BDR_RAISED,
                    BF_RECT Or BF_SOFT Or BF_ADJUST Or BF_MIDDLE);
      Canvas.Brush.Color:=clBtnFace;
      If _iIndex=iMouseOver
      Then Canvas.Font.Color:=clHighlightText
      Else Canvas.Font.Color:=clWindowText;
      DrawText(Canvas.Handle,@_sText[1],1,oRect,DT_CENTER Or DT_VCENTER);
    End;
  End;
Wobei diese Prozedur in eine andere eingebettet ist und oRect ist ne variable der äusseren...
die tbXXX Konstanten findest Du auch in der Unit Themes ...

EConvertError 13. Okt 2006 07:06

Re: TTabControl, XP-Style, OwnerDraw
 
Danke!

Das werde ich mir mal zu Gemüte führen!
Bei Problemen melde ich mich wieder!

Vielen Dank,
Andreas


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

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