Delphi-PRAXiS
Seite 1 von 2  1 2      

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 12:35


Stringlänge parsen
 
Wie kann ich am schnellsten die länge von Strings parsen
so das ich dann den längsten verwenden kann um mein Window in der Weite dementsprechend anzupassen.

Ja ich weis Length(string) aber ich suche eine schnelle Methode ;)

Habe mein Grund Menu soweit fertig.. und ich benötige die Berechnung um die Sub Menus (weite) auf den längsten String hin anzupassen.
Anbei ein shot.!
1 ganzer Tag nur für das Grundmenu. LOL

gruss

Neutral General 4. Sep 2017 12:36

AW: Stringlänge parsen
 
Length(string)

Bernhard Geyer 4. Sep 2017 12:37

AW: Stringlänge parsen
 
Du suchst doch nicht die Länge des Strings sondern den benötigten Platz zur Darstellung des Strings auf einem Canvas, oder?
Dazu nimmt man DrawText mit dem Paramter DT_CALCRECT

himitsu 4. Sep 2017 12:43

AW: Stringlänge parsen
 
http://www.delphipraxis.net/11102-la...es-string.html
Wenn Canvas oder HDC schon vorhanden sind, dann natürlich das direkt verwenden.

Zitat:

Zitat von EWeiss (Beitrag 1380255)
Ja ich weis Length(string) aber ich suche eine schnelle Methode ;)

Schneller als das geht es aber nicht.
Man kann noch über Pointer schneller sein, wenn der String nie leer ist, indem man diese Prüfung überpringt. :stupid:

EWeiss 4. Sep 2017 12:44

AW: Stringlänge parsen
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1380257)
Du suchst doch nicht die Länge des Strings sondern den benötigten Platz zur Darstellung des Strings auf einem Canvas, oder?
Dazu nimmt man DrawText mit dem Paramter DT_CALCRECT

Ich möchte die gesamte länge eines String parsen\vergleichen bsp. von 30 Einträgen und den längsten davon
verwenden um mein Sub Menu auf die weite auszurichten.

DT_CALCRECT hilft mir nicht ist aber auch nicht wichtig da ich es mit meiner Funktion
GDIP_GetTextBound nachher in Pixeln exakt ermittle wenn ich den längsten string habe.

Zitat:

Length(string)
Und ich sagte ja schon das ich weis das es mit Length geht aber ich muss etwas schnelles haben vielleicht in einem rutsch ;)

gruss

Glados 4. Sep 2017 12:44

AW: Stringlänge parsen
 
Zitat:

Ich möchte die gesamte länge eines String parsen\vergleichen bsp. von 30 Einträgen und den längsten davon
verwenden um mein Sub Menu auf die weite auszurichten.
QuickSort und dann das hier vielleicht?

Delphi-Quellcode:
function getTextWidth(aForm: TForm; const aString: string): Integer;
begin
 if aString <> '' then
  Result := aForm.Canvas.TextWidth(aString)
 else
  Result := 0;
end;

jaenicke 4. Sep 2017 12:47

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380259)
DT_CALCRECT hilft mir nicht ist aber auch nicht wichtig da ich es mit meiner Funktion
GDIP_GetTextBound nachher in Pixeln exakt ermittle wenn ich den längsten string habe.

Der nach Zeichen längste String ist aber nicht unbedingt der, der den meisten Platz beim Zeichnen benötigt...
Verschiedene Zeichen sind ja unterschiedlich breit.

Zitat:

Zitat von EWeiss (Beitrag 1380259)
Zitat:

Length(string)
Und ich sagte ja schon das ich weis das es mit Length geht aber ich muss etwas schnelles haben vielleicht in einem rutsch ;)

Bei Delphi-Strings geht es kaum schneller als mit Length, denn das liest ja nur die Längenangabe aus, die vor dem String steht.

// EDIT:
Die beim Zeichnen längste Zeile wirst du wohl am einfachsten bekommen, wenn du alle Strings in mehreren Zeilen nimmst und gesammelt an die Funktion zur Größenermittlung gibst. Das ist vermutlich nicht besonders schnell, aber zuverlässig und schneller als jeden Text einzeln anzufragen.

EWeiss 4. Sep 2017 12:49

