AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

[VCL] Textbreite in Pixeln ohne Canvas ermitteln?

Ein Thema von Der schöne Günther · begonnen am 21. Okt 2014 · letzter Beitrag vom 23. Okt 2014
Antwort Antwort
Der schöne Günther

Registriert seit: 6. Mär 2013
6.093 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

[VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 21. Okt 2014, 22:24
Ich möchte die Pixelbreite eines Textes (z.B. die Caption eines TButton ) ermitteln. Ich finde immer nur Beispiele welche die Methode TextWidth(..) eines TCanvas benutzen.

Im Falle eines TButton habe ich leider keinen Canvas. Was tue ich dann?
  Mit Zitat antworten Zitat
Darlo

Registriert seit: 28. Jul 2008
Ort: München
1.196 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 21. Okt 2014, 22:40
Quick and dirty habe ich das gestern (selbes Problem ) so gelöst.
Delphi-Quellcode:
var
lab: TLabel;
begin
lab := TLabel.create(form1);
lab.autosize := true;
lab.font := button1.font;
lab.caption := button1.caption;
result := lab.width;
lab.free;
end;
Philip
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#3

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 21. Okt 2014, 23:19
Man kann sich auch den Canvas vom Desktop holen:
Delphi-Quellcode:
function windowsDesktopCanvas: TCanvas;
var
DC: HDc;
begin
 DC := getWindowDC ( GetDeskTopWindow() );
 result := TCanvas.Create;
 result.Handle := DC;
end;
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#4

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 21. Okt 2014, 23:51
Oder man macht das wie dat FMX am Anfang und erstellt sich einmal ein internes Canvas, das man dann für diese Berechnungen benutzt.

Ich finde immer nur Beispiele welche die Methode TextWidth(..) eines TCanvas benutzen.
Vielleicht solltest du lernen die SuFu richtig zu benutzen?
Es ist garnicht so selten etwas zu finden, wo kein TCanvas benutzt wird, indem man direkt die WinAPIs benutzt, welche TCanvas.TextWidth intern benutzt.
Oder wo man sich Ein TCanvas auf dem Desktop erstellt, ohne eigene Zeichenfläche ala TBitmap.

TextWidthTextWidth
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.039 Beiträge
 
Delphi XE2 Professional
 
#5

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 21. Okt 2014, 23:57
Delphi-Quellcode:
FUNCTION TextExtent(FontHandle:HFont; const S:String):TSize;
var DC:HDC; OldFont:HFONT;
begin
   DC:=GetDC(0);
   try
      OldFont:=SelectObject(DC,FontHandle);
      GetTextExtentPoint32(DC,S,Length(S),Result);
      SelectObject(DC,OldFont);
   finally
      ReleaseDC(0,DC);
   end;
end;
Delphi-Quellcode:
FUNCTION TextWidth(FontHandle:HFont; const S:String):Integer;
begin
   result:=TextExtent(FontHandle,S).cx;
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#6

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 22. Okt 2014, 00:38
Lösen diese APIs überhaupt Exceptions aus?

IMHO geben die doch nur FehlerCodes zurück, welche man auswerten sollte.

Und dafür kann man dann auf das Try-Finally verzichten. Aber wenn es da wirklich mal knallen sollte, dann ist eh alles zuspät und das System ist so defekt, daß man die Anwendung sowieso beenden kann.



PS: Man kann sowas in der CL auch nachtragen/ändern lassen, wenn man bessere/alternative Lösungen kennt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (22. Okt 2014 um 00:44 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.093 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 22. Okt 2014, 12:04
Quick and dirty habe ich das gestern (selbes Problem ) so gelöst.
So werde ich das dann auch tun. Den im Endeffekt scheint sich das TLabel in seiner AdjustBounds-Methode auch wieder den Desktop-Canvas zu holen und tut dann irgendwelche mir unverständlichen Dinge damit.

Deshalb nehme ich jetzt auch ein Hilfslabel, schaue wie breit das werden würde und übernehme das dann für meinen Button.

Falls es noch interessiert, in Form einer Hilfsklasse sieht das dann so aus:
Delphi-Quellcode:
uses Helper.Vcl.ButtonAutosize;
[...]
Button1.Caption := 'Hallo Welt'; // Breite passt sich automatisch an

Delphi-Quellcode:
///   <summary>
///      <para>Überschreibt <c>Vcl.StdCtrls.TButton</c> dahingehend, dass er sich
///      wie ein <c>TLabel</c> mit <c>AutoSize=True</c> verhält: Ändert man
///      die <c>Caption</c>, passt sich seine Breite an.</para>
///      <para>Weiterhin kann für eine <c>TCaption</c> auch die Pixelbreite für
///      eine zu spezifizierende Schriftgröße abgefragt werden</para>
///   </summary>
///   <remarks>
///      <para>Wurde nicht mit Zeilenumbrüchen in der Caption getestet</para>
///      <para>Wenn man die AutoSize nicht will, kann man die neue Property
///         <c>CaptionNoAutoSize</c> verwenden
///      </para>
///   </remarks>
unit Helper.Vcl.ButtonAutoSize;

interface uses Vcl.StdCtrls, Vcl.Controls, Vcl.Graphics;

type

   /// <summary>
   /// Überschreibt den Setter der Property <c>Caption</c> sodass
   /// die Breite des Buttons wie bei einem Label mit <c>AutoSize = True</c>
   /// dynamisch angepasst wird.
   /// </summary>
   /// <remarks>
   /// Es wird nur die Eigenschaft <c>ClientWidth</c> angepasst
    /// </remarks>
   TButtonHelper = class helper for Vcl.StdCtrls.TButton
      private
         procedure setInheritedCaption(const Value: TCaption);
         function getCaption(): TCaption;

      protected
         procedure setCaption(const Value: TCaption); virtual;

      public // properties
         property Caption: TCaption
            read getCaption
            write setCaption;

         property CaptionNoAutosize: TCaption
            read getCaption
            write setInheritedCaption;
   end;

   TCaptionHelper = record helper for Vcl.Controls.TCaption
      private class var
         tempLabel: TLabel;
      private class
         destructor Destroy();
      private class
         procedure checkInitTempLabel(); static;


      function ToString(): String;
      function getPixelWidth(const forFont: TFont): Integer; overload;
   end;


implementation


{ TButtonHelper }

function TButtonHelper.getCaption(): TCaption;
begin
   Result := inherited Caption;
end;

procedure TButtonHelper.setCaption(const Value: TCaption);
const
   // Das ist der Rand den das RAD Studio XE7 standardmäßig um die automatisch
   // erstellte Caption "Button1" eines TButton macht. Die Breite (nicht ClientWidth)
   // scheint standardmäßig bei 75px zu liegen:
   // Vcl.StdCtrls.TCustomButton.Create(..)
   someOffsetPx: Integer = 37;
begin
   inherited Caption := Value;
   ClientWidth := Value.getPixelWidth(Font) + someOffsetPx;
end;

procedure TButtonHelper.setInheritedCaption(const Value: TCaption);
begin
   inherited Caption := Value;
end;

{ TCaptionHelper }

class procedure TCaptionHelper.checkInitTempLabel();
begin
   if not Assigned(tempLabel) then begin
      tempLabel := TLabel.Create(nil);
      tempLabel.AutoSize := True;
   end;
end;

class destructor TCaptionHelper.Destroy();
begin
   tempLabel.Free();
end;


function TCaptionHelper.getPixelWidth(const forFont: Vcl.Graphics.TFont): Integer;
begin
   Assert( Assigned(forFont) );
   checkInitTempLabel();
   tempLabel.Font := forFont;
   tempLabel.Caption := self;

   Result := tempLabel.Width;
end;

function TCaptionHelper.ToString(): String;
begin
   Result := self;
end;

end.
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.039 Beiträge
 
Delphi XE2 Professional
 
#8

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 23. Okt 2014, 00:06
Lösen diese APIs überhaupt Exceptions aus?

IMHO geben die doch nur FehlerCodes zurück, welche man auswerten sollte.

Und dafür kann man dann auf das Try-Finally verzichten. Aber wenn es da wirklich mal knallen sollte, dann ist eh alles zuspät und das System ist so defekt, daß man die Anwendung sowieso beenden kann.
Eigentlich hast du Recht. Laut OH sollten die benutzten Funktionen keine Exceptions auslösen.
Aber ich habe mir das nicht selbst ausgedacht, sondern aus den Source-Codes von XE2 abgeschrieben.
Ich denke, die, die das so geschrieben haben, verstehen mehr von der Materie als ich, also hab ich das unverändert übernommen.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#9

AW: [VCL] Textbreite in Pixeln ohne Canvas ermitteln?

  Alt 23. Okt 2014, 00:13
Bei manchen derer Codes denk ich eher das Gegenteil
und hab manchmal das Gefühl die benutzen ihre eigenes Zeugs nicht, denn sonst wären einige Dinge bestimmt benutzerfreundlicher. (z.B. das Suchen in der RTTI, was garnicht vorhanden ist)


Nja, zumindestens ist es mal nicht falsch, einen Resourcen-Schtzblock einzubauen, sondern nur bissl "unnötig",
abe natürlich wurde dafür dann die komplette "richtige" Fehlerbehandlung vergessen, wie an vielen anderen Stellen auch. (TMemo und der Zugriff auf nichtexistierende Zeilen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:41 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