Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktionsrückgabe freigeben (https://www.delphipraxis.net/88072-funktionsrueckgabe-freigeben.html)

IngoD7 9. Mär 2007 18:10

Re: Funktionsrückgabe freigeben
 
Zitat:

Zitat von Luckie
Windows?

Njet, leider zu einfach. ---> Undefinierter Bezeichner: 'ExtractIcon'

Luckie 9. Mär 2007 18:14

Re: Funktionsrückgabe freigeben
 
Ups. Probier mal ShellAPI. In den Delphi Units sollte sie nicht zu finden sein, da es eine Windows Funktion ist. Und laut PDK ist sie in ShellAPI.h definiert, sollte also auch in Delphi in ShellAPI.pas zu finden sein.

Guido Eisenbeis 9. Mär 2007 18:50

Re: Funktionsrückgabe freigeben
 
.
Hey cool! Richtig viele Antworten! Und brauchbar dazu. Dickes Lob an alle!

@IngoD7

ShellApi ist richtig.


@Heiko und brechi
Die von euch genannte Möglichkeit (war ja die gleiche) scheint zu funktionieren. Allerdings ist der Aufwand dann nicht wesentlich geringer, als der bei der Pozedur-Lösung.


Wie aus den Antworten deutlich zu sehen ist, wird die Funktions-Lösung von den Meisten abgelehnt und die Prozedurlösung ist der absolut deutliche Favorit.

Nachdem ich nun eure Antworten durchgelesen und eure Vorschläge getestet habe, bin ich (nach wie vor) überzeugter Anhänger der Procedure-Lösung! Zum Einen ist der Aufwand gegenüber der Funktions-Lösung nur unwesentlich größer. Zum Anderen ist die Procedure-Lösung deutlich besser lesbar, besser verwaltbar und besserer Programmierstil!

OK, Käs-gess! ;-)

Vielen Dank an alle!


@Angel4585

Bliebe noch eine Frage: Wie zum Kuckuck sieht dein "Tu was.." aus? Im Ernst, wie willst du zum Beispiel eine Zuweisung durchführen, ohne die Funktion erneut aufzurufen?

Beispiel:
Delphi-Quellcode:
function IchGebeEinObjectZurueck : TMeinObject;
begin
Result:=TMeinObject.Create;
end;
.
.
begin
with IchGebeEinObjectZurueck do
  try
    // Icon aus Exe auslesen und Image zuweisen
    Image1.Picture.Graphic := ???
  finally
    Free;
    end;
end;
Und trozdem auch dir vielen Dank!

Grüße,
Guido.

IngoD7 9. Mär 2007 19:15

Re: Funktionsrückgabe freigeben
 
Zitat:

ShellAPI
:shock: Eigentlich kein ungewöhnlicher Kandidat. :wall:

Hirnblockade! :freak: Da wäre ich ums Verrecken heute nicht mehr drauf gekommen.

IngoD7 9. Mär 2007 19:41

Re: Funktionsrückgabe freigeben
 
Unabhängig von sonstigen Hirnschäden bei mir :mrgreen: habe ich noch eine Frage zum Verständnis:

Was wird denn überhaupt mit dem zwischenzeitlichen Erzeugen eines TIcons gewonnen?
Oder anders:
Was spricht gegen eine direkte Zuweisung des Handles?
Delphi-Quellcode:
Image1.Picture.Icon.Handle := ExtractIcon(HInstance, PCHAR('C:\Windows\NotePad.exe'), 0);
Nachtrag:
Natürlich immer fein mit
Delphi-Quellcode:
Image1.Picture.Icon.ReleaseHandle;
freigeben.

Christian Seehase 9. Mär 2007 21:10

Re: Funktionsrückgabe freigeben
 
Moin Ingo,

gegen die Zuweisung des Handles spricht nichts, aber TIcon war hier ja auch nur als Beispielklasse gemeint ;-)

IngoD7 9. Mär 2007 21:26

Re: Funktionsrückgabe freigeben
 
Zitat:

Zitat von Christian Seehase
gegen die Zuweisung des Handles spricht nichts, aber TIcon war hier ja auch nur als Beispielklasse gemeint ;-)

Ja, stimmt. Aber dann war es ein etwas schlechtes Beispiel. ;)

Guido Eisenbeis 10. Mär 2007 02:58

Re: Funktionsrückgabe freigeben
 
Hallo Ingo.

Zitat:

Zitat von IngoD7
Unabhängig von sonstigen Hirnschäden bei mir :mrgreen: habe ich noch eine Frage zum Verständnis:

Was wird denn überhaupt mit dem zwischenzeitlichen Erzeugen eines TIcons gewonnen?
Oder anders:
Was spricht gegen eine direkte Zuweisung des Handles?
Delphi-Quellcode:
Image1.Picture.Icon.Handle := ExtractIcon(HInstance, PCHAR('C:\Windows\NotePad.exe'), 0);

Irgendwie habe ich das Gefühl, in einem "rekursiven Threadaufrufing" zu stecken! :-D

Erinnerst du dich noch an das Thema dieses Threads? *nicht-bös-gemeint* Das Beispiel ist auch nicht schlecht gewählt! Denn es geht in diesem Thread NICHT darum, ein Icon zu extrahieren und einem Image-Control zuzuweisen.

