Delphi-PRAXiS
Seite 2 von 6     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Stringlänge parsen (https://www.delphipraxis.net/193739-stringlaenge-parsen.html)

EWeiss 4. Sep 2017 13:56

AW: Stringlänge parsen
 
Zitat:

(<-- Verwirrender Satz aber ich hoffe du weißt was ich meine )
jo ich weis schon ;) :-D

gruss

Neutral General 4. Sep 2017 13:58

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380267)
Zitat:

(<-- Verwirrender Satz aber ich hoffe du weißt was ich meine )
jo ich weis schon ;) :-D

gruss

Gut. Denn das heißt:
Zitat:

Zitat von EWeiss
Ich mache es hier mit aber erst dann wenn ich den längsten String ermittelt habe. (einmalig..)

wird nicht funktionieren ;)

EWeiss 4. Sep 2017 14:03

AW: Stringlänge parsen
 
Zitat:

Meine oben genannte Funktion gibt die Länge eines Strings in Pixeln zurück.
Mit QuickSort kannst du dann sehr einfach den längsten String raussuchen.
Ich sagte doch, ich verwende GDI+ und mixe das nicht mit der Winapi.
mit meiner Funktion bekomme ich die exakte länge über boundingBox noch genauer geht's nicht.

Wenn es nicht mit einmalig geht dann muss ich wohl oder übel alle Strings da durchlaufen lassen.
Danke.

PS:
Mit DPI ist kein Problem da habe ich auch eine Funktion die ich schon in meinem C++ Example verwende.
Spielt aber keine rolle es passiert gar nichts solange wie ich DPI Aware nicht zulasse.
Denn dann wird auch nichts vergrößert.

gruss

Glados 4. Sep 2017 14:14

AW: Stringlänge parsen
 
Zitat:

und mixe das nicht mit der Winapi.
Habe ich mittlerweile schon öfter gehört. Ich verstehe gar nicht, was manche Leute gegen die Winapi haben.

EWeiss 4. Sep 2017 14:21

AW: Stringlänge parsen
 
Zitat:

Zitat von Glados (Beitrag 1380270)
Zitat:

und mixe das nicht mit der Winapi.
Habe ich mittlerweile schon öfter gehört. Ich verstehe gar nicht, was manche Leute gegen die Winapi haben.

Ich habe nichts dagegen aber wenn du meine Funktion einmal anschaust wirst du feststellen es gehört etwas mehr dazu.

Und ich arbeite mit der Win32API.. aber ich mixe nicht den Font der in GDI+ erstellt wurde mit dem von der Winapi.. denn das sind 2 paar Schuhe.

Trotzdem Danke.

gruss

t.roller 4. Sep 2017 15:24

AW: Stringlänge parsen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Macht WINDOWS das nicht automatisch?

EWeiss 4. Sep 2017 15:28

AW: Stringlänge parsen
 
Zitat:

Zitat von t.roller (Beitrag 1380274)
Macht WINDOWS das nicht automatisch?

Klar Windows nur das was du im ersten Post siehst ist kein normales Menu.
Auch kein Ownerdraw.

gruss

TiGü 4. Sep 2017 15:45

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380264)
Ich mache es hier mit aber erst dann wenn ich den längsten String ermittelt habe. (einmalig..)

Delphi-Quellcode:
function GetTextBound(UseText: WideString; UseFont: WideString; UseSize: single; var bW: integer;
  var bH: integer; UseStrFormat: integer): GPSTATUS; stdcall;
var
  Graphics: cardinal;
  Fam: GpFontFamily;
  TempFont: GpFont;
  DC: HDC;
begin

  result := GenericError;
  strFormat := nil;
  Fam := nil;
  // Create matching font
  try
    GdipCheck(GdipCreateFontFamilyFromName(UseFont, nil, Fam));
    if Assigned(Fam) then
    begin
      GdipCheck(GdipCreateFont(Fam, UseSize, 0, 2, TempFont));
      if Assigned(TempFont) then
      begin
        DC := GetDC(GetDesktopWindow);

        GdipCheck(GdipCreateStringFormat(0, 0, strFormat));
        GdipCheck(GdipCreateFromHDC(DC, Graphics));

        GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), length(UseText), TempFont,
            @layoutRect, strFormat, @boundingBox, nil, nil));

        if Assigned(strFormat) then
          GdipCheck(GdipDeleteStringFormat(strFormat));

        bW := round(boundingBox.Width - boundingBox.X);
        bH := round(boundingBox.Height - boundingBox.Y);

        if UseStrFormat <> 0 then
          Swap(bW, bH);

        ReleaseDc(GetDesktopWindow, DC);
      end;
    end;
  finally
    if Graphics <> 0 then
      GdipCheck(GdipDeleteGraphics(Graphics));
    if Assigned(TempFont) then
      GdipCheck(GdipDeleteFont(TempFont)); // Lösche das Font Object
    if Assigned(Fam) then
      GdipCheck(GdipDeleteFontFamily(Fam)); // Lösche das Font Family Object
  end;

end;