AW: Stringlänge parsen
 
Zitat:

Zitat von Glados (Beitrag 1380260)
Zitat:

Ich möchte die gesamte länge eines String parsen\vergleichen bsp. von 30 Einträgen und den längsten davon
verwenden um mein Sub Menu auf die weite auszurichten.
QuickSort und dann das hier vielleicht?

Delphi-Quellcode:
function getTextWidth(aForm: TForm; const aString: string): Integer;
begin
 if aString <> '' then
  Result := aForm.Canvas.TextWidth(aString)
 else
  Result := 0;
end;

Sorry irgendwie werde ich nicht verstanden.. das nutzt mir nichts und ist auch nicht wichtig.
Da ich den Text mit GDI+ zeichne und ein mix mit der Winapi ist da nicht das wahre.

Denke werde es dann wohl doch mit Length(string) in einer schleife machen müssen.

Zitat:

Verschiedene Zeichen sind ja unterschiedlich breit.
ja das ist klar ;)

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;
gruss

Neutral General 4. Sep 2017 12:52

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380259)
Ich möchte die gesamte länge eines String parsen\vergleichen bsp. von 30 Einträgen und den längsten davon
verwenden um mein Sub Menu auf die weite auszurichten.

Und ich sagte ja schon das ich weis das es mit Length geht aber ich muss etwas schnelles haben vielleicht in einem rutsch ;)

Length(string) in Assembler (Delphi 7):
Delphi-Quellcode:
  test eax, eax
  jz +$03
  mov eax, [eax-$04]
  ret
Schneller wirds nicht.
Außerdem in extremen Fällen können kürzere Strings (Anzahl der Zeichen) länger (in Pixeln) sein als andere längere Strings (Anzahl der Zeichen) (<-- Verwirrender Satz aber ich hoffe du weißt was ich meine :mrgreen: )

z.B.

WWWW (Length = 4)
iiiiiiiiiiii (Length = 12)

Glados 4. Sep 2017 12:53

AW: Stringlänge parsen
 
Zitat:

Sorry irgendwie werde ich nicht verstanden..
Doch wirst du.

Zitat:

Denke werde es dann wohl doch mit Length(string) in einer schleife machen müssen.
Auf Systemen mit einer anderen DPI als deine eigene wirst du Probleme bekommen.

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.

EWeiss 4. Sep 2017 12: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 12: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 13: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 13: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 13: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 14:24

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

EWeiss 4. Sep 2017 14: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 14: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 14: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 15: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);

...

EWeiss 4. Sep 2017 15:09

AW: Stringlänge parsen
 
Zitat:

Das ist doch eine ganz normale Frage?
Jo einmalig aber nicht fortlaufend.

Zitat:

Ich will ja nicht meckern, aber hast du das gerade aus dem Gedächtnis abgetippt oder irgendwoher kopiert?
Ist die selbstgemacht oder irgendwoher kopiert?
Mache ich überhaupt was selbst oder kopiere ich nur alles... LOL.
Ach was soll's

gruss

TiGü 4. Sep 2017 15:10

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380278)

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.

Bist du fertig mit editieren oder kann man mal antworten?
Immer diese Unart, die Beiträge nachträglich zu editieren und neues Zeug rein zuschreiben, anstatt einen neuen Beitrag zu erstellen.
Kannst du dir das nicht mal abgewöhnen? :roll:

Die von dir genannte Funktion ist bspw. bei mir so definiert:

Delphi-Quellcode:
//----------------------------------------------------------------------------
// FontFamily APIs
//----------------------------------------------------------------------------

  function GdipCreateFontFamilyFromName(name: PWCHAR;
    fontCollection: GPFONTCOLLECTION;
    out FontFamily: GPFONTFAMILY): GPSTATUS; stdcall;
  {$EXTERNALSYM GdipCreateFontFamilyFromName}
Daher meine Frage, woher deine GDIPlus-Übersetzung stammt.
Wenn du willst, kann ich dir ja mal meine Pascal-Unit zukommen lassen.

EWeiss 4. Sep 2017 15:20

AW: Stringlänge parsen
 
Ich habe diese Funktion editiert da sie mit PWCHAR nicht mit meinem Wrapper kompatible ist.
Und nein es gibt keine Problem sonst hätte mir GdipCheck das schon gemeldet.

