Einzelnen Beitrag anzeigen

bluescreen25

Registriert seit: 27. Nov 2005
Ort: Geldern
229 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: loadfile aus TMemoryStream

  Alt 22. Feb 2008, 14:42
Zitat von Union:
Zitat:
bei Icons über Stream laden, bekomme ich noch nichts Sichtbares
Was willst Du auch sehen:
Delphi-Quellcode:
if LoadPicture(SkinPfad + 'icons\' + Ini.ReadString('Icons','Icon' + IntToStr(iIndex) + 'Picture','0'))then
  Icon.LoadFromStream(pFile);
// Das wird gemacht auch wenn LoadPicture fehlschlägt - Einrückung würde helfen das auf den ersten Blick zu sehen
IL.AddIcon(Icon);
// Und das free ist wohl auch daneben. Selbst wenn bisher alles funktioniert hast löschst Du das soeben eingelesene Icon wieder!
Icon.Free;
Danke für die Tipps. Nur dort ist der Fehler nicht zu suchen. Festgestellt habe ich, das meine Procedure LoadPicture casesensitive ist, im Gegensatz zu LoadfromFile. Der war es nämlich egal ob der komplette Pfad "C:\MeinProgramm\skins\*.*" oder "C:\MeinProgramm\Skins\*.*" hieß. Er hatte die Icons durch meine aFilename einfach nicht gefunden.

Das Icon gebe ich selbstverständlich wieder frei, nachdem ich es in die Imagelist kopiert habe.Wenn du gesehen hast, ist der Aufbau eine Schleife und somit würden nach Füllen der IL einige Icons im Speicher hängen.

Die Absicherung die du meinst, kommt auf jeden Fall rein, es sollte erstmal funktionieren und das tuts ja jetzt auch.

Zitat:
Zitat:
bei Images über Stream laden , bekomme ich eine exception: Bitmap ist ungültig
Delphi-Quellcode:
//Ist Menu ein String, der sollte die Section angeben?
iString := lowercase(Ini.ReadString(Menu,'Background','0'));
Und hast Du mal daran gedacht den Debugger zu verwenden?
In diesem Punkt liegst du leider völlig daneben. Das Problem ist das TImage und das kann mit png,jpg oder Bitmaps füllen.
Um das aus einem Stream wieder ins Image zu bekommen, muss man z.B. über ein TJPEGImage gehen. Deshalb die exception.
Nach einigem Einlesen in Stream in Verbindung mit Images kam ich dann zum Ergebnis.

Delphi-Quellcode:
SkinBackground := TImage.Create(SkinForm);
    with SkinBackground do
    begin
      Parent := SkinForm;
      Name := iString + '_Background';
      SetBounds(0,0, SkinWidth, SkinHeight);
      iString := lowercase(Ini.ReadString(Menu,'Background','0'));
      Picture.RegisterFileFormat('jpg; *.jpeg','JPEG',TBitmap);

      if LoadPicture(SkinPfad + iString)then
      begin
       if ExtractFileExt(SkinPfad + iString) = '.jpgthen
          begin
            TempJpeg := TJPEGImage.Create;
            TempJpeg.LoadFromStream(pFile);
            Picture.Graphic := TempJpeg;
            TempJpeg.Free;
          end else if ExtractFileExt(SkinPfad + iString) = '.pngthen
            begin
              TempPng := TPNGObject.Create;
              TempPng.LoadFromStream(pFile);
              Picture.Graphic := TempPng;
              TempPng.Free;
            end;
       end;
Hier nach der Reihe die verbauten Proceduren und Functionen:

Im Form.Create werden die Streams erstellt...und die Skindateien eingelesen:

Delphi-Quellcode:
procedure LoadMemory;
var lCount: Integer;
    ext :TStrings;
begin
  try
   lFile := TMemoryStream.Create(); //Gesamtstream aller Files
   pFile := TMemoryStream.Create(); //Stream eines ladenen File
   ext := TStringList.Create;
   ext.Add('.jpg');
   ext.Add('.png');
   ext.Add('.ico');
   ext.Add('.bmp');

   FindAllSkinFiles(Skinpfad,Skindateien[0],Skindateien[1],Skindateien[2],ext);
  finally
   ext.Free;
  end;
end;
In FindallSkinFiles fülle ich Stringlisten mit Size,Position und die Streams....wobei ich mir immer noch nicht sicher bin, ob die Dateien nicht zweimal angefasst werden, da Stream.LoadfromFile ja nach Aufspüren eines Files aufgerufen wird. Gibt es da bessere Möglichkeiten ?

Delphi-Quellcode:
procedure FindAllSkinFiles(const Path:String;FileNames,FileSize,FilePosition,Extensions:TStrings);
var Tick:Cardinal;

  procedure DoSearch(const Path:String);
  var SR : TSearchRec;
  begin
    If Findfirst(Path + '*.*',faAnyFile,SR) = 0 then
     try
       repeat
         if GetTickCount >= Tick then
         begin
           Tick:= GetTickCount +100;
           Application.ProcessMessages;
         end;

         If (SR.Attr and faDirectory <> 0) and (SR.Name <> '.') and (SR.Name <> '..') then
           DoSearch(Path + SR.Name + '\')
         else
           If Extensions.IndexOf(ExtractFileExt(SR.Name)) >= 0 then
           begin
             Skindateien[0].Add(Path + SR.Name);
             pFile.LoadFromFile(Path + SR.Name);
             Skindateien[1].Add(IntToStr(pFile.Size));
             Skindateien[2].Add(IntToStr(lFile.Position));
             lFile.CopyFrom(pFile,pFile.Size);
             pFile.Position := 0;
           end;
        until FindNext(SR) <> 0;
     finally
       FindClose(SR);
     end;
    end;

  begin
    try
     Tick := GetTickCount + 100;
     DOSearch(ExtractFilePath(Path));
    finally

    end;
 end;

Die Ladefunktion eines Files aus dem GesamtStream:

Delphi-Quellcode:
function LoadPicture(aFileName:String):Boolean;
var lCount,Position,Size : Integer;
begin
  pFile.Clear;
  pFile.Position := 0;
  lFile.Position := 0;
  for lCount:= 0 to Skindateien[0].Count-1 do
  if (aFileName = Skindateien[0].Strings[lCount]) or (lCount = Skindateien[0].Count-1) then break;

  if aFileName = Skindateien[0].Strings[lCount] then
  begin
    Size := StrToInt(Skindateien[1].Strings[lCount]);
    Position := StrToInt(Skindateien[2].Strings[lCount]);

    lFile.Position := Position;
    pFile.CopyFrom(lFile,Size);

    Result := True;
  end else Result:= False;

  pFile.Position := 0;
end;

Die Verwendung bei PNGObjectsbei Images wie jpg siehe oben)

Delphi-Quellcode:
if LoadPicture(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Up',''))then
        UpPicture.LoadFromStream(pFile);

Jemand noch eine Idee zum Laden aller Files in den Stream (FindAllSkinFiles) ?


Gruß, bluescreen
...und ich dachte, Delphi ist ein Programmgenerator mit nur einem Button......tzzz
  Mit Zitat antworten Zitat