AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

GDI-Handles Leck

Ein Thema von DevilsCamp · begonnen am 9. Okt 2008 · letzter Beitrag vom 14. Jan 2009
Antwort Antwort
Seite 1 von 2  1 2      
DevilsCamp
(Gast)

n/a Beiträge
 
#1

GDI-Handles Leck

  Alt 9. Okt 2008, 08:17
Ich habe in einer Progress-Bar-Komponente folgenden Code zum anzeigen des Fortschritts als Text innerhalb der Komponente:

Delphi-Quellcode:
procedure TIrgendEineKomponente.PaintText(PaintRect: TRect; Canv: TCanvas);
var
  Ima2 : TBitmap;
  s : string;
  X : Integer;
  Y : Integer;
  diffx : Integer;
  t: string;
begin
  if fShowText then
  begin
    Ima2 := TBitmap.Create;
    Ima2.Width := Width;
    Ima2.Height := Height;
    diffx := 0;

    with Ima2.Canvas do
    begin
      CopyMode := cmBlackness;
      CopyRect(Rect(0, 0, Width, Height), Ima2.Canvas, Rect(0, 0, Width, Height));
      CopyMode := cmSrcCopy;
    end;

    with Ima2.Canvas do
    begin
      Font := Self.Font;
      Brush.Style := bsClear;
      Font.Color := clWhite;

      case fTextKind of
        mrgsPercent: s := Format('%0.*f%%', [FNachkommstellen, FPercentage]);
        mrgsXofY: s := Format('%0.0n / %0.0n', [1.0 * FPosition, 1.0 * FMaxWert]);
        mrgsValueOnly: s := Format('%0.0n', [1.0 * FPosition]);
        mrgsOwnText:
          begin
            if (not (csDesigning in ComponentState)) then
            begin
              if Assigned(FOnOwnText) then
                s := FOnOwnText(Self);
            end;
          end;
      end; // case

      if fTextKind <> mrgsXofY then
      begin
        with PaintRect do
        begin
          X := (Right - Left + 1) div 2 - TextWidth(S) div 2;
          Y := (Bottom - Top + 1 - TextHeight(S)) div 2;
        end; // with
      end
      else
      begin
        with PaintRect do
        begin
          X := (Right - Left + 1) div 2 - TextWidth(' / ') div 2;
          X := X - TextWidth(Format('%0.0n', [1.0 * FPosition]));
          Y := (Bottom - Top + 1 - TextHeight(S)) div 2;
        end;
      end;

      TextRect(PaintRect, X, Y, s);
    end; // with Ima2.Canvas

    Canv.CopyMode := cmSrcInvert;
    Canv.Draw(0, 0, Ima2);

    FreeAndNil(Ima2);
  end;
end;
Da ich mit Hilfe des Process Explorers festgestellt habe, dass die Anzahl der GDI-Handles während der Benutzung dieser Komponente steigt, sobald sich der Text ändert, habe ich folgende Theorie:
Im Code wird ja mit der Zeile
Ima2 := TBitmap.Create; ein TBitmap erzeugt (steigt da die Anzahl der GDI-Handles?) und mit
FreeAndNil(Ima2); wieder zerstört.
Was aber, wenn FreeAndNil nicht so funktioniert, wie es sollte, d.h. Ima2 NICHT zerstört wird? Dann würde ja das GDI-Handle nicht geschlossen werden, oder? Oder würde das automatisch mit dem beenden der Methode passieren?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: GDI-Handles Leck

  Alt 9. Okt 2008, 08:21
Warum sollte es nicht funktionieren? Ich würde das für sehr unwahrscheinlich halten. Meiner Meinung nach ist der Fehler an einer anderen Stelle zu suchen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#3

Re: GDI-Handles Leck

  Alt 9. Okt 2008, 09:55
Ja, das liegt mer oder weniger an Windows.
Erstelle das Bitmap im Create deiner Komponente und gib sie im Destroy frei.

Dru wrist sehen dass das Problem eingrenzt.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#4

