Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Resource wird nicht gefunden (https://www.delphipraxis.net/188740-resource-wird-nicht-gefunden.html)

Alter Mann 1. Apr 2016 15:56

Resource wird nicht gefunden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich möchte Bilder via TResourceStream laden, doch leider bekomme ich immer die
Fehlermeldung
Zitat:

Resource xxx nicht gefunden
.
Delphi-Quellcode:
...
{$R resources.res}
...

const
  IDB_0E00A = 100;    // PNG-Resource

...

procedure TForm1.LoadPNG(ID  : Integer);
var
  ResStream : TResourceStream;
  Png      : TPngImage;
begin
  try
    try
      ResStream := TResourceStream.CreateFromID(0, ID, RT_RCDATA);
      Png := TPngImage.Create;
      try
        Png.LoadFromStream(ResStream);
        Image1.Picture.Graphic := Png;
      finally
        Png.Free;
      end;
    except
      on E : Exception do
        ShowMessage(E.Message);
    end;
  finally
    if Assigned(ResStream) then
      ResStream.Free;                [COLOR="Lime"]<- Warum führt ein Free zu einem Fehler !!!?[/COLOR]
  end;
end;

...

LoadPNG(IDB_0E00A);
...
Die resources.res wird via brcc32 -32 resources.rc erzeugt und sind auch in der
Anwendung vorhanden.

Die Suche in der DP hat mich bisher nicht weiter geführt, daher:
Hat jemand einen Tipp/Hinweis?

Danke

DeddyH 1. Apr 2016 16:04

AW: Resource wird nicht gefunden
 
Hast Du es mal mit hInstance statt der 0 als Instanzhandle versucht?
Delphi-Quellcode:
ResStream := TResourceStream.CreateFromID(hInstance, ID, RT_RCDATA);
Zur AV: wenn Du schon das Create hinter das try setzt, solltest Du die Instanzvariable mit nil initialisieren.

Alter Mann 1. Apr 2016 17:18

AW: Resource wird nicht gefunden
 
hInstance bringt es auch nicht, damit hatte ich angefangen.
Bin dann aber bei FindResource auf diesen Hinweis gestoßen:

Zitat:

hModule [in, optional]
Type: HMODULE

A handle to the module whose portable executable file or an accompanying MUI file contains the resource.
If this parameter is NULL, the function searches the module used to create the current process.
Was die AV angeht: Der TResourcestream wird ja erstellt, er ist ja <> nil und trotzdem knallt es.

Sir Rufo 1. Apr 2016 19:43

AW: Resource wird nicht gefunden
 
  • Die Instanz wird nicht erzeugt, wenn im
    Delphi-Quellcode:
    constructor
    eine Exception kommt.
  • Die Instanzvariable ist eine lokale Variable und somit nicht initialisiert => da steht irgendwas drin.
  • Delphi-Quellcode:
    Assigned
    liefert
    Delphi-Quellcode:
    true
    wenn in der Instanzvariable irgendwas drin ist
    Delphi-Quellcode:
    <> nil
  • Delphi-Quellcode:
    TObject.Free
    prüft selber auch noch mal ob
    Delphi-Quellcode:
    <> nil
  • Es kann nicht festgestellt werden, ob die Instanzreferenz auf irgendeine Grütze oder eine intakte Instanz zeigt
  • Zeigt die Referenz auf Grütze, dann knallt es
Darum lautet das Pattern auch so
Delphi-Quellcode:
procedure bar;
var
  foo: TObject;
begin
  foo := TObject.Create;
  try
    ...
  finally
    foo.Free;
  end;
end;
oder
Delphi-Quellcode:
procedure bar;
var
  foo: TObject;
begin
  foo := nil;
  try
    foo := TObject.Create;

    ...
  finally
    foo.Free;
  end;
end;

Alter Mann 1. Apr 2016 20:08

AW: Resource wird nicht gefunden
 
@Sir Rufo

Nicht die Av ist das Problem.
Du liegst zwar grundsätzlich Richtig, aber im speziellem Fall wohl nicht(siehe Source-Code von TResurcestrem).
Delphi-Quellcode:
constructor TResourceStream.Create(Instance: THandle; const ResName: string; ResType: PChar);
begin
  inherited Create;
  Initialize(Instance, PChar(ResName), ResType, False);
end;
Ich vermute mal das es hier knallt(ungeprüft):
Delphi-Quellcode:
destructor TResourceStream.Destroy;
begin
  UnlockResource(HGlobal); [COLOR="MediumTurquoise"]<-[/COLOR]
  FreeResource(HGlobal);   [COLOR="MediumTurquoise"]<-[/COLOR]
  inherited Destroy;
end;

Sir Rufo 1. Apr 2016 20:41

AW: Resource wird nicht gefunden
 
Nein, tut mir leid, aber ich habe dein Projekt gerade mal mit dem Debugger durchgesteppt und die erste Exception wird hier geworfen:
Delphi-Quellcode:
constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer;
  ResType: PChar);