Ich verwende nix von progdigy sondern habe meine eigene Unit erstellt auf der Basis von Win32Api.
Delphi hat die Eigenschaft alles unnötig aufzubauschen.
Sieht man ja an den Kompilaten ;)

mag ja sein das ich ein zwei Sachen nicht initialisiert habe.. meine Regel ist solange der Compiler nicht meckert kompiliert
und alles rund läuft sollte das schon gut sein.

gruss

EWeiss 4. Sep 2017 15:31

AW: Stringlänge parsen
 
Ach so das noch ;)
Neue Post! 8-)

Delphi-Quellcode:
strFormat: GPSTRINGFORMAT; // Tigü: war nicht definiert
boundingBox, layoutRect: TGPRectF; // Tigü: war nicht definiert
war definiert nur nicht in der Funktion daher muss hier auch nix auf NIL gesetzt werden da GLOBAL!

Delphi-Quellcode:
var
  strFormat: GPSTRINGFORMAT;
  boundingBox: TGPRectF;
  layoutRect: TGPRectF;
  rcLayout: TGPRectF;
  brush: Pointer;
Das kannst du natürlich nicht sehen.

EDIT:

Delphi-Quellcode:
Graphics: GPGRAPHICS; // Tigü: Hier war ein falscher Typ (Cardinal)

Der Typ ist nicht falsch wenn er das wäre würde mein ganzer Quelltext nicht funktionieren.
Das ist eine Auslegungs Sache wie ich Graphics definiere.
IN VB ist es Long, in PowerBasik ist es DWORD und bei mir ist es Cardinal (DWORD) wenn du so willst.

gruss

TiGü 4. Sep 2017 15:42

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380283)
Ich habe diese Funktion editiert da sie mit PWCHAR nicht mit meinem Wrapper kompatible ist.
Und nein es gibt keine Problem sonst hätte mir GdipCheck das schon gemeldet.

Ich verwende nix von progdigy sondern habe meine eigene Unit erstellt auf der Basis von Win32Api.
Delphi hat die Eigenschaft alles unnötig aufzubauschen.
Sieht man ja an den Kompilaten ;)

Du wirst schon wissen was du tust, aber wäre es nicht sinnvoller gewesen deinen Wrapper entsprechend anzupassen, anstatt die Übersetzung der DLL-Funktion?

Schau mal hier, wie die Jungs vom Wine-Projekt das gelöst haben: https://source.winehq.org/WineAPI/Gd...yFromName.html

Du bist ja nun inzwischen etwas sattelfester in C/C++.
Was für ein Typ hat das erste Argument?

Zitat:

Zitat von EWeiss (Beitrag 1380283)
mag ja sein das ich ein zwei Sachen nicht initialisiert habe.. meine Regel ist solange der Compiler nicht meckert kompiliert
und alles rund läuft sollte das schon gut sein.

Auch wenn wir uns sowas alle wünschen würden, aber der Compiler ist da etwas schludderig und keine Hilfe.
Kann es sein, dass bei dir strFormat, boundingBox und layoutRect globale Variablen sind? :twisted:
Die fehlen schlicht und ergreifend in der Funktion und deswegen kann es nicht kompilieren.
Wenn ich das nun einfüge und die beiden Rechtecke nicht per FillChar (oder ZeroMemory) initialisiere, haben die zufällige Werte und werden von GdipMeasureString nicht richtig ausgefüllt bzw. falsch übernommen.
Das knallt dann spätestens beim berechnen von bH oder bW, weil Round einen "invalid floting point operation"-Fehler wirft.

EWeiss 4. Sep 2017 15:48

AW: Stringlänge parsen
 
Zitat:

Kann es sein, dass bei dir strFormat, boundingBox und layoutRect globale Variablen sind?
korrekt.. sind global habe ich ja einen Post über dir geschrieben.

Delphi-Quellcode:
        FillChar(boundingBox, SizeOf(boundingBox), 0);
        FillChar(layoutRect, SizeOf(layoutRect), 0);
Das ist OK! Habe es addiert.
Danke.

gruss

TiGü 4. Sep 2017 15:57

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380284)
EDIT:

