Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Bilder von DLL in ImageList (https://www.delphipraxis.net/97556-bilder-von-dll-imagelist.html)

dominikkv 12. Aug 2007 19:44


Bilder von DLL in ImageList
 
Hi

ich habe Bilder zu einer Ressource einer DLL hinzugefügt (Tutorial)
Nun möchte ich die Bilder in eine Imagelist laden.
Das mache ich bisher so:

Delphi-Quellcode:
procedure TForm1.LoadImages;
var
  h :HINST;
  r :TResourceStream;
  j :TJpegImage;
  im: TImage;
begin
  h := LoadLibrary('pBilder.dll');
  if h <> 0 then
  begin
    r := TResourceStream.Create(h, 'Bild1', 'Jpeg');
    j := TJpegImage.Create;
    im := TImage.create(self);
      try
        j.LoadFromStream(r);
        Im.Picture.Bitmap.Assign(j);
        test.Add(im.Picture.Bitmap, im.Picture.Bitmap); // test ist die ImageList
      finally
        j.Free;
        r.Free;
        im.free;
      end;
  end;
  FreeLibrary(h);
end;
Blöderweise kommt nach der Procedur eine AV.
Also wenn ich Schritt-für-Schritt Debugging mache klappt die Prozedur ohne Probleme, dannach kommen ein paar Assembleranweisungen und dann die AV.

Ohne die Procedur kommt die AV nicht.

Meine Frage also:
Was mach ich falsch bzw gibt es einen "professionelleren" Weg als meinen?

mfg.Dominik

turboPASCAL 12. Aug 2007 20:50

Re: Bilder von DLL in ImageList
 
Delphi-Quellcode:
try
        j.LoadFromStream(r);
        Im.Picture.Bitmap.Assign(j); // <--<< (1)
        test.Add(im.Picture.Bitmap, im.Picture.Bitmap); // <--<< (2)
(1) Du lädst ein JPEG in ein Bitmap, das klappt ja nun nicht.

Bitte so:
Delphi-Quellcode:
Im.Picture.Assign(j);
(2) Da du nun ein JPEG und kein Bitmap hast musst du das Image noch zu einem Bitmap wandeln:
Delphi-Quellcode:
/////////////////////////////////////////////////////
// Convert a JPEG / PNG / GIF etc to Bitmap
// Attention: not for Icons and Metaliles

procedure ImageToBitmap(Img: TImage);
var
  Pic: TPicture;
begin
  Pic := TPicture.Create;
  try
    Pic.Assign(Img.Picture);
    Img.Picture.Bitmap.Assign(Pic.Graphic);
  finally
    FreeAndNil(Pic);
  end;
end;

procedure TForm1.LoadImages;
//...
ImageToBitmap(Im);
test.Add(im.Picture.Bitmap, im.Picture.Bitmap);
//...

dominikkv 12. Aug 2007 21:40

Re: Bilder von DLL in ImageList
 
ok, hab mir das mal zu herzen genommen^^

jetzt sieht das ganze so aus:

Delphi-Quellcode:
procedure ImageToBitmap(Img: TImage);
var
  Pic: TPicture;
begin
  Pic := TPicture.Create;
  try
    Pic.Assign(Img.Picture);
    Img.Picture.Bitmap.Assign(Pic.Graphic);
  finally
    FreeAndNil(Pic);
  end;
end;

procedure TForm1.LoadImages;
var
  h :HINST;
  r :TResourceStream;
  j :TJpegImage;
  im: TImage;
  I: Integer;
  Namen: TStringList;
begin
  Namen := TStringList.Create;
  Namen.Add('bWdhTrackp');     Namen.Add('bWdhTrack');
  Namen.Add('bWdhp');          Namen.Add('bWdhNonep');
  Namen.Add('bWdhNone');

  h := LoadLibrary('pBilder.dll');
  if h <> 0 then
    for I := 0 to 4 do
    begin
      r := TResourceStream.Create(h, Namen[I], 'Jpeg');
      j := TJpegImage.Create;
      im := TImage.create(self);
        try
          j.LoadFromStream(r);
          Im.Picture.Assign(j);
          ImageToBitmap(Im);
          test.Add(im.Picture.Bitmap, im.Picture.Bitmap);
        finally
          j.Free;
          r.Free;
          im.free;
        end;
    end;
  FreeLibrary(h);
  Namen.free;
end;
leider kommt immernoch die AV.
Ich hab aber etwas interessantes festgestellt:
er führt nur die erste schleife aus, dann beim
Delphi-Quellcode:
im.free
springt er in die Unit System zu
Delphi-Quellcode:
        CALL   SysInit.@GetTLS
        MOV    ECX,[EAX].RaiseListPtr
        MOV    EDX,[ECX].TRaiseFrame.NextRaise
        MOV    [EAX].RaiseListPtr,EDX
        ADD    ESP,5*4                 { Remove local RaiseList       }
 [...]
nach so ca 100 befehlen kommt dann die AV.

dominikkv 12. Aug 2007 22:13

Re: Bilder von DLL in ImageList
 
ok, den code hatte ich nach dem create meiner forms ausgeführt.

ich hab mir jetzt mal nen button draufgeklatscht und dann über den button die procedur eingbunden, jetzt kommt die AV unmittelbar nach dieser Zeile:
Delphi-Quellcode:
test.Add(im.Picture.Bitmap, im.Picture.Bitmap);
ist das die richtige art ein bild in eine ImageList zu adden?

turboPASCAL 12. Aug 2007 22:35

Re: Bilder von DLL in ImageList
 
Zitat:

Zitat von dominikkv
Delphi-Quellcode:
procedure ImageToBitmap(Img: TImage);
//...

procedure TForm1.LoadImages;
var
  h :HINST;
  r :TResourceStream;
  j :TJpegImage;
  im: TImage;
  I: Integer;
  Namen: TStringList;
begin
  Namen := TStringList.Create;
  Namen.Add('bWdhTrackp');     Namen.Add('bWdhTrack');
  Namen.Add('bWdhp');          Namen.Add('bWdhNonep');
  Namen.Add('bWdhNone');

  h := LoadLibrary('pBilder.dll');
  if h <> 0 then
    for I := 0 to 4 do // <--<<
    begin
      r := TResourceStream.Create(h, Namen[I], 'Jpeg'); // <--<<
      j := TJpegImage.Create; // <--<<
      im := TImage.create(self); // <--<<
        try
          j.LoadFromStream(r);
          Im.Picture.Assign(j);
          ImageToBitmap(Im);
          test.Add(im.Picture.Bitmap);
        finally
          j.Free; // <--<<
          r.Free; // <--<<
          im.free; // <--<<
        end;
    end;
  FreeLibrary(h);
  Namen.free;
end;

Also, eine AV -Fehlerstelle kann ich jetzt so nicht sehen. Aber das du Objekte zu "Wegwerfartikeln" machst obwohl man es geschickter anstellen könnte...

Delphi-Quellcode:
procedure TForm1.LoadImages;
var
  h :HINST;
  r :TResourceStream;
  j :TJpegImage;
  im: TImage;
  I: Integer;
  Namen: TStringList;
begin
  Namen := TStringList.Create;
  Namen.Add('bWdhTrackp');
  Namen.Add('bWdhTrack');
  Namen.Add('bWdhp');
  Namen.Add('bWdhNonep');
  Namen.Add('bWdhNone');

  h := LoadLibrary('pBilder.dll');
  if h <> 0 then
  begin
    j := TJpegImage.Create;
    im := TImage.create(self);
    try
      for i := 0 to Namen.Count - 1 do
      begin
        r := TResourceStream.Create(h, Namen[I], 'Jpeg');
        try
          j.LoadFromStream(r);
          Im.Picture.Assign(j);
          ImageToBitmap(Im);
          test.Add(im.Picture.Bitmap, im.Picture.Bitmap);
        finally
          r.Free;
        end;
      end;
    finally
      j.Free;
      im.free;
    end;
  end;
  FreeLibrary(h);

  Namen.free;
end;
(nur mal so ins blaue getippt)

Hänge doch mal das Projekt als Zip an ,dann könnte man mal nachgucken.

dominikkv 13. Aug 2007 18:09

Re: Bilder von DLL in ImageList
 
haha...mein Delphi verarscht sich selbst... :wall:
Wenn ich eine ImageList auf meine Form ziehe trägt er diese automatsch in die public-section meiner Form statt direkt unter dem namen ein...
Delphi-Quellcode:
type
  TfSoFi = class(TForm, IDropSource)
     // hier hin sollte die deklaration
  private

  public
    test: TImageList; // und hier ist sie
  end;
Folge: die ImageList wird nicht erzeugt und gibt daher ne AV beim Adden...

Das komische daran ist das das nur bei dieser einen Form passiert... mit anderen Forms hatte ich das Problem noch nie.
Und auch Ereignis-Routinen (zB Button1Click) die ich aus dem OI erstelle landen im public-Teil.
Aber ich würd sagen ich mache wegen der Frage nen neuen Thread auf, da die alte Frage ja jetzt geklärt ist...
Danke nochmal an turboPASCAL wegen dem richtigen umwandeln der Bilder und den Tipps...

mfg.Dominik

dominikkv 13. Aug 2007 19:28

Re: Bilder von DLL in ImageList
 
noch eine klitzekleine Frage:
Als ich die Bilder zur Designtime hinzugefügt habe hab ich immer "Zentrieren" in der Imagelist ausgewählt.
Wie kann ich das jetzt über den quellcode machen?


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