Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Resourcen auflisten (https://www.delphipraxis.net/107110-resourcen-auflisten.html)

TonyMontana 22. Jan 2008 17:40


Resourcen auflisten
 
Kann mir jemand sagen, wie ich folgenden Quelltext anpassen muss, damit alle Resourcen korrekt aufgelistet werden?

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, StdCtrls, Menus;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    PopupMenu1: TPopupMenu;
    GetResources1: TMenuItem;
    procedure GetResources1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  NewNode: TTreeNode;
  Start: TTreeNode;

implementation

{$R *.DFM}

function EnumNamesFunc(hModule:THandle; lpType, lpName:PChar; lParam: DWORD):BOOL; stdcall;
begin
  Result := True;
  Form1.TreeView1.Items.AddChild(Start, lpName);
end;

function EnumTypesFunc(Handle: THandle; lpszType: PChar; lParam: DWORD):BOOL; stdcall; // --> Parameter Dekl. korrekt?
begin
 Result := True;
 Start := Form1.TreeView1.Items.AddChild(NewNode, 'bla');
//Start := Form1.TreeView1.Items.AddChild(NewNode, lpszType); --> funktioniert nicht!
 EnumResourceNames(0, lpszType, @EnumNamesFunc, 0);
end;

procedure TForm1.GetResources1Click(Sender: TObject);
begin
   TreeView1.Items.BeginUpdate;
   TreeView1.Items.Clear;
   NewNode := TreeView1.Items.Add(nil, 'Resources');
   EnumResourceTypes(0, @EnumTypesFunc, 0);
   TreeView1.FullExpand;
   TreeView1.Items.EndUpdate;
end;

end.
Das Problem ist, dass nur Resourcen aufgelistet werden, dessen ID ein String ist und komischerweise(?) gar keine Resourcen aufgelistet werden, sobald ich die lpszType Variable benutze (siehe auskommentierte Zeile oben)!

Dann noch ne kleine Frage am Rande, ist die Parameter Deklaration der Funktion EnumTypesFunc so korrekt? Ich tuhe mich immer schwer, von C nach Delphi zu übersetzen. Vielleicht kann mir der ein oder andere ja einen Tip geben, wo ich nachschauen kann wie die Pendants bestimmter Variablentypen von C in Delphi aussehen!

Eine kleine Frage noch ... THandle ist doch gleich Integer. Aber Handles sind doch immer positiv oder 0? Dann könnte ich doch gleich Cardinal nehmen, oder???

Danke!

Apollonius 22. Jan 2008 18:02

Re: Resourcen auflisten
 
Momentan ist THandle ein Cardinal, ich weiß aber nicht, wie das in 64-Bit-Windows-Versionen ist, da ist Cardinal schließlich auch größer.
Name und Typ von Resourcen können sowohl PChars als auch IDs sein (siehe auch MakeIntAtom). Das steht übrigens auch in der MSDN. Du kannst auf jeden Fall bei beiden Enum*-Callback-Funktionen mit IS_INTRESOURCE prüfen, ob eine ID oder ein Namensstring vorliegt und dann entsprechend nach Cardinal casten und IntToStr verwenden oder den PChar verwenden.
IS_INTRESOURCE gibt es allerdings in der Standard-Windows-Unit nicht. Du musst also entweder eine andere Unit verwenden (z.B. JwaWindows von den Jedis) oder die Funktion nachbilden: Die Beschreibung gibt es hier.

TonyMontana 22. Jan 2008 19:31

Re: Resourcen auflisten
 
Zitat:

Zitat von Apollonius
Momentan ist THandle ein Cardinal, ich weiß aber nicht, wie das in 64-Bit-Windows-Versionen ist, da ist Cardinal schließlich auch größer.

Ok, dann ist die Deklaration der EnumCallback Funktionen warscheinlich so korrekt.


Zitat:

Zitat von Apollonius
Name und Typ von Resourcen können sowohl PChars als auch IDs sein (siehe auch MakeIntAtom).

Daran liegt das also... Ich weiß leider nicht, wie das mit den Atoms funktioniert.

Zitat:

Zitat von Apollonius
Du kannst auf jeden Fall bei beiden Enum*-Callback-Funktionen mit IS_INTRESOURCE prüfen, ob eine ID oder ein Namensstring vorliegt und dann entsprechend nach Cardinal casten und IntToStr verwenden oder den PChar verwenden.

Ich bekomme es irgendwie nicht hin :|

Die Funktion habe ich jetzt so implementiert:
Delphi-Quellcode:
function IS_INTRESOURCE(wInteger: WORD): BOOL;
begin
  Result := (LongWord(wInteger) shr 16) = 0;
end;
Wie ist eigentlich die Reihenfolge von LongWords, also LoWord - HiWord oder HiWord - LoWord? Was passiert dementsprechend bei einem TypeCast LongWord(Word)? Wird das Word dann zum HiWord oder LoWord? :oops:

Wie muss ich IS_INTRESOURCE verwenden und wie muss ich die einzelnen Variablen Typecasten, damit die Resourcen richtig aufgelistet werden? So wie ich es versucht habe, liefert mir IS_INTRESOURCE immer True...

Apollonius 23. Jan 2008 13:44

Re: Resourcen auflisten
 
Eigentlich heißt das entsprechende Makro MakeIntResource und nicht MakeIntAtom, aber die beiden machen sowieso das gleiche.
Ich glaube, dass IS_INTRESOURCE in der MSDN falsch deklariert ist. Makros kennen ja sowieso keine Typen, insofern ist die Parameter-Deklaration obsolet. In einer Übersetzung solltest du den Parameter als Cardinal deklarieren, denn wenn man ein Word 16 Bytes nach rechts shiftet, kann nur Null rauskommen. Probiere es damit nochmal.

TonyMontana 23. Jan 2008 17:05

Re: Resourcen auflisten
 
Ja, genau das habe ich mir nämlich auch gedacht bzw. hatte den Verdacht, dass ein Boolsche Überprüfung dieser Art wohl zu nichts sinnvollem führt :zwinker:

Habe es jetzt noch mal mit MakeIntResource probiert und siehe da, es funktioniert! :cheers:

Danke für deine Hilfe, auch wenn ich nicht immer ganz verstanden habe wie ich das machen soll, hat mich das doch auf die richtigen Ideen gebracht :thumb:

Zwei Fragen habe ich aber trotzdem noch ...

Was soll diese Deklaration?
Delphi-Quellcode:
...
  {$EXTERNALSYM RT_CURSOR}
  RT_CURSOR      = MakeIntResource(1);
...
  {$EXTERNALSYM RT_ICON}
  RT_ICON        = MakeIntResource(3);
...
  {$EXTERNALSYM DIFFERENCE}
  DIFFERENCE = 11;

  {$EXTERNALSYM RT_GROUP_CURSOR}
  RT_GROUP_CURSOR = MakeIntResource(DWORD(RT_CURSOR + DIFFERENCE));
  {$EXTERNALSYM RT_GROUP_ICON}
  RT_GROUP_ICON  = MakeIntResource(DWORD(RT_ICON + DIFFERENCE));
...
Warum steht da nicht einfach folgendes:
Delphi-Quellcode:
  {$EXTERNALSYM RT_GROUP_CURSOR}
 //11+1 = 12 -->
  RT_GROUP_CURSOR = MakeIntResource(12);
  {$EXTERNALSYM RT_GROUP_ICON}
 //11+3 = 14 -->
  RT_GROUP_ICON  = MakeIntResource(14);
Und warum ein DWORD TypeCast?

Die Frage nach der Reihenfolge von LoWord und HiWord in einem DWORD ist auch noch nicht geklärt!

Ich denke mal es ist so, oder? Jedenfalls wäre es für mich so logisch: DWORD = HiWord + LoWord.

PS: Hat jemand noch nen Tip wo ich Hilfe finde, um C(++) Quelltexte nach Delphi zu portieren? Ansonsten muss ich nen neuen Thread aufmachen und da fragen :mrgreen:

:bounce1: :bouncing4: :bounce1: :bouncing4: :bounce1: :bouncing4: :bounce1: :bouncing4:

Apollonius 23. Jan 2008 19:53

Re: Resourcen auflisten
 
Wenn du ein Word nach DWord (bzw. Cardinal) castet, wird das Word logischerweise ins LoWord reingepackt. Sonst wäre ja DWord(Word(5))<>DWord(5).

Ich vermute mal, dass die Werte 12 und 14 nicht direkt angegeben werden, um zu zeigen, dass der GROUP-Wert immer gleich dem normalen Wert plus 11 ist.

TonyMontana 23. Jan 2008 23:45

Re: Resourcen auflisten
 
Ja, jetzt wo ich so drüber nachdenke, macht alles Sinn was du sagst :thumb:

Dann ist das Thema ja jetzt erledigt :dancer2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz