Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Skinroutine schneller machen (https://www.delphipraxis.net/108786-skinroutine-schneller-machen.html)

bluescreen25 19. Feb 2008 15:44


Skinroutine schneller machen
 
Hallo, ich lade meine Buttons als Bilder dynamisch durch eine Schleife durch eine Skin.ini, in der die Positionen und Dateinamen der Images hinterlegt sind.

Das dauert sehr lange, da viele Einzeldateien und Festplattenzugriffe zwischen ini und Skinordner mit den Bildern erfolgen.

Die Frage die sich stellt ist, ob es etwas bringt, den Skinordner in ein Zip zu packen (Kompressionsrate unerheblich, kann auch 0 sein) und beim Starten des Programms die eine Zip im Speicher zu entpacken und dann die Skinroutine ablaufen kann.

Ich wählte das Zip , so das ein Benutzer (Skinner) selbst sich das Zip erstellen kann.

Wie kann ich dann das entpackte Zip im Stream nutzen ?
Wenn ich in der Skinroutine (Schleife) so abfrage:

[delphi
UpPicture.LoadFromFile(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Up',''));[/delphi]
...sprich den Dateinamen des Bildes...

Bringt dieser Ansatz was und ich bräuchte das Hilfe, weil ich mit Streams überhaupt nicht auskenne.

Gruß, bluescreen25

Bernhard Geyer 19. Feb 2008 15:48

Re: Skinroutine schneller machen
 
Probier lieber mal mit AQTime oder nicht was anderes das bremsene Element ist. Ich glaube nicht das die Dateibestimmung und das laden wirklich das bremsende Element ist.

bluescreen25 19. Feb 2008 16:28

Re: Skinroutine schneller machen
 
Zitat:

Zitat von Bernhard Geyer
Probier lieber mal mit AQTime oder nicht was anderes das bremsene Element ist. Ich glaube nicht das die Dateibestimmung und das laden wirklich das bremsende Element ist.

Ich lade es gerade mal runter. Mal schaun.

Hier mal ein Auszug der Schleife rein nur für die Buttons einzulesen, alle anderen Elemente sindähnlich aufgebaut:

Delphi-Quellcode:
for iIndex := 0 to 30 do
    begin
      iString := lowercase(Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Function','0'));
      If iString = '0' then Goto ButtonEnde;
      SkinButton := TcAVeButton.Create(SkinForm);
      with SkinButton do
      begin
        FunktionButton[Skin].Add(iString);
        Parent := SkinForm;
        Aktion := Menu;
        Tag := iIndex;
        Funktion := iString;
        TouchMode := Touch;
        FixMode := TouchFix;

        if FileExists(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Up','')) then
        UpPicture.LoadFromFile(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Up',''));
        OverPicture := UpPicture;
        DownPicture := UpPicture;
        if FileExists(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Over','')) then
        OverPicture.LoadFromFile(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Over',''));
        if FileExists(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Down','')) then
        DownPicture.LoadFromFile(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'Down',''));
        if FileExists(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'StatusTrue','')) then
        BoolTruePicture.LoadFromFile(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'StatusTrue',''));
        if FileExists(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'StatusFalse','')) then
        BoolFalsePicture.LoadFromFile(SkinPfad + Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'StatusFalse',''));

        BoolPicXPos := Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'PicXPos',0);
        BoolPicYPos := Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'PicYPos',0);
        SetBounds(Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'X',0),Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'Y',0),UpPicture.Width ,UpPicture.Height);

        KeyListX[Skin].Add(IntToStr(Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'X',0)+ (UpPicture.Width div 2)));
        KeyListY[Skin].Add(IntToStr(Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'Y',0)+ (UpPicture.Height div 2)));
        if SkinButton.Funktion = 'executeapp' then AppIndex := Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'AppIndex',0);

        Font.Color := HTMLColorToColor(Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'LabelColor','&H000000'));
        Font.Name := Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'LabelFont','Arial');
        Font.Size := Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'LabelFontSize',0);
        iString := lowercase(Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'LabelFunction',''));
        if (iString <> '') and (iString <> 'text') then FunktionButtonLabel[Skin].Add(iString);
        Caption := Ini.ReadString(Menu,'Button' + IntToStr(iIndex) + 'LabelCaption','');
        LabelXPos := Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'LabelX',0);
        LabelYPos := Ini.ReadInteger(Menu,'Button' + IntToStr(iIndex) + 'LabelY',0);
        OnMouseDown := SkinButtonMouseDown;
        OnMouseUp := SkinButtonMouseUp;
        OnClick := SkinButtonClick;

      end;

      if (iString <> '') and (iString <> 'text') then ObjektButtonLabel[Skin].Add(SkinButton);
      ObjektButton[Skin].Add(SkinButton);
      Application.ProcessMessages;
    end;

