AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi IconHandle von Icon Datei
Thema durchsuchen
Ansicht
Themen-Optionen

IconHandle von Icon Datei

Ein Thema von EWeiss · begonnen am 25. Apr 2019 · letzter Beitrag vom 26. Apr 2019
Antwort Antwort
Seite 1 von 2  1 2      
EWeiss
(Gast)

n/a Beiträge
 
#1

IconHandle von Icon Datei

  Alt 25. Apr 2019, 21:17
Meine Funktion..

Delphi-Quellcode:
function TSkinPopUpMenu.GetHIconFromFile(AFileName: PWideChar; ASmall: Boolean; AIndex: Integer)
  : HIcon;
var
  LDummy: HIcon;
  LInfo: TSHFileInfo;
begin
  Result := 0;

  If ExtractIconEx(AFileName, -1, Result, LDummy, 0) <> 0 then
  begin
    If ASmall then
      ExtractIconEx(AFileName, AIndex, LDummy, Result, 1)
    else
      ExtractIconEx(AFileName, AIndex, Result, LDummy, 1);
  end
  else
  begin
    SHGetFileInfo(PWideChar(ExtractFileExt(AFileName)), FILE_ATTRIBUTE_NORMAL, LInfo,
      SizeOf(LInfo), IfThen(ASmall, SHGFI_SMALLICON, SHGFI_LARGEICON)
      or SHGFI_ICON or SHGFI_LINKOVERLAY or SHGFI_USEFILEATTRIBUTES);
    Result := LInfo.HIcon;
  end;
end;
Aufruf..
Delphi-Quellcode:
  if ImageIconPath <> 'then
  begin
    FIcon[ButtonCount].ImageIcon := GetHIconFromFile(ImageIconPath, true);
    if (FIcon[ButtonCount].ImageIcon <> 0) then
      btnMenu[ButtonCount].ImageDrop(HButton, FIcon[ButtonCount], X, Y, W, H);
  end;
Freigeben..
Delphi-Quellcode:
  if ButtonCount > 0 then
  begin
    for IntI := 0 to ButtonCount - 1 do
    begin
      btnMenu[IntI].ImageDropRemove(btnMenu[IntI].Handle);
      btnMenu[IntI].DestroyWindow;
      btnMenu[IntI] := nil;
    end;
    SetLength(btnMenu, 0);
    SetLength(FIcon, 0);
    ButtonCount := 0;
  end;
Funktioniert soweit alles..
Aber!

Wenn ich das PopuMenu ca.. 30 > 40 mal hintereinander aufrufe dann schlägt das fehl.
If ExtractIconEx(AFileName, -1, Result, LDummy, 0) <> 0 then

und kracht dann in
Result := LInfo.HIcon;

Warum? Wenn doch alle Icon Handles freigegeben werden.
Delphi-Quellcode:
procedure TSkinPushButton.ImageDropRemove(WinHandle: HWND);
begin

  if ImgDrop <> 0 then
  begin
    DestroyIcon(ImgDrop);
    SkinEngine.SetImageProperty(WinHandle, PROP_IMAGE_DROP, 0);
  end;
end;
gruss

