View Issue Details

IDProjectCategoryView StatusLast Update
0001915JEDI VCL00 JVCL Componentspublic2004-08-01 01:45
ReporterSalvatore BessoAssigned Tojfudickar 
Status resolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0001915: TJvAppRegistryStorage ignores BooleanAsString = False and TypedIntegerAsString = False
DescriptionAs per summary, even setting those two flags to False the values are stored always as strings. Maybe the same happens for FloatAsString = False, but I have not tested it and for other types of storage (Ini, Xml, etc.)
TagsNo tags attached.



2004-07-01 15:31

developer   ~0004661

It's not a problem of the appstorage, it's more a problem of the FormStorage component.
I have fixed it for the StoredValues, but not for the StoredProps. First was nearly easy, second is a little bit more complex. So i think i wouldn't change it in the next time.

Salvatore Besso

2004-07-02 01:59

reporter   ~0004664

hello Jens,

thank you for your fix. It would be great anyway to fix also StoredProps. I explain better: Suppose that I have an Integer value that I read on application start with StoredValues. Then this value is modified in a "Preferences" dialog and the edit line where it is modified is also included in StoredProps. In this case I will have, at the end, two copies of the same value, one Integer and one string (or maybe the Integer will be overwritten and transformed into string, since they have the same name, supplied in the OnTranslate event).


2004-07-02 02:13

viewer   ~0004665

Sorry i didn't understand your description. Have you a more clear example.

It's not possible to have the same value twice.


2004-07-02 02:18

developer   ~0004666

It was me - Jens :-)

Salvatore Besso

2004-07-02 04:01

reporter   ~0004669

Well, BooleanAsString = False is no longer ignored, but now we fall somehow into bug 0001916. I explain better. Since, if type at design time is set as Boolean, and it's not possible in this case to leave the value blank as I do with strings (default is set to False), the restored value is wrong (False) instead of True (real value in the registry).


2004-07-02 04:06

developer   ~0004670

what should i do? Boolean is only true or false, so i can't give you an empty value :-)

And the stored value have no default values. So if the value is not convertable when loading my internal default true is used. Nothing else is possible, i think


Salvatore Besso

2004-07-02 04:14

reporter   ~0004671

JENS> Sorry i didn't understand your description. Have you a more clear example

JENS> I have fixed it for the StoredValues, but not for the StoredProps

what I mean is that it would be better to fix it also for StoredProps. This is the scenario:

At program start I read an Integer value, say of name "MyIntValue" from the registry and into the Integer variable MyIntValue:

MyIntValue := MyStorage.StoredValue['MyIntValue'];

Then, in my wonderful :-) Preferences dialog I offer the user the possibility to change this Integer value so I use for this a TEdit associated with a TUpDown component. Then, in the TFormStorage of this form (different than that used at startup) I add the property TUpDown.Position that is translated into MyIntValue in the common TRegistryStore. Without the fix applied to StoredProps, I suppose that MyIntValue will become a string again. Of course the same is valid for Boolean and Float values. IMHO, Not fixing StoredProps makes the fix to StoredValues somehow useless. I hope that it's more clear now.

Salvatore Besso

2004-07-02 04:21

reporter   ~0004672

> what should i do? Boolean is only true or false, so i can't
> give you an empty value :-)

ok, you are perfectly right, but maybe I didn't explain myself correctly.

In the registry, the value I want to restore is True (represented as DWORD = 1) but the value restored by the component is False. What I mean is that in presence of a default value, the restored value is wrong (the default is always returned instead of the real value). Further, the default value should be returned only if the restore from registry fails (in case of errors), isn't it?


2004-07-02 05:04

developer   ~0004674

Yes!!! I had too look for it :-)

2004-07-02 07:20 (9,795 bytes)

Salvatore Besso

2004-07-02 07:26

reporter   ~0004675

hello Jens,

ok, I have made a test case (see above) that is a complete "summa" of all issues posted by me on these components. With this test case you will be able to verify issues 1915 (this) and 1916, plus another thing about OnTranslatePropertyName that I have discovered only now.

Please give a look at the readme.txt file before trying. You have to load a .reg file before, but don't worry, it's harmless :-) It creates only the test registry tree (needed before trying).

Salvatore Besso

2004-07-02 11:15

reporter   ~0004677

hello Jens,

a bit of light has been seen :-) I try to explain myself the best that I can always referring to the test case.

String values:

Now they are retrieved correctly. It was my fault because I forgot to restore all values before accessing them. In DMMainDataModule, in the RetrieveAllValues method, I have inserted these two lines at the beginning to fix almost this part of the problem:



Integer value:

Now it is retrieved correctly only if you don't open Options form, because Options form, as soon as it is opened, accesses the values and transform all Integer and Boolean values into string due to the missing fix to StoredProps (I mean the fix that you have already made to StoredValues regarding TypedIntegerAsString = False, BooleanAsString = False and FloatAsString = False).

This happens because the properties trasformed into strings return a wrong RegKind [1] = REG_SZ in JclRegistry.InternalRegReadA, where parameter RegKinds is [4] = REG_DWORD. At the end the big problem is that it's necessary to make the fix to StoredProps to avoid the transformation of DWORD into strings.


Boolean value:

It is still not retrieved correctly. There was another fault made by me, because setting BooleanAsString = False it's also necessary to specify:

BooleanStringFalseValues = '0'
BooleanStringTrueValues = '1'

overriding default literal values to match the two possible REG_DWORD values indicating a Boolean. But even setting those two properties the final value is still wrong. Let us see.