ButtonEnde:
Ob das ne Bremse din ist, weiss ich net.

Gruß, bluescreen

busybyte 19. Feb 2008 16:32

Re: Skinroutine schneller machen
 
Du verwendest ein echtes Inifile im Textformat,das ist Deine erste Bremse und nur für kleine Dateien geeignet.
Speichere und lade mit einem Stream,das ist zwar nicht so übersichtlich, aber um einiges schneller.
Ansonsten bräuchten wir wohl etwas mehr Kot.

Delphi-Quellcode:
unit MyStream_U;
interface

Uses Classes;  //TStream

Procedure WriteInt(Stream:TStream;I:Longint);
Procedure ReadInt(Stream:TStream;Var I:Longint);
Procedure WriteStr(Stream:TStream;S:String);
Procedure ReadStr(Stream:TStream;Var S:String);

implementation
//StreamPocedures
Procedure WriteStr(Stream:TStream;S:String);
Var Len:Longint;
begin
Len:=Length(S);
Stream.Write(Len,SizeOf(Len));
Stream.Write(PChar(S)^,Len);
end;

Procedure WriteInt(Stream:TStream;I:Longint);
begin
Stream.Write(I,SizeOf(I));
end;


Procedure ReadStr(Stream:TStream;Var S:String);
Var Len:Longint;
begin
Stream.Read(Len,Sizeof(Len));
Setlength(S,Len);
Stream.Read(PChar(S)^,Len);
end;

Procedure ReadInt(Stream:TStream;Var I:Longint);
begin
 Stream.Read(I,SizeOf(I));
end;

/////  Stream Ende

end.
Delphi-Quellcode:
Uses MyStream_U; //Edit

Function MySave(Filename_:String):Boolean;
Var
Stream:TStream;
Len:integer;
cnt1:integer;
begin
result:=false;
while Filename_='' do exit;

with GLAudioForm do
 Try
 Stream:=TFilestream.Create(Filename_,fmcreate);

 //Audiokat - Beispiel nicht copy/paste fähig
 Len:=Length(AudioKat);
 WriteInt(Stream,Len);
  for cnt1 := 0 to Len- 1 do
  begin
  TestS:=AudioKat[cnt1].AKFilename;
  writeStr(Stream,AudioKat[cnt1].AKFilename);
  end;
.
.
.
Delphi-Quellcode:
Uses MyStream_U; //Edit

Function MyLoad(Filename_:String):Boolean;
Var
Stream:TStream;
Len:integer;
cnt1:integer;
SData:String;
//f: PChar;

begin
Result:=False;
Len:=0;
 while not Fileexists(Filename_) do
  begin
  exit;
  end;

Stream:=TFileStream.Create(Filename_,fmOpenread);
with GLAudioForm do
Try
//AudioKat
ReadInt(Stream,Len);
Setlength(AudioKat,Len);
 for cnt1 := 0 to Len- 1 do
  begin
  ReadStr(Stream,SData);
  Add_to_AudioKat(SData,cnt1);
  end;
.
.
.

grenzgaenger 19. Feb 2008 21:43

Re: Skinroutine schneller machen
 
sag mal, warum verwendest du kein 3 Pass verfahren?

1. ermitteln welche bildchen du brauchst
2. bildchen laden
3. bildchen zuweisen

dann brauchste 'n bildchen nicht 1'000 mal von der platte kratzen, sondern nur noch einmal.. denke, dann geht dein progy ab wie 'ne rakete..

bluescreen25 20. Feb 2008 04:59

Re: Skinroutine schneller machen
 
Zitat:

Zitat von grenzgaenger
sag mal, warum verwendest du kein 3 Pass verfahren?

1. ermitteln welche bildchen du brauchst
2. bildchen laden
3. bildchen zuweisen

dann brauchste 'n bildchen nicht 1'000 mal von der platte kratzen, sondern nur noch einmal.. denke, dann geht dein progy ab wie 'ne rakete..

Ich lade ja beim Start mehrmals das gleiche Bild, aber nur dadurch, wenns es auf verschiedenen Forms gebraucht wird. Es ist ja ein Skin, wo der User in der ini den Aufbau bestimmt.Deshalb wollte ich ja wenigstens davon abkommen, diese nicht immer von der Festplatte neu zu laden.

Das Programm lädt alle verwendeten Grafiken nur zum Start, wollte keine Aufbauverzögerungen bei den Form(Menüwechseln) haben.


Ich kenne das 3 Pass Verfahren nicht. Hast du mehr Infos ?

Gruß, bluescreen


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