Announcement

Collapse
No announcement yet.

TJvCaptionButton / Jedi / GDI Objekte

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TJvCaptionButton / Jedi / GDI Objekte

    Hallo,

    hat jemand Erfahrungen mit TJvCaptionButton von den Jedi-Komponenten?
    Diese Komponente hat offensichtlich ein Resourcen-Leck.
    In meiner Application steigt die Anzahl GDI-Handle ständig an (Task-Manager => Prozesse => GDI-Objekte).
    Das Problem tritt auf, wenn ein Fenster aus der gleichen Anwendung so geöffnet wird, dass es den CaptionButton verdeckt. Nach dem Schließen dieses Fensters geht die Anzahl GDI-Objekte nicht mehr auf den Wert vor dem Öffnen zurück, er ist immer um eins höher.

    Bei einer Steuerungssoftware, die normalerweise ununterbrochen laufen sollte, ist das tötlich, da beim Erreichen der max. Anzahl GDI-Objekte (i.d.R. 10000) im Programm nichts mehr geht.

    Bin für jeden Hinweis dankbar.

    Josef

  • #2
    Zur Info - falls jemand JvCaptionButton verwendet:

    Ich konnte die Ursache inzwischen mit Hilfe des Tools "Memory Validator" (http://www.memoryvalidator.com) lokalisieren und das Problem lösen.
    Es tritt nur auf, wenn zwei oder mehrere JvCaptionButton in ein TForm eingefügt werden.
    Die Komponente hat zwei Handler, die (vermutlich per PostMessage) zum Zeichnen aufgerufen werden: HandleNCPaintBefore und HandleNCPaintAfter.

    HandleNCPaintBefore erzeugt mit CreateRectRgn ein Objekt und HandleNCPaintAfter löscht es dann wieder. Die Übergabe des GDI-Handles erfolgt über den Msg-Parameter (TWMNCPaint-Struktur). Solange nur ein JvCaptionButton vorhanden ist, funktioniert alles korrekt. Bei zwei CaptionButtons wird zuerst für jeden Button HandleNCPaintBefore und dann für jeden Button HandleNCPaintAfter aufgerufen, dabei geht ein Handle verloren und das Objekt kann nicht mehr gelöscht werden. Offensichtlich hat der dahinterliegende Programmcode nur eine TWMNCPaint-Struktur, die bei allen Aufrufen verwendet wird.
    Ich habe es so gelöst, dass ich mir das Handle des in HandleNCPaintBefore erzeugten Objekts innerhalb der Klasse merke (FSaveRgn).

    Datei: ...\jvcl\run\JvCaptionButton.pas
    unit JvCaptionButton
    ...
    type
    ...
    private
    ....
    FSaveRgn: HRGN;
    FNewRgn: HRGN;
    ...

    procedure TJvCaptionButton.HandleNCPaintBefore(Wnd: THandle; var Msg: TWMNCPaint);
    var
    ...
    begin
    ...
    try
    Msg.RGN := CreateRectRgn(0, 0, 1, 1);
    FNewRgn := Msg.RGN;
    FRgnChanged := True;
    CombineRgn(Msg.RGN, FSaveRgn, DrawRgn, RGN_DIFF);
    finally
    DeleteObject(DrawRgn);
    .....
    end;

    procedure TJvCaptionButton.HandleNCPaintAfter(Wnd: THandle; var Msg: TWMNCPaint);
    begin
    if FRgnChanged then
    begin
    DeleteObject(FNewRgn);
    Msg.RGN := FSaveRgn;
    FRgnChanged := False;
    end;

    Redraw(rkDirect);
    end;

    Comment

    Working...
    X