begin
  inherited Create;
  Initialize(Instance, PChar(ResID), ResType, True); // <- da kommt die Exception
end;
dann wird im gleichen Atemzug
Delphi-Quellcode:
TResourceStream.Destroy
ganz brav und ohne weitere Exception durchlaufen, dann kommt die Ausgabe der MessageBox mit der Exception.

Der lokalen Variablen
Delphi-Quellcode:
ResStream
wird kein Wert zugewiesen!

Den Rest der Begründung findest du in meinem Post vorher.

Wenn du mit Resourcen arbeiten möchtest, dann kannst du dir auch einmal diesen Post von mir anschauen
http://www.delphipraxis.net/1330587-post3.html

Um meine Aussage zu überprüfen brauchst du lediglich eine Zeile einfügen:
Delphi-Quellcode:
procedure TForm1.LoadPNG(ID : Integer);
var
  ResStream : TResourceStream;
  Png : TPngImage;
begin
  ResStream := nil; // eine Zeile, die tut auch nix, die will nur spielen!
  try
    try
      ResStream := TResourceStream.CreateFromID(0, ID, RT_RCDATA);
      Png := TPngImage.Create;
      try
        Png.LoadFromStream(ResStream);
        Image1.Picture.Graphic := Png;
      finally
        Png.Free;
      end;
    except
      on E : Exception do
        ShowMessage(E.Message);
    end;
  finally
    // kann ersatzlos entfallen
    // if Assigned(ResStream) then
      ResStream.Free; // <- Warum ein Free zu einem Fehler !!!? <- Kommt ja jetzt nicht mehr
  end;
end;
Und noch etwas zum Thema Resource-Dateien

Wenn du die *.RC Datei in dein Projekt aufnimmst, dann wird diese Datei automatisch beim Erzeugen des Projekts erstellt und eingebunden. Das umständliche und manuelle Erzeugen der *.res Datei entfällt.

So sieht das dann in der dpr aus
Delphi-Quellcode:
program ResTest;

{$R 'Resources.res' '..\Rescource\Resources.rc'} // <- diese Zeile wird automatisch von Delphi erstellt

uses
  Forms,
  frmMain in 'frmMain.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Alter Mann 2. Apr 2016 08:45

AW: Resource wird nicht gefunden
 
Moin, Moin,

@Sir Rufo

was die AV angeht: Ja da hast du recht, die Zeile bewirkt Wunder:oops:

Danke:!:

Was den Beitrag angeht, da bin ich mir nicht sicher(habe es noch nicht getestet); Das mit den 4 Bilderchen war/ist nur ein Beispiel. Ich brauche eine Lösung für ~1000 Bilderchen.

Also, warum findet der ResourceStream die Resourcen nicht?

