Delphi-PRAXiS
Seite 11 von 13   « Erste     91011 1213      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Benötige Hilfe beim Entwickeln einer Komponente (https://www.delphipraxis.net/98560-benoetige-hilfe-beim-entwickeln-einer-komponente.html)

Sunlight7 8. Sep 2007 01:59

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Delphi-Quellcode:
SetWindowRgn(Handle, Region, True);
DeleteObject(Region);
Das Region Handle nach einer Zuweisung mit MSDN-Library durchsuchenSetWindowRgn nicht mehr verwenden oder gar löschen :warn:

Im MSDN steht geschrieben:
After a successful call to SetWindowRgn, the operating system owns the region specified by the region handle hRgn. The operating system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not close this region handle.

torud 8. Sep 2007 08:38

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Danke für die info. Gelöscht wird es ja, aber es wird komischerweise in dem Code nach dem Löschen noch einmal verwendet. Bei mir funzt es jedenfalss nicht. Warum auch immer.

oki 8. Sep 2007 13:01

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Um das noch mal in Erinnerung zu bringen, hier der Code den ich gepostet habe
Delphi-Quellcode:
procedure TMyControl.DoInvisible;
begin
  //gesamten Clientbereich erfassen
  if FullRgn <> 0 then
    DeleteObject(FullRgn);
  FullRgn := CreateRectRgn(0, 0, Width, Height);
  //'Mask' alles unsichtbar
  CombineRgn( FullRgn, FullRgn, FullRgn, RGN_DIFF );

  // alle sichtbaren Bereiche einblenden
  PointRgn := CreateRectRgn( X, Y, Width, Hight);  // das ist ein Bereich im Rect der eingeblendet wird
  CombineRgn( FullRgn, FullRgn, PointRgn, RGN_OR );
  DeleteObject(Pointrgn);

  // alles Kombiniert und fertig
  SetWindowRgn(Handle, FullRgn, TRUE);
end;
Hier wird nirgens der FullRgn nach SetWindowRgn angefaßt!

Das einzige, was gelöscht wird ist PointRgn. PointRgn wird aber nur für die Kombination der Sichtbaren Bereiche(PointRgn; heisst bei mir so, weil das Rect-Bereiche von Eckpunkten sind) auf den FullRange verwendet. Das dann in einer Schleife.

Ob in meinem ersten Bereich das DeleteObject auf FullRange jetzt korrekt ist, keine Ahnung, bin ich jetzt auch etwas unsicher. Dort wird auf jeden Fall erst mal das ganze Control/Form unsichtbar gemacht.

Im mittleren Abschnitt werden alle sichtbaren Bereiche auf FullRgn kombiniert und im letzten Abschnitt alles gesetzt.

Das was Tom macht ist den letzten Teil meines (auch hier dem Forum entlehnt) Codes herauszunehmen. Der Anfangs- und Mittelteil fehlt völlig und der Rest ist inkorrect!

Kein Wunder, dass nichts mehr geht.

Gruß oki

Sunlight7 8. Sep 2007 13:22

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Zitat:

Zitat von oki
Delphi-Quellcode:
procedure TMyControl.DoInvisible;
begin
  //gesamten Clientbereich erfassen
  if FullRgn <> 0 then
    DeleteObject(FullRgn);
  FullRgn := CreateRectRgn(0, 0, Width, Height);
  //'Mask' alles unsichtbar
  CombineRgn( FullRgn, FullRgn, FullRgn, RGN_DIFF );

  // alle sichtbaren Bereiche einblenden
  PointRgn := CreateRectRgn( X, Y, Width, Hight);  // das ist ein Bereich im Rect der eingeblendet wird
  CombineRgn( FullRgn, FullRgn, PointRgn, RGN_OR );
  DeleteObject(Pointrgn);

  // alles Kombiniert und fertig
  SetWindowRgn(Handle, FullRgn, TRUE);
end;

Ich weiß jetzt nicht, wo Du FullRgn deklariert hast, ich nehme mal an als Private, aber wenn Du DoInvisible mehr als 1 x aufrufst löscht Du das Region Handle nach SetWindowRgn...

Delphi-Quellcode:
// 1. Aufruf, FullRgn = 0 (vermutlich)
procedure TMyControl.DoInvisible;
begin
  //gesamten Clientbereich erfassen
  if FullRgn <> 0 then
    DeleteObject(FullRgn);
  ...
  // alles Kombiniert und fertig
  SetWindowRgn(Handle, FullRgn, TRUE);
end;
Delphi-Quellcode:
// 2. Aufruf, FullRgn <> 0, wurde mit SetWindowRgn gesetzt, wird aber gelöscht
procedure TMyControl.DoInvisible;
begin
  //gesamten Clientbereich erfassen
  if FullRgn <> 0 then
    DeleteObject(FullRgn);
   ...
  // alles Kombiniert und fertig
  SetWindowRgn(Handle, FullRgn, TRUE);
end;

Richtig wäre:
Delphi-Quellcode:
procedure TMyControl.DoInvisible;
   var FullRgn:HRgn;
begin
  FullRgn := CreateRectRgn(0, 0, Width, Height);
  //'Mask' alles unsichtbar
  CombineRgn( FullRgn, FullRgn, FullRgn, RGN_DIFF );

  // alle sichtbaren Bereiche einblenden
  PointRgn := CreateRectRgn( X, Y, Width, Hight);  // das ist ein Bereich im Rect der eingeblendet wird
  CombineRgn( FullRgn, FullRgn, PointRgn, RGN_OR );
  DeleteObject(Pointrgn);

  // alles Kombiniert und fertig
  SetWindowRgn(Handle, FullRgn, TRUE);
  // FullRgn nicht mehr antasten
end;

oki 8. Sep 2007 13:46

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi Sunlight7,

richtig, FullRgn ist privat deklariert.

Nun ist es aber doch so, dass bei einem CreateRectRgn ein handle erzeugt und somit Speicher reserviert wird. Wenn sich das Aussehen oder die Größe ändert, dann muß der Range ja neu gesetzt werden.
Rufe ich nun für FullRgn ein weiteres Mal CreateRectRgn auf, so wird imho doch ein neues Handle erzeugt und neuer Speicher reserviert. Damit würde ich dann doch ohne DeleteObject auf das alte Handle ein Speicherleck erzeugen. Oder nicht?

Gruß oki

Sunlight7 8. Sep 2007 13:56

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi Oki,

Nein wüdest Du nicht, da sich das OS bei einem Aufruf von SetWindowRgn das Handle und alles damit verbundene unter die Finger krallt und sich auch um die Entsorgung kümmert, wenn es nicht mehr gebraucht wird.

oki 8. Sep 2007 14:05

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Das heißt dann auch, dass das Handle für die PointRgn nicht mit DeleteObject frei gegeben werden muß?

Gruß oki

Sunlight7 8. Sep 2007 14:19

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Nein, denn das gilt nur für Region Handles, die mit Delphi-Referenz durchsuchenSetWindowRgn einem Fenster zugewiesen werden.

oki 8. Sep 2007 16:48

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi Sunlight7,

ich glaub dir das schon, aber ein komisches Gefühl hab ich dabei doch. Denn wenn ich für die Variable FullRgn die mein mit SetWindowRgn zugewiesenes Handle enthält eine neue Zuweisung mit CreateRectRgn tätige, wird das enthaltene Handle doch überschrieben. Oder wird das alte Handle bei der Zuweisung des neuen mit SetWindowRgn vom OS frei gegeben?

Gruß oki

Sunlight7 8. Sep 2007 17:08

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Also als Beispiel:

Delphi-Quellcode:
procedure TMyControl.Foo;
   var Rgn1, Rgn2:HRgn;
begin
  Rgn1:=CreateRectRgn(0, 0, Width, Hight);  
  SetWindowRgn(Handle, Rgn1, TRUE);
  // Jetzt hat das OS die Kontrolle über das Handle in Rgn1

  Rgn2:=CreateRectRgn(0, 0, Width, Hight);
  SetWindowRgn(Handle, Rgn2, TRUE);
  // Jetzt hat das OS die Kontrolle über das Handle in Rgn2 und Rgn1 wurde gelöscht

  SetWindowRgn(Handle, 0, TRUE);
  // Und nu is auch Rgn2 gelöscht
end;
Edit: Fehler ausgebessert :roll:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:06 Uhr.
Seite 11 von 13   « Erste     91011 1213      

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