![]() |
dfm resource in EXE zur laufzeit speichern->schreibgeschü
Hallo DP.
Wie der titel schon sagt: Ich möcht die dfm-formular daten zur laufzeit zurück in die resourcen schreiben...habe aber das problem, dass ER behauptet sie seien schreib geschützt! Was ja verständlich ist, da ich EXE ja gerade ausführe. Mein code bis jetzt:
Delphi-Quellcode:
damit will ich immerwährende persistenz erreichen :-D ...hoffe ihr habt eine idee, wie dies möglich ist?
destructor TForm1.Destroy;
var resStream:TResourceStream; begin resStream:=TResourceStream.Create(FindResourceHInstance(FindClassHInstance(ClassType)), ClassName, RT_RCDATA); try resStream.WriteComponentRes(ClassName, self); finally resStream.Free; end; inherited; end; mfg. maximov. |
Re: dfm resource in EXE zur laufzeit speichern->schreibge
ich kenn mich da zwar nicht richtig aus, aber wäre es denn nicht möglich,
die Datei zu kopieren und dann auf deren Inhalte draufzuzugreifen ? |
Re: dfm resource in EXE zur laufzeit speichern->schreibge
hmmm... dann hab ich zwei exe dateien, wo nur eine sein sollte. Also uncool, wenn du verstehst was ich meine :wink: ...sollte schon der direkte weg sein.
|
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Während der Ausführungszeit wird das Binary schreibgeschützt bleiben, weil Windows hier eine spezielle Technik (MemoryMappedFiles) einsetzt, um nicht alles im RAM halten zu müssen...
Was spricht dagegen, eine "externe" DFM zu benutzen, die an Stelle der gelinkten interpretiert wird, sofern sie existiert? Dein Programm könnte diese Datei dann erstellen und beim nächsten Start würden diese Daten verwendet werden... |
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Hab die idee glatt mal getestet...und es funktioniert auch wunderbar. Der folgende code sorgt dafür, das die dfm-daten aus der dfm datei geladen wird:
Delphi-Quellcode:
...ABER das führt zu einer reihe von schwierigkeiten, da änderungen am formular nur nach expliziten speichern in der dfm-datei stehen, die dann evtl ohne diese änderungen, beim start des grogs geladen wird. Beendet man dann das prog werden die dfm-daten, ohne die änderungen, gespeichert und delphi fragt dann ob die 'neue' dfm geladen werden soll! Wenn man dann nicht tierisch aufpasst und >nein< drückt wird die arbeit zunichte gemacht. Drückt man tatsächlich nein, dann sind die änderungen, die man zur laufzeit gemacht hat futsch. :(
constructor TForm1.Create(AOwner: TComponent);
begin // inherited; // <- standard initialisierung von delphi abklemmen GlobalNameSpace.BeginWrite; try CreateNew(AOwner); if (ClassType <> TForm) and not (csDesigning in ComponentState) then begin Include(FFormState, fsCreating); try LoadCompoFromFile(self,ExtractFilePath(paramstr(0))+'fm1.dfm'); // hier wäre noch interessant den unit-namen auszulesen? finally Exclude(FFormState, fsCreating); end; if OldCreateOrder then DoCreate; end; finally GlobalNameSpace.EndWrite; end; end; ... destructor TForm1.Destroy; begin SaveCompoToFile(self,ExtractFilePath(paramstr(0))+'fm1.dfm'); inherited; end; Diese methode ist zu verwirrend für den programmierer :? Gibt es wirklich keine methode die resource in diese 'MemoryMappedFiles' zu schreiben? Möglicherwiese über umwege? cu, maximov |
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Zitat:
Hierzu würde sich ein Konstruktur eignen, der einen Stream, in dem die Daten enthalten sind, übergeben bekommt, zB
Delphi-Quellcode:
im Konstructor Create(AOwner: TComponent) könntest Du dann prüfen, ob die optionale dfm-Datei existiert und einen FileStream erzeugen oder den ResourceStream, wie in der StdImplementierung. Anschließend ruft er den Konstruktor CreateFromStream auf, etwa so:
constructor TForm1.CreateFromStream(AOwner: TComponent; ADFMStream: TStream);
begin //... LoadCompoFromStream(Self, ADFMStream); //... end;
Delphi-Quellcode:
Durch diese Abstraktion wäre se später auch denkbar, mit Datenbanken statt mit Dateien zu arbeiten...
constructor TForm1.Create(AOwner: TComponent);
var myStream: TStream; begin //create stream with dfm-data either from file or from res if FileExists(GetDFMFilename) then myStream:= TFileStream.Create(GetDFMFilename) else myStream:= //as implemented in unit Classes //create instance w data from stream try CreateFromStream(AOwner, myStream); finally myStream.Free; end; end; Den Unit-Dateinamen der Klasse (zB um GetDFMFilename zu implementieren) bekommst Du übrigens mithilfe der RTTI heraus (TTypeData.UnitName). Achja, der Code und das Verfahren ist nicht von mir getestet worden. Zitat:
|
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Diese ausführung wäre natürlich auch nicht zu verübeln...allerdings ist das grundproblem das selbe. Sobald hier die dfm datei vorhanden ist wird sie benutzt und die änderungen im original werden übergangen :? Deshalb wäre es mir lieb, wenn ins original gespeichert wird, also beides ins die dfm-datei (dann hab ich änderungen von der laufzeit zur designzeit -> sehr cool) und in die exe-res da so die konstitenz gewahrt bleibt :roll:
Wenn das wirklich nicht möglich ist? Dann müsste ich selektiv lesen, also jedesmal entscheiden woher ich die dfm daten lese :cry: @RTTI: danke für den tip :-D ...auch danke für die mühe. @MemoryMappedFileHandle: Kann ich das handle vielleicht irgendwie schliessen, oder irgendeiner 'sharedMode' benutzen? Vielleicht können noch andere in ihre trickkiste greifen und mir hier helfen? ...Wenn es hinhaut ist das sicher auch für viele andere zu verwenden. mfg. maxímov |
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Zitat:
Zitat:
Zitat:
|
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Ich brauch das, damit alle eingaben positionen etc erhalten bleiben, ohne den geringsten aufwand. Vollständige persistenz eben :wink:
|
Re: dfm resource in EXE zur laufzeit speichern->schreibge
Bin gespannt...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:03 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