The real value is retrieved from the registry as a string and then converted into a boolean value. Entering into JclRegistry.InternalRegReadA the parameter RegKinds is [1..2], indicating REG_SZ and REG_EXPAND_SZ types (we are reading a boolean as string). But RegQueryValueExA at line 420 returns a RegKind of [4] because the real value is REG_DWORD, and this is ok, but the following test:

Result := Result and (Size <= DataSize) and (RegKind in RegKinds);

of course fails because RegKind IS NOT IN RegKinds. Ultimately, and IMHO, the offending line could be located in unit JvAppStorage, method TJvCustomAppStorage.ReadBooleanInt at line 1374:

1373: else
1374: Value := DecryptPropertyValue(DoReadString(Path,

because using DoReadString here, then JclRegistry.InternalRegReadA will receive a RegKinds parameter of [1..2] indicating REG_SZ and REG_EXPAND_SZ types (of course, we are about to read a string).

But due to this wrong RegKinds parameter the comparison

...(RegKind in RegKinds)

will always fail because the RegKind effectively queried from the registry is REG_DWORD [4].

Maybe the solution is to use IntToStr(DoReadInteger()) instead of DoReadString, so the RegKinds parameter sent to JclRegistry.InternalRegReadA will be correct (REG_DWORD [4]), but I'm not sure, it's only a guess.

Salvatore Besso

2004-07-08 04:34

reporter   ~0004714

hello Jens,

any news after my last bugnote?



2004-07-08 14:09

developer   ~0004718

Sorry no. The week was very busy. Hope to look for it on monday.


2004-07-13 16:08

developer   ~0004760

Hi Salvatore,

not finished, but a pieace nearer i hope.

Please look at the next version. FormStorage now always uses the typed procedures.

Your sample works for this problem.

Waiting for your next comments.


2004-07-14 03:30 (10,102 bytes)

Salvatore Besso

2004-07-14 03:34

reporter   ~0004761

hello Jens,

> not finished, but a piece nearer i hope

yes, things are now much better than before, but another new problem (not seen before) popped out with the latest JCL/JVCL snapshot. Please see comments on updated test case (just uploaded), especially those on Form2, related to property storage. It seems that now properties are not retrieved at all and wrong values are written back to the registry.


Salvatore Besso

2004-07-14 03:39

reporter   ~0004762

again me :-)

I'm not really sure, but what is the purpose of the FormVersion value written in every key?



2004-07-14 04:30

viewer   ~0004763

I didn't know the exact use of the formversion, because it's historic :-)

As far as i can see, you can use it to prevent loading of property-values by incrementing the formversion value of the component.

Increasing this value, all keys smaller then the value will be ignored.



2004-07-14 14:14

developer   ~0004765

Hi Salvatore,

please try again, and only do the following change:
procedure TForm2.OptionsRegistryStorageTranslatePropertyName(
  Sender: TJvCustomAppStorage; Instance: TPersistent; var Name: String;
  const Reading: Boolean);

    if Name = 'DevNameEdit_Text' then
      Name := 'Developer_Name'
    else if Name = 'MyNameEdit_Text' then
      Name := 'My_Name'
    else if Name = 'BoolCheckBox_Checked' then
      Name := 'This_Is_Boolean'
    else if Name = 'IntUpDown_Position' then
      Name := 'This_Is_Integer'

The Translationdirection is allways the same, independent from the parameter reading.

With this for me everything seems to be ok.


Salvatore Besso

2004-07-15 07:17

reporter   ~0004766

hello Jens,

ok, now it seems that all is ok. I have made the modification that you suggested in your last bugnote. The values in Form2 are now retrieved and saved correctly. But at this point, what is the use of the Reading parameter in the OnTranslateProperty event? Behaviour differs from what is said in the help file (dtx file).

I suppose that these modifications on the ancestor affect all the descendant components not used in the test case, such as IniStorage, XmlStorage, etc.

Thank you and best regards


2004-08-01 01:45

developer   ~0004867

JvAppStorage.dtx changed

Issue History

Date Modified Username Field Change
2004-07-01 12:06 Salvatore Besso New Issue
2004-07-01 15:31 jfudickar Note Added: 0004661
2004-07-02 01:59 Salvatore Besso Note Added: 0004664
2004-07-02 02:13 anonymous Note Added: 0004665
2004-07-02 02:18 jfudickar Note Added: 0004666
2004-07-02 04:01 Salvatore Besso Note Added: 0004669
2004-07-02 04:06 jfudickar Note Added: 0004670
2004-07-02 04:14 Salvatore Besso Note Added: 0004671
2004-07-02 04:21 Salvatore Besso Note Added: 0004672
2004-07-02 05:04 jfudickar Note Added: 0004674
2004-07-02 07:20 Salvatore Besso File Added:
2004-07-02 07:26 Salvatore Besso Note Added: 0004675
2004-07-02 11:15 Salvatore Besso Note Added: 0004677
2004-07-08 04:34 Salvatore Besso Note Added: 0004714
2004-07-08 14:09 jfudickar Note Added: 0004718
2004-07-13 16:08 jfudickar Note Added: 0004760
2004-07-14 03:30 Salvatore Besso File Added:
2004-07-14 03:34 Salvatore Besso Note Added: 0004761
2004-07-14 03:39 Salvatore Besso Note Added: 0004762
2004-07-14 04:30 anonymous Note Added: 0004763
2004-07-14 14:14 jfudickar Note Added: 0004765
2004-07-15 02:00 jfudickar Status new => assigned
2004-07-15 02:00 jfudickar Assigned To => jfudickar
2004-07-15 07:17 Salvatore Besso Note Added: 0004766
2004-08-01 01:45 jfudickar Status assigned => resolved
2004-08-01 01:45 jfudickar Resolution open => fixed
2004-08-01 01:45 jfudickar Note Added: 0004867