Alter Mann 2. Apr 2016 09:33

AW: Resource wird nicht gefunden
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, da ich nicht beratungsresistent bin, habe ich den Beitrag aus
Funktion: Graphic anhand des Namens aus Res erstellen an D2009 angepasst
Delphi-Quellcode:
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  cboResources.Items.Clear;
  cboResources.Items.Add('IDR_LOADING');
  cboResources.Items.Add('IDB_0E00A');
  cboResources.Items.Add('IDB_0E00B');
  cboResources.Items.Add('IDB_0E00C');

  FResources := Resources.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FResources.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  case cboResources.ItemIndex of
    0 : Image1.Picture.Assign(Resources.BildA);
    1 : Image1.Picture.Assign(Resources.BildB);
    2 : Image1.Picture.Assign(Resources.BildC);
    3 : Image1.Picture.Assign(Resources.BildD);
  end;
end;
...
sowie

Delphi-Quellcode:
type
  Resources = class abstract
  private
    class var FBildA: TGraphicResource;
    class var FBildB: TGraphicResource;
    class var FBildC: TGraphicResource;
    class var FBildD: TGraphicResource;
  public
    constructor Create;
    destructor Destroy; override;
  public
    class property BildA: TGraphicResource read FBildA;
    class property BildB: TGraphicResource read FBildB;
    class property BildC: TGraphicResource read FBildC;
    class property BildD: TGraphicResource read FBildD;
  end;

implementation

{$R 'Resources.res' '..\Rescource\Resources.rc'}

{ Resources }

constructor Resources.Create;
begin
  FBildA := TGifResource.Create( 'IDR_LOADING' );
  FBildB := TPngResource.Create( 'IDB_0E00A' );
  FBildC := TPngResource.Create( 'IDB_0E00B' );
  FBildD := TBitmapResource.Create( 'IDB_0E00C' );
end;
und laufen lassen.

Das Ergebnis habe ich angehängt.

Das Problem mus also wo anders liegen:|

Die *.rc Datei sieht so aus:
Code:
LANGUAGE 0, SUBLANG_NEUTRAL
IDR_LOADING       GIF           "Loading.gif"

LANGUAGE 0, SUBLANG_NEUTRAL
IDB_0E00A         PNG           "smileys\\0E00A.PNG"

LANGUAGE 0, SUBLANG_NEUTRAL
IDB_0E00B         PNG           "smileys\\0E00B.PNG"

LANGUAGE 0, SUBLANG_NEUTRAL
IDB_0E00C         BMP           "smileys\\ACHTUNG.BMP"
Kann es an der Typ-Zuweisung liegen?

Sir Rufo 2. Apr 2016 09:51

AW: Resource wird nicht gefunden
 
Und wenn du deine RC Datei mal so anpasst?
Code:
LANGUAGE 0, SUBLANG_NEUTRAL
IDR_LOADING      RCDATA          "Loading.gif"

LANGUAGE 0, SUBLANG_NEUTRAL
IDB_0E00A        RCDATA          "smileys\\0E00A.PNG"

LANGUAGE 0, SUBLANG_NEUTRAL
IDB_0E00B        RCDATA          "smileys\\0E00B.PNG"

LANGUAGE 0, SUBLANG_NEUTRAL
IDB_0E00C        RCDATA          "smileys\\ACHTUNG.BMP"

Alter Mann 2. Apr 2016 10:09

AW: Resource wird nicht gefunden
 
So, nun verstehe ich nix mehr:oops:

Wenn ich die rc-Datei entsprechend anpasse, kann ich das GIF laden.
Bei allen anderen bleibt es dabei: Resource nicht gefunden.

Was mache ich da Falsch?

Update:

Es geht:wink:

Ich habe alle PNG/GIF usw. in der rc-Datei in RCDATA umbenannt. Und schon läuft es mit dem Resourcestream.

Danke für die Denkanstöße:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:49 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