Delphi-PRAXiS
Seite 1 von 2  1 2      

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 TButton mit zwei Captions und unterschiedlichem Font (https://www.delphipraxis.net/144734-tbutton-mit-zwei-captions-und-unterschiedlichem-font.html)

Phoner 15. Dez 2009 13:19


TButton mit zwei Captions und unterschiedlichem Font
 
Hallo,

ich habe zwei TLabel-Komponenten als Unter-Komponenten eines TButtons definiert. Auf diese Art kann ich zwei Caption-Zeilen simulieren, jeweils mit unterschiedlichem Font. Rein optisch sieht das erst mal OK aus.
Klicke ich den Button jedoch so an, dass ich ein drüber liegendes Label treffe, so sehe ich kein optisches Feedback des Buttons.
Meine Frage lautet also: Wie kann ich eine Control visuell sichtbar schalten, aber alle Mausoperationen sollen direkt vom Parent (hier dem TButton) behandelt werden. Klar kann ich das OnClick-Ereignis entsprechend auf die gleiche Funktion setzen, aber mir fehlt die optische Umsetzung, dass der Button gedrückt wird, wenn ich ein darüber liegendes Control treffe.

Oder fällt jemand eine andere Möglichkeit ein, einen TButton mit zwei Captions und jeweils unterschiedlichem Font zu erstellen? Ich möchte keine Bitmaps benutzen.

himitsu 15. Dez 2009 13:31

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Warum zeichnest du dann den Text einfach nicht selber?

Ansonsten mußt du in den Labels die Windowsbotschaften (das Klicken) abfangen, an den Button weiterleiten und eventuell noch die Klickposition umrechnen.

shmia 15. Dez 2009 13:39

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Zitat:

Zitat von Phoner
Klar kann ich das OnClick-Ereignis entsprechend auf die gleiche Funktion setzen, aber mir fehlt die optische Umsetzung, dass der Button gedrückt wird, wenn ich ein darüber liegendes Control treffe.

Nicht auf den gleichen Eventhandler setzen sondern auf:
Delphi-Quellcode:
proecdure TMyObscureDoubleLabelButton.LabelClicked(Sender:TObject);
begin
   self.Click;
end;

Phoner 15. Dez 2009 14:06

Re: TButton mit zwei Captions und unterschiedlichem Font
 
@himitsu
Wie zeichne ich denn den Text direkt drauf? Fleucht da irgendwo ein Sample rum?

@shmia
Ja, da mag schöner sein, aber prinzipiell ist das Auswerten des Events nicht das Problem.

himitsu 15. Dez 2009 14:14

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Standardmäßig hat ein Button ja kein OnPaint-Ereignis, aber notfalls könnt man das umgehen.

- man zeichne ein Bild mit dem gewünschten Text
- lege es in einer ImageList ab
- und weise es dem Button zu

dieses Bild kann man auch live, z.B. im OnCreate und bei Änderung der Captions zeichnen
und halte die ImageList als Subkomponente des Buttons.

shmia 15. Dez 2009 14:44

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Zitat:

Zitat von Phoner
@shmia
Ja, da mag schöner sein, aber prinzipiell ist das Auswerten des Events nicht das Problem.

Es geht doch gar nicht um Schönheit, sondern um Funktionalität.
Was wäre, wenn bei deinem Button Enabled=False wäre.
Dann würde ein Klick auf das Label das Event des Buttons aufrufen, was bestimmt nicht erwünscht ist.
Durch Aufruf der Click-Methode wird genau das Gleiche gemacht, das auch passiert wenn man den Button per Maus anklickt.
In der OH steht auch, dass zusätzlich das Modal-Result des Formulars gesetzt wird.
Ausserdem möchtest du den Button vielleicht auch zusammen mit Actions einsetzen.
Auch hier stellt die Click-Methode sicher, dass die Action über den ActionLink ausgeführt wird.

HJay 16. Dez 2009 19:28

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Sehr interessantes Thema! Ich versuche mich gerade in Vererbung und Objekterzeugung einzuarbeiten und bin auch an einer Lösung interessiert.

Erste Idee wäre gewesen:

Delphi-Quellcode:
TMyButton = class(TButton)
protected
  procedure Paint(var Message: TMessage); message WM_PAINT;
public
  UpperLine : String;
  LowerLine : String;
end;

procedure TMyButton.Paint(var Message: TMessage);
begin
  Canvas.TextOut(0, 0, UpperLine);  // Canvas gibt es aber leider nicht...
  Canvas.TextOut(0, 12, LowerLine);
end;
1) Würde das funktionieren mit WM_PAINT?