Ich will ja nicht meckern, aber hast du das gerade aus dem Gedächtnis abgetippt oder irgendwoher kopiert?
Weil so kompiliert es zumindest in höheren Versionen (Berlin, Tokyo) nicht.
Ggf. unterscheidet sich der dort mitgelieferte übersetzte Header Winapi.GDIAPI.pas (von http://www.progdigy.com, hgourvest@progdigy.com, 15-02-2002) von deiner GDIPlus-Unit.
Ist die selbstgemacht oder irgendwoher kopiert?

Außerdem sind da einige Fehler drin, die ein funktionieren unmöglich gemacht haben.
Hier eine entsprechende korrigierte Version:

Delphi-Quellcode:
function GetTextBound(UseText: WideString; UseFont: WideString; UseSize: single; var bW: integer;
  var bH: integer; UseStrFormat: integer): GPSTATUS; stdcall;
var
  Graphics: GPGRAPHICS; // Tigü: Hier war ein falscher Typ (Cardinal)
  Fam: GpFontFamily;
  TempFont: GpFont;
  DC: HDC;
  strFormat: GPSTRINGFORMAT; // Tigü: war nicht definiert
  boundingBox, layoutRect: TGPRectF; // Tigü: war nicht definiert
begin
  Result := GPSTATUS.GenericError; // Tigü: Result ist immer GenericError?? Wird nirgens auf GPStatus.ok gesetzt
  strFormat := nil;
  Fam := nil;
  TempFont := nil; // Tigü: war nicht initialisiert!
  // Create matching font
  try
    GdipCheck(GdipCreateFontFamilyFromName(PWideChar(UseFont), nil, Fam)); // Tigü: PWideChar fehlte
    if Assigned(Fam) then
    begin
      GdipCheck(GdipCreateFont(Fam, UseSize, 0, 2, TempFont));
      if Assigned(TempFont) then
      begin
        DC := GetDC(GetDesktopWindow);

        GdipCheck(GdipCreateStringFormat(0, 0, strFormat));
        GdipCheck(GdipCreateFromHDC(DC, Graphics));

        FillChar(boundingBox, SizeOf(boundingBox), 0); // Tigü: waren nicht initialisiert, Werte waren "unendlich" klein oder groß
        FillChar(layoutRect, SizeOf(layoutRect), 0);   // Tigü: waren nicht initialisiert, Werte waren "unendlich" klein oder groß
                                                                  //
        GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), Length(UseText), TempFont,
          @layoutRect, strFormat, @boundingBox, nil, nil));

        if Assigned(strFormat) then
          GdipCheck(GdipDeleteStringFormat(strFormat));

        bW := round(boundingBox.Width - boundingBox.x);
        bH := round(boundingBox.Height - boundingBox.y);

        if UseStrFormat <> 0 then
          Swap(bW, bH);

        if (bW <> 0) or (bH <> 0) then
          Result := GPSTATUS.Ok; // Tigü: Wenns klappt, sollte das so auch per Result mitgeteilt werden!!

        ReleaseDc(GetDesktopWindow, DC);
      end;
    end;
  finally
    if Assigned(Graphics) then // Tigü: entsprechend des neuen Typs anpassen
      GdipCheck(GdipDeleteGraphics(Graphics));
    if Assigned(TempFont) then
      GdipCheck(GdipDeleteFont(TempFont)); // Lösche das Font Object
    if Assigned(Fam) then
      GdipCheck(GdipDeleteFontFamily(Fam)); // Lösche das Font Family Object
  end;
end;

EWeiss 4. Sep 2017 15:48

AW: Stringlänge parsen
 
Zitat:

Ist die selbstgemacht oder irgendwoher kopiert?
Bitte? Was sollen deine Anmachungen andauernd.
Suche dir dafür in Zukunft jemand anderen... und ja es funktioniert auch ohne deine Verschlimmbesserungen.

Nur mal so zum Mitschreiben..
Delphi-Quellcode:
Result := GPSTATUS.Ok; // Tigü: Wenns klappt, sollte das so auch per Result mitgeteilt werden!!
Quatsch!
GdipCheck liefert die Rückgabe..

Delphi-Quellcode:
function GdipCreateFontFamilyFromName(
  name: WideString;
  fontCollection: Pointer;
  out FontFamily: GpFontFamily
): GPSTATUS; stdcall; external LibGdiPlus;
Was für ein PWideChar?
und so könnte ich weiter machen... aber lassen wir das.

gruss

TiGü 4. Sep 2017 16:05

AW: Stringlänge parsen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von EWeiss (Beitrag 1380278)
Zitat:

Ist die selbstgemacht oder irgendwoher kopiert?
Bitte? Was sollen deine Anmachungen andauernd.
Suche dir dafür in Zukunft jemand anderen... und ja es funktioniert auch ohne deine Verschlimmbesserungen.

Das ist doch eine ganz normale Frage?
Sind wir heute wieder besonderes dünnhäutig?

Anbei noch ein Screenshot des Line Timer von der Nexus Quality Suite (https://www.nexusdb.com/support/inde...etimerfeatures).
Die Funktion habe ich 100 mal aufgerufen und in der linken Spalte siehst du die Zeiten in Millisekunden.
Alles größer 0,5 habe ich mal farblich markiert.

Du könntest also am meisten Zeit sparen, wenn du - insofern die Schrifteinstellungen für alle Einträge im Menü gleich sind - Das Erstellen der FontFamily, der GDIPlus-Font und das Graphics-Objekt nur einmalig machst und dann über deine Strings iterierst und dir entsprechend die Objekte übergibst.

Delphi-Quellcode:
//Pseudocode:

    GdipCheck(GdipCreateFontFamilyFromName(PWideChar(UseFont), nil, Fam)); // PWideChar
    if Assigned(Fam) then
    begin
      GdipCheck(GdipCreateFont(Fam, UseSize, 0, 2, TempFont));
      if Assigned(TempFont) then
      begin
        DC := GetDC(GetDesktopWindow);

        GdipCheck(GdipCreateStringFormat(0, 0, strFormat));
        GdipCheck(GdipCreateFromHDC(DC, Graphics));
        DoFindLongestStringWidth(strFormat, TempFont, Graphics, UseTexts {hier natürlich dann eine Liste oder Array mit den Strings übergeben}, bW, bH, UseStrFormat);

        ReleaseDc(GetDesktopWindow, DC);

...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:46 Uhr.
Seite 2 von 6     12 34     Letzte »    

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 by Thomas Breitkreuz