Geändert von EWeiss (25. Apr 2019 um 21:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#2

AW: IconHandle von Icon Datei

  Alt 25. Apr 2019, 22:28
Du extrahierst zwei Icons pro Aufruf von ExtractIconEx, also musst du auch beide zerstören. Oder du castest so, dass nur ein Icon extrahiert wird:ExtractIconEx(PChar(AFileName), AIndex, Result, HICON(nil^), 1); Auch der Aufruf von ExtractIconEx(PChar(AFileName), -1, ...) könnte Icons extrahieren; die Doku zu MSDN-Library durchsuchenExtractIconEx ist da leider nicht präzise genug. Geht's dabei nur um Ermittlung der Anzahl der vorhandenen Icons, setze beide HIcon-Parameter auf NULL (siehe oben).

Grüße
Dalai
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: IconHandle von Icon Datei

  Alt 25. Apr 2019, 22:36
Du extrahierst zwei Icons pro Aufruf von ExtractIconEx, also musst du auch beide zerstören. Oder du castest so, dass nur ein Icon extrahiert wird:ExtractIconEx(PChar(AFileName), AIndex, Result, HICON(nil^), 1); Auch der Aufruf von ExtractIconEx(PChar(AFileName), -1, ...) könnte Icons extrahieren; die Doku zu MSDN-Library durchsuchenExtractIconEx ist da leider nicht präzise genug. Geht's dabei nur um Ermittlung der Anzahl der vorhandenen Icons, setze beide HIcon-Parameter auf NULL (siehe oben).

Grüße
Dalai
Ich kann jetzt nicht erkennen wo ich 2 Icons pro Aufruf extrahiere..
Du meinst das LDummy + Result?

ja ich sehe es gerade
Danke.. kann mir dann das LDummy sparen..

Delphi-Quellcode:
function TSkinPopUpMenu.GetHIconFromFile(AFileName: PWideChar; ASmall: Boolean; AIndex: Integer)
  : HIcon;
var
  LInfo: TSHFileInfo;
begin
  Result := 0;

  If ExtractIconEx(AFileName, -1, Result, HICON(nil^), 0) <> 0 then // << denke das sollte so ausreichen
  begin
    If ASmall then
      ExtractIconEx(AFileName, AIndex, HICON(nil^), Result, 1)
    else
      ExtractIconEx(AFileName, AIndex, Result, HICON(nil^), 1);
  end
  else
  begin
    SHGetFileInfo(PWideChar(ExtractFileExt(AFileName)), FILE_ATTRIBUTE_NORMAL, LInfo,
      SizeOf(LInfo), IfThen(ASmall, SHGFI_SMALLICON, SHGFI_LARGEICON)
      or SHGFI_ICON or SHGFI_LINKOVERLAY or SHGFI_USEFILEATTRIBUTES);
    Result := LInfo.HIcon;
  end;
end;

Habe das PopupMenu jetzt 100 mal geöffnet und geschlossen scheint zu funktionieren..
Na ja wer macht das schon bei normaler Bedienung.

gruss

Geändert von EWeiss (25. Apr 2019 um 22:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#4

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 00:25
Du meinst das LDummy + Result?
Jep, genau das.

Zitat:
Delphi-Quellcode:
function TSkinPopUpMenu.GetHIconFromFile(AFileName: PWideChar; ASmall: Boolean; AIndex: Integer)
  : HIcon;
var
  LInfo: TSHFileInfo;
begin
  Result := 0;

  If ExtractIconEx(AFileName, -1, Result, HICON(nil^), 0) <> 0 then // << denke das sollte so ausreichen
  begin
    If ASmall then
      ExtractIconEx(AFileName, AIndex, HICON(nil^), Result, 1)
    else
      ExtractIconEx(AFileName, AIndex, Result, HICON(nil^), 1);
  end
  else
  begin
    SHGetFileInfo(PWideChar(ExtractFileExt(AFileName)), FILE_ATTRIBUTE_NORMAL, LInfo,
      SizeOf(LInfo), IfThen(ASmall, SHGFI_SMALLICON, SHGFI_LARGEICON)
      or SHGFI_ICON or SHGFI_LINKOVERLAY or SHGFI_USEFILEATTRIBUTES);
    Result := LInfo.HIcon;
  end;
end;
Geht's denn beim ersten Aufruf von ExtractIconEx um die Ermittlung der Anzahl von Icons? Dann solltest du keinen Parameter für ein HICON übergeben.

Vielleicht kann eine Untersuchung auf Speicherlecks nicht schaden, mit einer Software, die auch Windows Handles mit untersucht; leider weiß ich nicht, was es da gibt, was für aktuellere/neuere Delphis taugt. FastMM bzw. ReportMemoryLeaksOnShutdown meldet nicht freigegebene Icons eben nicht, wie ich selber schon in einem ähnlichen Zusammenhang festgestellt habe.

Grüße
Dalai
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 00:33
Zitat:
Geht's denn beim ersten Aufruf von ExtractIconEx um die Ermittlung der Anzahl von Icons? Dann solltest du keinen Parameter für ein HICON übergeben.
Nein.. Es wird ein Icon für das Menu übergeben.. diese sind unterschiedlich.. hänge gleich mal einen Shot an.
Sorry ja dann dürfte das ausreichen oder?
If ExtractIconEx(AFileName, -1, HICON(nil^), HICON(nil^), 0) <> 0 then

Zitat:
ReportMemoryLeaksOnShutdown meldet nicht freigegebene Icons eben nicht, wie ich selber schon in einem ähnlichen Zusammenhang festgestellt habe.
Ja das war mein Problem habe nicht bedacht das ich so wie du bemerkt hast 2 Icons extrahiere.
Aber! Seltsam ist das schon denn die Icons liegen nur im Format 16x16 vor direkt von einem Icon File nicht aus einer EXE-Datei!
Habe auch im Taskmanager nicht feststellen können das sich der Speicher erhöht der blieb immer konstant.

Also das LDummy hätte eigentlich gar kein Icon ausgeben dürfen.
Weil kein Large Icon in der Icon Datei existiert.

Diese Icons werden addiert + die Icons für die Pfeile.
Danke nochmal für deine Hilfe.

Wenn ein Icon übergeben wird, wird dieses als Overlay auf den Button gezeichnet.
Delphi-Quellcode:
  if ImageIconPath <> 'then
   begin
     FIcon[ButtonCount].ImageIcon := GetHIconFromFile(ImageIconPath, true);
     if (FIcon[ButtonCount].ImageIcon <> 0) then
       btnMenu[ButtonCount].ImageDrop(HButton, FIcon[ButtonCount], X, Y, W, H);
   end;
und später mit
btnMenu[IntI].ImageDropRemove(btnMenu[IntI].Handle);

gelöscht..

gruss

Geändert von EWeiss ( 9. Jul 2019 um 09:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#6

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 01:06
Nein.. Es wird ein Icon für das Menu übergeben.. diese sind unterschiedlich.. hänge gleich mal einen Shot an.
Die Intention der Funktion GetHIcon insgesamt ist mir schon klar. Es ging mir nur um den darin enthaltenen Aufruf if ExtractIconEx(..., -1, ...) <> 0 . Das eigentliche Extrahieren der Icons erfolgt ja erst danach in einem weiteren Aufruf von ExtractIconEx (sofern der erste Aufruf klappte).

Anders ausgedrückt: Sofern das erste ExtractIconEx klappt, rufst du es danach nochmals auf. Wenn man die Doku zu MSDN-Library durchsuchenExtractIconEx ganz genau nimmt, holen beide Aufrufe (der mit -1 als Index und der mit dem eigentlichen Index) jeweils ein Icon:
Zitat:
nIconIndex
If this value is a negative number and either phiconLarge or phiconSmall is not NULL, the function begins by extracting the icon whose resource identifier is equal to the absolute value of nIconIndex.
Leider ist aus der Doku nicht ersichtlich, ob auch ein Icon geholt wird, wenn man ExtractIconEx(AFileName, -1, Result, HICON(nil^), 0) ruft, also nIconIndex=-1 und nIcons=0, aber trotzdem ein Ziel (hier Result) angegeben wurde.

Zitat:
Habe auch im Taskmanager nicht feststellen können das sich der Speicher erhöht der blieb immer konstant.
Schau lieber auf die Anzahl der Handles, ggf. im Process Explorer bzw. Process Hacker.

Zitat:
Danke nochmal für deine Hilfe.
Keine Ursache. Ich wusste nur deshalb um das Problem, weil ich es selbst schon hatte .

Grüße
Dalai
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 01:09
Zitat:
Die Intention der Funktion GetHIcon insgesamt ist mir schon klar. Es ging mir nur um den darin enthaltenen Aufruf if ExtractIconEx(..., -1, ...) <> 0. Das eigentliche Extrahieren der Icons erfolgt ja erst danach in einem weiteren Aufruf von ExtractIconEx (sofern der erste Aufruf klappte).
Sorry hatte dich nicht richtig verstanden habe es oben editiert.. aber hier nochmal..
If ExtractIconEx(AFileName, -1, HICON(nil^), HICON(nil^), 0) <> 0 then

oder besser so!
If ExtractIconEx(AFileName, -1, -1, -1) <> 0 then




gruss

Geändert von EWeiss (26. Apr 2019 um 01:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#8

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 01:19
Sorry hatte dich nicht richtig verstanden habe es oben editiert.. aber hier nochmal..
If ExtractIconEx(AFileName, -1, HICON(nil^), HICON(nil^), 0) <> 0 then
Ja, so meinte ich das.

Zitat:
oder besser so!
If ExtractIconEx(AFileName, -1, -1, -1) <> 0 then
Keine Ahnung, was dann passiert. Deutet die API die HICON-Parameter dann als NULL? Wäre ich mir nicht sicher genug, um es so zu benutzen.

Grüße
Dalai
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 01:24
Zitat:
Keine Ahnung, was dann passiert. Deutet die API die HICON-Parameter dann als NULL? Wäre ich mir nicht sicher genug, um es so zu benutzen.
Ich mache es wie im ersten Beispiel dann bin ich auf der sicheren Seite. Danke!

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#10

AW: IconHandle von Icon Datei

  Alt 26. Apr 2019, 01:27
Mir fällt gerade ein, dass es wohl gar nicht geht, eine Konstante (hier -1) als var -Parameter zu übergeben. Und die beiden HICON-Parameter von ExtractIconEx sind im Delphi als var deklariert. D.h. der Compiler müsste meckern, wenn 3x -1 übergeben wird.

Grüße
Dalai
  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 23:20 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