Wie Chris schon sagte, ist das TIcon nur ein Beispiel. Ginge es darum, hättest du natürlich recht: Durch die direkte Zuweisung des Icon-Handles aus der Rückgabe von ExtractIcon würde lediglich eine Referenz auf das "Icon[0]" der NotePad.exe-Ressourcedatei erzeugt und es würde auch nur einmal Speicher belegen.

In diesem Thread geht es aber um was ganz anderes: Wie man Speicher freigibt, der durch Funktionen belegt wird, die ein Objekt als Rückgabe liefern.

Ich denke, dass die Beiträge in diesem Thread und die Tests die ich durchgeführt habe aber deutlich zeigen, dass die Prozedur-Lösung der Funktion-Lösung vorzuziehen ist. Bei der Prozedur-Lösung kann man wirklich modular programmieren. Damit meine ich, dass der Code, der sich in der Prozedur befindet, soweit gekapselt ist, dass man sich außerhalb nicht mehr drum zu kümmern braucht. Man übergibt von außen einen Variablen-Parameter (Objekt), der dann auch außen freigegeben werden kann/muss und alles Andere wird innerhalb der Prozedur erledigt.

Meine (Taskmanager-Minimal-) Tests mit der Funktion-Lösung haben folgendes ergeben: Trotz zwischenzeitlichem Erzeugen eines TIcons wächst bei vielfachem Aufrufen der Funktion die Speicherbelegung. Zwar um einiges langsamer, aber dennoch.

Abschließend nochmals vielen Dank an alle!


Eine(n) hab ich noch:

Zitat:

Zitat von IngoD7
Natürlich immer fein mit
Delphi-Quellcode:
Image1.Picture.Icon.ReleaseHandle;
freigeben.

An welcher Stelle des Codes würdest du das aufrufen?

Auch in der Hilfe zu ExtractIcon steht:
Zitat:

Remarks
You must destroy the icon handle returned by ExtractIcon by calling the DestroyIcon function.
Ich kann aber das Icon nicht freigeben, solange ich es in Image1 noch benötige. Muss man sich da noch bei Programmende drum kümmern, oder erfolgt dann eine Freigabe automatisch?


Guido.

Angel4585 10. Mär 2007 07:42

Re: Funktionsrückgabe freigeben
 
Zitat:

Zitat von Guido Eisenbeis
@Angel4585

Bliebe noch eine Frage: Wie zum Kuckuck sieht dein "Tu was.." aus? Im Ernst, wie willst du zum Beispiel eine Zuweisung durchführen, ohne die Funktion erneut aufzurufen?

Beispiel:
Delphi-Quellcode:
type
  TMeinObject = class(TObject)
    private
      FIcon : TIcon;
    public
      constructor Create;
      property ObjectIcon : TIcon read FIcon write FIcon;
    end;


constructor TMeinObject.Create;
begin
FIcon:=TIcon.Create;
end;

function IchGebeEinObjectZurueck : TMeinObject;
begin
Result:=TMeinObject.Create;
end;
.
.
var
meinobject : TMeinObject;
begin
with IchGebeEinObjectZurueck do
  try
    // Icon aus Exe auslesen und Image zuweisen
    Image1.Picture.Graphic := ObjectIcon
  finally
    Free;
    end;
//So oder so:
meinobject:=IchGebeEinObjectZurueck;
Image1.Picture.Graphic := meinobject.ObjectIcon;
FreeAndNil(meinobject);
end;

Dazu muss ich sagen das ich das Problem nicht verstehe... den Speicher freigeben den eine Funktion belegt??
Also die Funktion erzeug ein Object, der Zeiger auf dieses Object wird weitergegeben und in eine andere Variable gespeichert, könnte auch in 10 andere Variablen weitergegeben werden, es ist und bleibt EIN Object.
Jedes Mal wenn die Funktion aufgerufen wird wird auch ein neues Object erzeugt, d.h. nach dem 10. Aufruf der Funktion sind es 10 Objekte.
Wenn ich jedoch das ganze mit einer Prozedur erledige in der das Object falls es schon erzeugt wurde freigebe und danach erzeuge ist klar das es immer nur ein einziges bleibt.

Sprich bei:

Delphi-Quellcode:
procedure DieProzedur(var AMeinObject : TMeinObject);
begin
if Assigned(AMeinObject) then
  FreeAndNil(AMeinObject);
AMeinObject:=TMeinObject.Create;
end;
Da hantiere ich die ganze Zeit mit ein und der selben Variable, wodurch auch keine neuen Instanzen des Objects erzeugt werden.

Muetze1 10. Mär 2007 13:46

Re: Funktionsrückgabe freigeben
 
Wobei man dies:
Zitat:

Zitat von Angel4585
Delphi-Quellcode:
procedure DieProzedur(var AMeinObject : TMeinObject);
begin
if Assigned(AMeinObject) then
  FreeAndNil(AMeinObject);
AMeinObject:=TMeinObject.Create;
end;

so verkürzen kann:

Delphi-Quellcode:
procedure DieProzedur(var AMeinObject : TMeinObject);
begin
  AMeinObject.Free;
  AMeinObject := TMeinObject.Create;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:21 Uhr.
Seite 2 von 4     12 34      

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