Delphi-Quellcode:
Graphics: GPGRAPHICS; // Tigü: Hier war ein falscher Typ (Cardinal)

Der Typ ist nicht falsch wenn er das wäre würde mein ganzer Quelltext nicht funktionieren.
Das ist eine Auslegungs Sache wie ich Graphics definiere.
IN VB ist es Long, in PowerBasik ist es DWORD und bei mir ist es Cardinal (DWORD) wenn du so willst.

Ich möchte dich an dieser Stelle ausdrücklich warnen! :!:
Das funktioniert wunderbar für 32-Bit bis ans Ende aller Tage.

Aber unter 64-Bit wirst du schnell merkwürdige Fehler (höchstwahrscheinlich) bekommen (können).
Die GDIPLUS-DLL wird dir 64-Bit Zeiger geben (Länge 8 Byte) und du wirst hart auf 32-Bit Länge casten und damit die Adresse abschneiden.
Das führt unweigerlich zu merkwürdigen Fehlern und Zugriffsverletzungen.
Das gilt auch für alle anderen Typen wie bpsw. Brush, Texture, Gradienten, Pen, Image, Bitmap, StringFormat, FontFamily etc. pp.

TiGü 4. Sep 2017 16:00

AW: Stringlänge parsen
 
Hier mal ein Beispiel was falsche, nicht mitwachsende Typen für Ärger sorgen können:
http://www.delphipraxis.net/181512-s...imagelist.html

EWeiss 4. Sep 2017 16:05

AW: Stringlänge parsen
 
Das ist korrekt was du sagst deshalb verwende ich für 64Bit ja auch die "normale" GDIPlus vom http://www.progdigy.com ;)

Ich weis das Graphics, Image und einige andere variablen Pointer sind.
Bei mir sind diese fast alle Cardinal und glaube mir in 32Bit gibt es keine Probleme.

Ich hatte einfach keine Lust 5 Units für 3 API Funktionen in meine LIB einzubinden die machen alleine schon 1MB aus.

gruss

EWeiss 4. Sep 2017 16:15

AW: Stringlänge parsen
 
Nun ja wirklich weiter bin ich noch nicht muss mich mal schlau machen was Glados mit QuickSort meint.
Kenn mich damit nicht aus.

gruss

TiGü 4. Sep 2017 16:28

AW: Stringlänge parsen
 
Zitat:

Zitat von EWeiss (Beitrag 1380292)
Nun ja wirklich weiter bin ich noch nicht muss mich mal schlau machen was Glados mit QuickSort meint.
Kenn mich damit nicht aus.

Der Vorschlag bringt dich auch nicht weiter.
Da muss man auch nichts sortieren.

PseudoCode:

Delphi-Quellcode:
function GetTextWidth(MyStrings: TStrings {ja, nur ein Beispiel, kannst auch Array nehmen}): Integer;
var
  Result, NewWidth: Integer;
  MyString: string;
begin
  Result := 0;
  NewWidth := 0;
  for MyString in MyStrings do
  begin
    NewWidth := GetTextBoundOnlyWidth(MyString); // Platzhalterfunktion zum Ermitteln der Breite des Strings
    if NewWidth > Result then // Immer wenn die Breite größer ist von diesen String, dann Result entsprechen erhöhen
      Result := NewWidth;
  end;
end;

Glados 4. Sep 2017 17:00

AW: Stringlänge parsen
 
Zitat:

Der Vorschlag bringt dich auch nicht weiter.
Da muss man auch nichts sortieren.
Ich habe nicht gesagt, dass man zwingend sortieren muss. Aber mit QuickSort kann man den längsten String ausfindig machen.

Was anderes macht dein Code auch nicht!
Ob nun dein Vorschlag oder meiner: das Ergebnis ist am Ende dasselbe je nachdem wie man es auswertet.

Neutral General 4. Sep 2017 17:05

AW: Stringlänge parsen
 
Zitat:

Zitat von Glados (Beitrag 1380294)
Was anderes macht dein Code auch nicht!
Ob nun dein Vorschlag oder meiner: das Ergebnis ist am Ende dasselbe je nachdem wie man es auswertet.

