View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001421 | JEDI VCL | 00 JVCL Components | public | 2004-03-04 05:51 | 2004-03-28 06:27 |
| Reporter | anonymous | Assigned To | jfudickar | ||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | closed | Resolution | no change required | ||
| Product Version | |||||
| Target Version | Fixed in Version | ||||
| Summary | 0001421: TJvAppIniStorage losing stored properties | ||||
| Description | When you use more than one main form, TJvAppIniStorage will reset all stored properties back to the inherited vaules on the sub forms when the sub forms are .free from the main form. This was tried with no luck: FrmSub.JvAppIniFileStorage2.Flush; FrmSub.JvAppIniFileStorage2.Reload; (The resulting ini file was good at this point) But after FrmSub.Free all properties in the ini file were reset again. There is also a JvAppIniFileStorage1 on the main form. The above issue was posted by more than one person on the jedi.vcl newsgroup. | ||||
| Tags | No tags attached. | ||||
|
2004-03-04 16:36
|
JVtesting.zip (362,975 bytes) |
|
|
The properties for the second form are cleared by this code in the create event of the main form: procedure TForm1.FormCreate(Sender: TObject); begin if FormSub = nil then FormSub := TFormSub.Create(self); // This should cause the problem // I check some settings here... // FormSub.JvAppIniFileStorage1.Reload; << does not help FormSub.free; //<< resets the properties. FormSub := nil; end; |
|
2004-03-04 17:23
|
JVtestingChanged.zip (368,969 bytes) |
|
|
I have updated your example. There is no problem for me now. Some hints: - Use one global JvAppStorageComponent - The TForm1.FormCreate is useless (for me) - It works now with Registry and Ini-File |
|
|
Please check my sample and give a feedback if the bug can be closed. Greetings and thanks. Jens |
|
|
First I want to thank Craig for following up on my bug post while I was sleeping and then at work all day... I owe you one! Jens, I may have had two problems with my implementation. I found I had a stray JvAppIniFileStorage on my main form in addition to the instances I had on the two separate sub forms. Also, I hadn't set the AppStoragePath for either of the JvFormStorage components on the subforms. Once I removed the JvAppIniFileStorage on my main form and set the AppStoragePath, everything work correctly for me. I dynamically create one or the other subform (only one will exist at any one time), so I guess I won't have the same problem that Craig exhibited in his example. Specifically, the usage is that one instance of JvAppIniFileStorage should exist at any one time. Somehow, that requirement is less than desirable, but I can't think of a elegant solution, so I can certainly live with that restriction! Thanks to both of you for helping me through my problem. If Craig is okay with the solution, you can close the case as far as I'm concerned. -Charles |
|
|
As i said before, i think the best solution is to work with one central JvAppStorage. The point is that the AppIniStorage cashes the contents. So if you work with differnt Storages, there can be a problem. Greetings Jens |
|
|
Jens, I agree. A central storage component is practically the only way that will work, regardless of which back end is used. Personally, if you have many forms, I would put the storage component on a data module that will be used by all forms. This is definately not a bug, just a feature (possibly annoying for some, but, well, though <g>) |
|
|
Jens, In your example zip file the sub form still loses its stored property values if you do not .show or .showmodal the sub form. Use your example to add text to the fields in the sub form then exit the app. Next, run the app's main form only, then exit and you will see that the ini and the sub form has reset its stored values back to the inherited vaules. Even a data module as marcelb reccomemds will still have the stored values lost. (FIY I did delete the unused registry component, JvAppRegistryStorage1 before testing the ini functionality) -Craig edited on: 03-05-04 06:19 |
|
|
Okay, I though about it overnight... If you intend for TJvAppIniFileStorage to be an "application" store, then why not move the declaration of FIniFile from the class to the package implementation so it is treated as a "class" variable? Then add a usage counter to keep track of when you really need to deallocate it... implementation uses JvTypes, JvResources; var IniFile: TMemIniFile; UsageCount: integer = 0; constructor TJvCustomAppIniStorage.Create(AOwner: TComponent); begin inherited Create(AOwner); IniFile := TMemIniFile.Create(Name); inc(UsageCount); end; destructor TJvCustomAppIniStorage.Destroy; begin inherited Destroy; // Has to be done AFTER inherited, see comment in // TJvCustomAppMemoryFileStorage dec(UsageCount); if UsageCount = 0 then IniFile.Free; end; This way it work philosophically like you guys intended and it will not suffer from errant use by the uninitiated like me! This way each placement of a TJvAppIniFileStorage component becomes a local reference to the "application" store. -Charles Just my $.2 |
|
|
But this will not help in all ways. It's a little bit more complex. Some issues: 1. Multi Threading 2. The logic must be more complex because different AppStorageComponents can use different files. 3. Don't know, maybe there are better solutions. Any comments Greetings Jens |
|
|
Craig: it reverts to the defaults because of the way FormStorage works: values are read from the store when the form is shown and written when it is destroyed. I think the Loaded method of the FormStorage component should resotre the values/placement/sizes instead of (or in addition to) the FormShow event (and in general the way it hijacks the events of the form is bad practice that should be erradicated anyway) Charles: Jens is right; too much trouble and generally not worth to go that route. |
|
|
Hi Craig, the problem is raised by your project definition. Both forms are in the project initialisation. Removing the subform of the project intialisation solves the problem. Without looking into it seems to be, that the FormStorage Component loads the values when the form is shown the first time, and stores it when deleting. I must look into it. Greetings Jens |
|
2004-03-06 10:17
|
JVtesting.zip (363,611 bytes) |
|
|
"Removing the subform of the project intialisation solves the problem" did not solve the issue so, here is my work around: (Zip file uploaded) procedure TForm1.Button1Click(Sender: TObject); begin if FormSub = nil then FormSub := TFormSub.Create(self); FormSub.showmodal; FormSub.free; FormSub := nil; JvAppIniFileStorage1.Reload; << after the sub form writes to the ini file end; procedure TForm1.FormCreate(Sender: TObject); begin if FormSub = nil then FormSub := TFormSub.Create(self); FormSub.Visible := false; FormSub.Show; << short flicker until the .free is called // I use the stored values here... FormSub.free; FormSub := nil; JvAppIniFileStorage1.Reload; << after the sub form wrote the ini file. end; It is an extra step but it works great (except for the flicker). Thank you all for helping me get through this. I'm ok with closing this issue now. - Craig edited on: 03-06-04 10:23 edited on: 03-07-04 08:00 |
|
2004-03-06 11:03
|
JVtestingworking.zip (369,514 bytes) |
|
|
Craig, look at my example. I can't see any further problems. Please try it again. Jens |
|
|
Problem solved, see the next post for use of '.RestoreFormPlacement'. I'm editing out my comments below do to the better solution found. Jens, Your last posted zip file will not give me access the the sub form's values so I can use them as application settings like data path info. . . . -Craig edited on: 03-07-04 09:33 |
|
|
I tried this. procedure TForm1.FormCreate(Sender: TObject); begin if FormSub = nil then FormSub := TFormSub.Create(self); FormSub.JvFormStorage1.RestoreFormPlacement; << working fine // FormSub.Visible := false; << no longer needed so no flicker // FormSub.Show; // I use the stored values here... FormSub.free; FormSub := nil; JvAppIniFileStorage1.Reload; end; -Craig edited on: 03-07-04 09:29 |
|
|
Help! I just updated JVCL. Now none of the TJvCustomAppIniStorage stuff is working at all. I noticed that JvAppStorage.pas was updated on the 6th. Did this break using an ini file? TJvAppRegistryStorage still works. I went back to the prior one 1.18 (or 1.19) of JvAppStorage.pas and ini works again. -Craig edited on: 03-07-04 17:21 |
|
|
You can see what's changed here: http://cvs.jvcl.sourceforge.net/viewcvs.py/jvcl/dev/JVCL3/run/JvAppStorage.pas |
|
|
Craig, it appears the change Jens has done introduced a new bug. AFAICT, if the Location property is not set (either because of loading from the DFM or through code), the storage is deemed uninitialized, resulting in no file being used. Luckily for us, Jens has coded in such a bad way (<g>) we can just explicitly set Location to it's current value (i.e. using <Store>.Location := <Store>.Location) and it all works. I don't quite understand why he did that though. To me, it seems totally obsolete. |
|
|
Hi Everybody. Sorry for that. I have tested everything, but not the case that the Location was flExeFile. I didn't think that my changes were so bad (<g>). They made sense (for me) but they were not perfect. What i wanted to prevent was that the reload procedure was called before all properties were set. Now i changed it via an overloaded "loaded" procedure. It seems to work for all cases, hope so. I found the problem testing the new flTemp type. If this property is set, the component tries first to load the Ini-File in the exe-directory and after that the component in the temp-directory. So reload was called twice. I didn't want that. Please give it a new try. Greetings Jens |
|
|
Jens, How could Reload be called before the component is loaded? FormStorage doesn't do anything unless the form is shown and I'm pretty sure that when the form can be shown it is done loading that form and any form/data module/component it depends on. Unless you are abusing the FormCreate event (although I think that one is also called after it is loaded). The "bad code" was referring to the fact that the Initialized (or whatever it was called) was set, regardless if the value of Location actually changed. Usually that's not a good thing, although there are situations where it can be very helpful. Anyway, I haven't checked your changes, but I'm sure you got it covered now ;-) |
|
|
Hi Marcel, the point of reload calling is the following: In the procedure Loaded the properties "Location" and "Filename" where initialized. Both call a "Set"-Procedure and this procedure calls the reload procedure. The initiating problem was: I had changed the location to flTemp. The ini-file doesn't exist in the temp directory, it exists in the exe-directory. While the "Loaded" procedure the filename-property is set first. Then the file is loaded. Then the Location-property is set. Now the reload is executed again. But now the file does not exists (because Location now =flTemp). So the file is not loaded and the contents of the old file still be loaded And there we have an other bug, i've not fixed until now (coming to me this night). The reload checks if the file exists and then loads the file. If the file does not exist, nothing happens. That had to be changed. In the case that the file does not exists, the old contents had to be changed. I hope now it's clear. Greetings Jens |
|
|
Will I still have to do this with the new changes? procedure TForm1.FormCreate(Sender: TObject); begin if FormSub = nil then FormSub := TFormSub.Create(self); FormSub.JvFormStorage1.RestoreFormPlacement; << reads sub form's settings // I use the stored values here for path and other application settings. FormSub.free; << writes sub form settings FormSub := nil; JvAppIniFileStorage1.Reload; << fills the buffer with both the main form and sub forms settings. end; Thank You again, -Craig |
|
|
Hi Craig, i think so yes. The changes i had done were only for the problem of changing the Location-Property at designtime. They didn't change anything else. Greetings Jens |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2004-03-04 05:51 | anonymous | New Issue | |
| 2004-03-04 16:36 | craigism | File Added: JVtesting.zip | |
| 2004-03-04 16:38 | craigism | Note Added: 0003208 | |
| 2004-03-04 17:20 | jfudickar | Status | new => assigned |
| 2004-03-04 17:20 | jfudickar | Assigned To | => jfudickar |
| 2004-03-04 17:23 | jfudickar | File Added: JVtestingChanged.zip | |
| 2004-03-04 17:23 | jfudickar | Note Added: 0003210 | |
| 2004-03-04 17:25 | jfudickar | Note Added: 0003211 | |
| 2004-03-04 17:25 | jfudickar | Status | assigned => feedback |
| 2004-03-04 17:25 | jfudickar | Resolution | open => no change required |
| 2004-03-04 18:56 | anonymous | Note Added: 0003212 | |
| 2004-03-04 23:56 | jfudickar | Note Added: 0003215 | |
| 2004-03-05 01:13 | marcelb | Note Added: 0003216 | |
| 2004-03-05 05:04 | craigism | Note Added: 0003220 | |
| 2004-03-05 06:19 | craigism | Note Edited: 0003220 | |
| 2004-03-05 06:29 | cginzel | Note Added: 0003224 | |
| 2004-03-06 08:22 | jfudickar | Note Added: 0003243 | |
| 2004-03-06 09:07 | marcelb | Note Added: 0003244 | |
| 2004-03-06 09:21 | jfudickar | Note Added: 0003245 | |
| 2004-03-06 10:17 | anonymous | File Added: JVtesting.zip | |
| 2004-03-06 10:23 | craigism | Note Added: 0003246 | |
| 2004-03-06 10:23 | craigism | Note Edited: 0003246 | |
| 2004-03-06 11:03 | jfudickar | File Added: JVtestingworking.zip | |
| 2004-03-06 11:05 | jfudickar | Note Added: 0003248 | |
| 2004-03-06 19:12 | craigism | Note Added: 0003250 | |
| 2004-03-07 07:58 | craigism | Note Edited: 0003250 | |
| 2004-03-07 08:00 | craigism | Note Edited: 0003246 | |
| 2004-03-07 08:55 | craigism | Note Added: 0003251 | |
| 2004-03-07 09:29 | craigism | Note Edited: 0003251 | |
| 2004-03-07 09:33 | craigism | Note Edited: 0003250 | |
| 2004-03-07 16:58 | craigism | Note Added: 0003257 | |
| 2004-03-07 17:01 | craigism | Note Edited: 0003257 | |
| 2004-03-07 17:21 | craigism | Note Edited: 0003257 | |
| 2004-03-08 01:25 |
|
Note Added: 0003258 | |
| 2004-03-08 03:21 | marcelb | Note Added: 0003261 | |
| 2004-03-09 14:55 | jfudickar | Note Added: 0003290 | |
| 2004-03-10 07:00 | marcelb | Note Added: 0003301 | |
| 2004-03-10 07:14 | jfudickar | Note Added: 0003302 | |
| 2004-03-10 09:10 | craigism | Note Added: 0003303 | |
| 2004-03-10 23:48 | jfudickar | Note Added: 0003307 | |
| 2004-03-28 06:27 | jfudickar | Status | feedback => closed |