2) Nur leider hat TButton kein Canvas. Kann man mit dem "Handle" irgendwie auf die Fläche des Buttons zeichnen/schreiben? Falls ja, wie geht das?

3) Oder noch anders: Kann man irgendwie auf elegante Art ein Canvas in der Methode "nachrüsten", also bei Create erzeugen und als TCanvas zur Verfügung stellen?

Ich bin gespannt!

HJay 18. Dez 2009 19:02

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Ich habe Fortschritte gemacht, aber leider noch ein Problem: Die beiden Captions werden korrekt gezeichnet, aber nachdem man draufgedrückt hat, bleibt der Button leer. Sobald die Form eine andere Paint-Message erhält, zeichnet er sich wieder. Was habe ich vergessen? Auf welche Message müsste ich noch reagieren?

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
  TMyButton = class(TButton)
  protected
    procedure Paint(var Msg: TMessage); message WM_PAINT;
  private
    FCanvas: TCanvas;
  public
    CaptionTop : String;
    CaptionBottom : String;

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    property Canvas: TCanvas read FCanvas;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    MyButton : TMyButton;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyButton }

constructor TMyButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Parent := AOwner as TWinControl;
  FCanvas := TCanvas.Create;
  FCanvas.Handle := GetDC(Self.Handle);;
end;

destructor TMyButton.Destroy;
begin
  FCanvas.Free;
  inherited;
end;

procedure TMyButton.Paint(var Msg: TMessage);
begin
  inherited;
  Canvas.Pen.Color := clBlack;
  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(2, 2, CaptionTop);
  Canvas.Font.Style := Canvas.Font.Style + [fsBold]; // zweite Zeile anders formatiert
  Canvas.Textout(2, 2 + Canvas.TextHeight(CaptionTop), CaptionBottom);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyButton := TMyButton.Create(Self);
  MyButton.Left  := 16;
  MyButton.Top   := 48;
  MyButton.Height := 48;
  MyButton.CaptionTop   := 'upper text';
  MyButton.CaptionBottom := 'lower text';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  MyButton.Free;
  inherited;
end;

end.

HJay 2. Jan 2010 13:48

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Hat keiner von den Kennern hier eine Lösung? Ist echt schade, dass es FAST geht, aber dann an so einer Kleinigkeit scheitert. Wäre echt dankbar, wenn jemand noch einmal einen Blick drauf werfen könnte, denn das gleich Prinzip wäre für viele andere Komponenten ohne eigenen Canvas ja auch brauchbar!

Danke im voraus! (was ein Danke im nachhinein nicht ausschließen soll :-)

SirThornberry 2. Jan 2010 14:10

Re: TButton mit zwei Captions und unterschiedlichem Font
 
Mir fällt auf das du im OnCreate einfach den Parent setzt und den Owner auf WinControl castest.
Das ist der völlig falsche Weg. Wenn der Owner zum Beispiel kein WinControl ist knallt es. Oder wenn der Owner noch keinen Parent hat wird in aller Regel das Handle auch noch nicht existieren und somit wird auch der Button noch kein Handle haben etc.
Was spricht dagegen das Canvas-Handle erst im OnPaint zu besorgen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:40 Uhr.
Seite 1 von 2  1 2      

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