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) = '.jpg' then
begin
TempJpeg := TJPEGImage.Create;
TempJpeg.LoadFromStream(pFile);
Picture.Graphic := TempJpeg;
TempJpeg.Free;
end else if ExtractFileExt(SkinPfad + iString) = '.png' then
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 PNGObjects
bei 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