Re: GDI-Handles Leck

  Alt 10. Okt 2008, 08:56
Jetzt bin ich noch verwirrter.

Auf meinem Entwicklungsrechner (Vista Ultimate, 32bit, 2GB RAM) ändert sich die Anzahl der GDI-Handles für den Prozess nicht. Auf 3 Windows XP-Professional Rechnern (2 haben 1GB, einer 3GB RAM) steigt die Anzahl unaufhaltsam (und ich habe die selbe EXE-Datei verwendet).
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#5

Re: GDI-Handles Leck

  Alt 13. Jan 2009, 14:32


Ich habe den QuellCode meines Programmes nun komplett zerlegt und habe das Problem endlich aufdecken können.
Um prüfen zu können ob ein Text von der Breite her komplett in in ein TLabel passt, hole ich mir mit GetDC einen Handle auf das Label. Mit dem Handle kann ich nun ein TCanvas "misbrauchen" um die Breite mit Canvas.TextWidth zu bestimmen. Dummerweise habe vergessen, das Handle mit ReleaseDC wieder frei zu geben => irgendwann gehen die Resourcen zu ende.

Warum ich aber keine Probleme unter Windows Vista habe und unter XP schon:
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: GDI-Handles Leck

  Alt 13. Jan 2009, 14:54
Vista braucht von sich aus schon genug Resourcen ... vielleicht haben die ja einfach einige Grenzen entsprechend angehoben

Bei TLabel mit Autosize, könnte man notfalls auch nach dem Zuweisen einfach Width auslesen.
(kommt aber darauf an, was man erreichen will und wie "schön" es werden soll)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#7

Re: GDI-Handles Leck

  Alt 13. Jan 2009, 22:50
Zitat von himitsu:
Bei TLabel mit Autosize, könnte man notfalls auch nach dem Zuweisen einfach Width auslesen.
(kommt aber darauf an, was man erreichen will und wie "schön" es werden soll)
Das Label ist in einem GridPanel. Und sollte der Text (in dem Fall Dateiname inkl. Verzeichnis) zu lang sein, dann will ich den Pfad kürzen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: GDI-Handles Leck

  Alt 14. Jan 2009, 08:50
in D2009 kann man für Dateinamen follgende Einstellungen verwenden (kA. seit wann es das gibt)
.ShowAccelChar = False
.EllipsisPosition = epPathEllipsis

Ansonsten könnte man (glaub ich) auch TStaticText statt TLabel nutzen und das gleiche Verhalten über die WinAPI steuern (TStaticText nutzt doch das STATIC-Control von Windows ) lassen (müßte dann aber mal schaun wie man das dem STATIC sagte, das es so kürzen soll)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: GDI-Handles Leck

  Alt 14. Jan 2009, 09:41
Evtl. bringt MinimizeName aus FileCtrl ja auch etwas.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#10

Re: GDI-Handles Leck

  Alt 14. Jan 2009, 10:15
Zitat von DeddyH:
Evtl. bringt MinimizeName aus FileCtrl ja auch etwas.
Leider nicht. Mit der selben Funktion sollen auch normale Texte werden können.

Und selbst, wenn ich nur Pfade kürzen lassen wollte wäre MinimizeName nichts für mich. MinimizeName macht ja folgendes:
Delphi-Quellcode:
const
 sPath = 'c:\Pfad\zur\meiner\Super-tollen\Applikation\VollKrass.exe';

ShowMessage(MinimizeName(sPath, Form1.Canvas, 200));

//results in a message: 'c:\...\VollKrass.exe'
Ich möchte den Text so kürzen:
Delphi-Quellcode:
const
 sPath = 'c:\Pfad\zur\meiner\Super-tollen\Applikation\VollKrass.exe';

ShowMessage(MeinEigenesKuerzen(sPath, Form1.Canvas, 200));

//results in a message: '...r-tollen\Applikation\VollKrass.exe'
Sollte es bereits so eine Funktion geben: Ich schau sie mir gerne an
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 02:54 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