Doch. Um die Strings sortieren zu können musst du für jeden String in einer Schleife erst mal die Länge ermitteln.
Danach noch zu sortieren ist Unsinn weil man sich in der Schleife auch grad immer merken kann ob das aktuelle Element das (bisher) größte ist:
Delphi-Quellcode:
if NewWidth > Result then // Immer wenn die Breite größer ist von diesen String, dann Result entsprechen erhöhen
  Result := NewWidth;

EWeiss 4. Sep 2017 17:05

AW: Stringlänge parsen
 
Zitat:

Zitat von TiGü (Beitrag 1380293)
Zitat:

Zitat von EWeiss (Beitrag 1380292)
Nun ja wirklich weiter bin ich noch nicht muss mich mal schlau machen was Glados mit QuickSort meint.
Kenn mich damit nicht aus.

Der Vorschlag bringt dich auch nicht weiter.
Da muss man auch nichts sortieren.

PseudoCode:

Delphi-Quellcode:
function GetTextWidth(MyStrings: TStrings {ja, nur ein Beispiel, kannst auch Array nehmen}): Integer;
var
  Result, NewWidth: Integer;
  MyString: string;
begin
  Result := 0;
  NewWidth := 0;
  for MyString in MyStrings do
  begin
    NewWidth := GetTextBoundOnlyWidth(MyString); // Platzhalterfunktion zum Ermitteln der Breite des Strings
    if NewWidth > Result then // Immer wenn die Breite größer ist von diesen String, dann Result entsprechen erhöhen
      Result := NewWidth;
  end;
end;

Danke das ist ein Anhaltspunkt.
TStrings sind ok..

gruss

Glados 4. Sep 2017 17:15

AW: Stringlänge parsen
 
Zitat:

Ob nun dein Vorschlag oder meiner: das Ergebnis ist am Ende dasselbe je nachdem wie man es auswertet.
Zitat:

Doch.
:roll::wall:

Neutral General 4. Sep 2017 17:18

AW: Stringlänge parsen
 
Zitat:

Zitat von Glados (Beitrag 1380297)
Zitat:

Ob nun dein Vorschlag oder meiner: das Ergebnis ist am Ende dasselbe je nachdem wie man es auswertet.
Zitat:

Doch.
:roll::wall:

Ok, dass "Doch" hat in dem Kontext nicht gepasst, der Rest trifft trotzdem zu.

:roll: :wall:

:roll:

Rollo62 4. Sep 2017 19:20

AW: Stringlänge parsen
 
Ich bin wahrscheinlich schon OffTopic weil ich das Problem falsch verstehe,
oder dieser Vorschlag steht hier schonmal irgendwo im Thread:

Aber du könntest die Strings einmalig beim Erzeugen parsen und die Längen und was auch immer separat verwalten, z.B. als Liste oder Array, o.ä.
Damit könntest du die Länge relativ schnell über das Array finden.

Mal so hingeschrieben, ohne Test und Sicherheitsabfragen.
Delphi-Quellcode:
  intMax := SucheMaxLänge(intStart, intAnzahl);

function SucheMaxLänge(intStart, intAnzahl) : Integer;
begin
   Result := 0;

   while intAnzahl > 0 do
   begin
     if FLenArray[intStart+IntAnzahl] > Result then
        Result := FLenArray[intStart+IntAnzahl];
     Dec(intAnzahl);
   end;
end;
Dazu müsste aber das Array immer mit der Stringliste synchron laufen, ein Insert, Delete, etc. wenn du das gewährleisten kannst.

Rollo

EWeiss 4. Sep 2017 19:26

AW: Stringlänge parsen
 
Theoretisch ist das machbar praktisch leider nicht weil sich die Menüs immer ändern dynamisch.
Irgendwelche Strings im Speicher halten würde also nicht viel bringen.

Bei jeden neuen Film sieht das anders aus.

gruss

Rollo62 4. Sep 2017 19:37

AW: Stringlänge parsen
 
Nur die Längen im Speicher halten ...

hoika 4. Sep 2017 22:38

AW: Stringlänge parsen
 
Hallo,
gibt es hier überhaupt ein Performance-Problem,
oder ist es eine theoretische Diskussion?

"Minimal-Bsp." bitte, was das Problem zeigt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 Uhr.
Seite 1 von 2  1 2      

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