Quick.Config.Registry.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. { ***************************************************************************
  2. Copyright (c) 2015-2019 Kike Pérez
  3. Unit : Quick.Config.Registry
  4. Description : Save config to Windows Registry
  5. Author : Kike Pérez
  6. Version : 1.5
  7. Created : 21/10/2017
  8. Modified : 25/01/2019
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.Config.Registry;
  22. {$i QuickLib.inc}
  23. interface
  24. uses
  25. Classes,
  26. Windows,
  27. SysUtils,
  28. Registry,
  29. Quick.Json.Serializer,
  30. {$IFDEF DELPHIRX102_UP}
  31. System.Json,
  32. System.JSON.Types,
  33. {$ELSE}
  34. {$IFDEF FPC}
  35. fpjson,
  36. //jsonparser,
  37. //fpjsonrtti,
  38. Quick.Json.fpc.Compatibility,
  39. {$ELSE}
  40. Rest.Json.Types,
  41. System.JSON,
  42. Rest.Json,
  43. {$ENDIF}
  44. {$ENDIF}
  45. Quick.Commons,
  46. Quick.Config.Base;
  47. type
  48. TAppConfigRegistryProvider = class(TAppConfigProvider)
  49. private
  50. fRootKey : HKEY;
  51. fMainKey : string;
  52. fRegConfig : TRegistry;
  53. function JsonToRegistry(const StrJson : string) : Boolean;
  54. function RegistryToJson(out StrJson : string) : Boolean;
  55. class function IsSimpleJsonValue(v: TJSONValue): Boolean;
  56. function IsRegKeyObject(const cCurrentKey : string = '') : Boolean;
  57. function IsRegKeyArray(const cCurrentKey : string = '') : Boolean;
  58. function ProcessPairRead(const cCurrentKey, cRegKey : string; aIndex : Integer) : TJSONValue;
  59. function ProcessElementRead(const cCurrentKey, cRegKey : string; aIndex : Integer) : TJSONValue;
  60. procedure ProcessPairWrite(const cCurrentKey: string; obj: TJSONObject; aIndex: integer);
  61. procedure ProcessElementWrite(const cCurrentKey: string; arr: TJSONArray; aIndex, aMax : integer);
  62. function AddRegKey(const cCurrentKey, NewKey : string) : Boolean;
  63. function ReadRegValue(const cCurrentKey, cName : string) : TJSONValue;
  64. procedure AddRegValue(const cCurrentKey, cName : string; cValue : TJSONValue);
  65. protected
  66. procedure Load(cConfig : TAppConfig); override;
  67. procedure Save(cConfig : TAppConfig); override;
  68. public
  69. constructor Create(aHRoot : HKEY = HKEY_CURRENT_USER; const aMainKey : string = ''); virtual;
  70. destructor Destroy; override;
  71. property HRoot : HKEY read fRootKey write fRootKey;
  72. property MainKey : string read fMainKey write fMainKey;
  73. end;
  74. EAppConfig = Exception;
  75. TAppConfigRegistry = class(TAppConfig)
  76. private
  77. function GetProvider : TAppConfigRegistryProvider;
  78. public
  79. constructor Create(aHRoot : HKEY = HKEY_CURRENT_USER; const aMainKey : string = '');
  80. destructor Destroy; override;
  81. property Provider : TAppConfigRegistryProvider read GetProvider;
  82. end;
  83. {Usage: create a descend class from TAppConfigRegistry and add published properties to be loaded/saved
  84. TMyConfig = class(TAppConfigRegistry)
  85. private
  86. fName : string;
  87. fSurname : string;
  88. fStatus : Integer;
  89. published
  90. property Name : string read fName write fName;
  91. property SurName : string read fSurname write fSurname;
  92. property Status : Integer read fStatus write fStatus;
  93. end;
  94. MyConfig := TMyConfig.Create;
  95. MyConfig.Provider.MainKey := 'MyAppName';
  96. MyConfig.Name := 'John';
  97. MyConfig.Save;
  98. }
  99. implementation
  100. { TAppConfigRegistryProvider }
  101. constructor TAppConfigRegistryProvider.Create(aHRoot : HKEY = HKEY_CURRENT_USER; const aMainKey : string = '');
  102. begin
  103. inherited Create;
  104. if aHRoot <> HKEY_CURRENT_USER then fRootKey := aHRoot
  105. else fRootKey := HKEY_CURRENT_USER;
  106. if aMainKey <> '' then fMainKey := aMainKey
  107. else fMainKey := ExtractFileNameWithoutExt(ParamStr(0));
  108. fRegConfig := TRegistry.Create(KEY_READ or KEY_WRITE);
  109. end;
  110. destructor TAppConfigRegistryProvider.Destroy;
  111. begin
  112. if Assigned(fRegConfig) then fRegConfig.Free;
  113. inherited;
  114. end;
  115. procedure TAppConfigRegistryProvider.Load(cConfig : TAppConfig);
  116. var
  117. Serializer: TJsonSerializer;
  118. json : string;
  119. begin
  120. fRegConfig.Access := KEY_READ;
  121. fRegConfig.RootKey := fRootKey;
  122. if not fRegConfig.KeyExists('\Software\' + fMainKey) then
  123. begin
  124. if not CreateIfNotExists then raise EAppConfig.Create('Not exists MainKey in registry!')
  125. else TAppConfigRegistry(cConfig).DefaultValues;
  126. Save(cConfig);
  127. end;
  128. RegistryToJson(json);
  129. serializer := TJsonSerializer.Create(slPublishedProperty);
  130. try
  131. serializer.JsonToObject(cConfig,json);
  132. finally
  133. serializer.Free;
  134. end;
  135. end;
  136. procedure TAppConfigRegistryProvider.Save(cConfig : TAppConfig);
  137. begin
  138. JsonToRegistry(cConfig.ToJSON);
  139. end;
  140. function TAppConfigRegistryProvider.JsonToRegistry(const StrJson : string) : Boolean;
  141. var
  142. jValue : TJSONValue;
  143. aCount : Integer;
  144. i : Integer;
  145. aCurrentKey : string;
  146. begin
  147. Result := False;
  148. if fMainKey = '' then raise EAppConfig.Create('MainKey not defined!');
  149. fRegConfig.Access := KEY_READ or KEY_WRITE;
  150. fRegConfig.RootKey := fRootKey;
  151. aCurrentKey := '\Software\' + fMainKey;
  152. if fRegConfig.KeyExists(aCurrentKey) then
  153. begin
  154. try
  155. if fRegConfig.KeyExists(aCurrentKey + '_bak') then fRegConfig.DeleteKey(aCurrentKey + '_bak');
  156. fRegConfig.MoveKey(aCurrentKey,aCurrentKey + '_bak',True);
  157. except
  158. raise EAppConfig.Create('Can''t write Config Registry');
  159. end;
  160. end;
  161. try
  162. if not AddRegKey('\Software',fMainKey) then
  163. begin
  164. raise EAppConfig.Create('Can''t create key');
  165. end;
  166. {$IFNDEF FPC}
  167. jValue := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson),0) as TJSONValue;
  168. {$ELSE}
  169. jValue := TJSONObject.ParseJSONValue(StrJson) as TJSONValue;
  170. {$ENDIF}
  171. try
  172. if IsSimpleJsonValue(jValue) then
  173. begin
  174. {$IFNDEF FPC}
  175. AddRegValue(aCurrentKey,TJSONPair(jValue).JsonString.ToString.DeQuotedString('"'),TJSONPair(jValue).JsonValue);
  176. {$ELSE}
  177. AddRegValue(aCurrentKey,TJSONPair(jValue).JsonString.DeQuotedString('"'),TJSONPair(jValue).JsonValue);
  178. {$ENDIF}
  179. end
  180. {$IFNDEF FPC}
  181. else if jValue is TJSONObject then
  182. {$ELSE}
  183. else if jvalue.JSONType = jtObject then
  184. {$ENDIF}
  185. begin
  186. aCount := TJSONObject(jValue).Count;
  187. for i := 0 to aCount - 1 do
  188. ProcessPairWrite(aCurrentKey,TJSONObject(jValue),i);
  189. end
  190. {$IFNDEF FPC}
  191. else if jValue is TJSONArray then
  192. {$ELSE}
  193. else if jValue.JSONType = jtArray then
  194. {$ENDIF}
  195. begin
  196. aCount := TJSONArray(jValue).Count;
  197. for i := 0 to aCount - 1 do
  198. ProcessElementWrite(aCurrentKey,TJSONArray(jValue),i,aCount);
  199. end
  200. else raise EAppConfig.Create('Error Saving config to Registry');
  201. Result := True;
  202. finally
  203. jValue.Free;
  204. end;
  205. if fRegConfig.KeyExists(aCurrentKey + '_bak') then fRegConfig.DeleteKey(aCurrentKey + '_bak');
  206. except
  207. on E : Exception do
  208. begin
  209. fRegConfig.DeleteKey(aCurrentKey);
  210. fRegConfig.MoveKey(aCurrentKey+'_bak',aCurrentKey,True);
  211. raise EAppConfig.Create(e.message);
  212. end;
  213. end;
  214. end;
  215. function TAppConfigRegistryProvider.RegistryToJson(out StrJson : string) : Boolean;
  216. var
  217. jValue : TJSONValue;
  218. jPair : TJSONPair;
  219. jArray : TJSONArray;
  220. a, b : string;
  221. aCount : Integer;
  222. i : Integer;
  223. aName : string;
  224. aValue : TJSONValue;
  225. aCurrentKey : string;
  226. newObj : TJSONObject;
  227. RegKeyList : TStringList;
  228. RegValueList : TStringList;
  229. RegKey : string;
  230. RegValue : string;
  231. RegKeyInfo : TRegKeyInfo;
  232. begin
  233. Result := False;
  234. //check if exists root key
  235. fRegConfig.Access := KEY_READ;
  236. fRegConfig.RootKey := fRootKey;
  237. if fRegConfig.KeyExists('\Software\' + fMainKey) then
  238. begin
  239. fRegConfig.OpenKeyReadOnly('\Software\' + fMainKey);
  240. aCurrentKey := '\Software\' + fMainKey;
  241. end
  242. else raise EAppConfig.Create('Can''t read key');
  243. newObj := TJSONObject.Create;
  244. try
  245. //read root values
  246. RegValueList := TStringList.Create;
  247. try
  248. fRegConfig.GetValueNames(RegValueList);
  249. for RegValue in RegValueList do
  250. begin
  251. newObj.AddPair(RegValue,ReadRegValue(aCurrentKey,RegValue));
  252. end;
  253. finally
  254. RegValueList.Free;
  255. end;
  256. //read root keys
  257. RegKeyList := TStringList.Create;
  258. try
  259. fRegConfig.GetKeyNames(RegKeyList);
  260. for RegKey in RegKeyList do
  261. begin
  262. fRegConfig.OpenKeyReadOnly(aCurrentKey + '\' + RegKey);
  263. if IsRegKeyObject then
  264. begin
  265. jValue := ProcessPairRead(aCurrentKey + '\' + RegKey,Regkey,i);
  266. newObj.AddPair(RegKey,jValue);
  267. end
  268. else if IsRegKeyArray then
  269. begin
  270. jValue := ProcessElementRead(aCurrentKey + '\' + RegKey,Regkey,i);
  271. newObj.AddPair(RegKey,jValue);
  272. end
  273. else raise EAppConfig.Create('Unknow value reading Config Registry');
  274. end;
  275. finally
  276. RegKeyList.Free;
  277. end;
  278. StrJson := newObj.ToJSON;
  279. finally
  280. newObj.Free;
  281. end;
  282. end;
  283. function TAppConfigRegistryProvider.IsRegKeyObject(const cCurrentKey : string = '') : Boolean;
  284. begin
  285. Result := not IsRegKeyArray(cCurrentKey);
  286. end;
  287. function TAppConfigRegistryProvider.IsRegKeyArray(const cCurrentKey : string = '') : Boolean;
  288. var
  289. RegValue : string;
  290. RegValueList : TStrings;
  291. RegKey : string;
  292. RegKeyList : TStrings;
  293. n : Integer;
  294. begin
  295. Result := False;
  296. if cCurrentKey <> '' then fRegConfig.OpenKeyReadOnly(cCurrentKey);
  297. //check if exists RegKey numeric (indicates is a Array)
  298. RegKeyList := TStringList.Create;
  299. try
  300. {$IFNDEF FPC}
  301. fRegConfig.GetKeyNames(RegKeyList);
  302. {$ELSE}
  303. try
  304. fRegConfig.GetKeyNames(RegKeyList);
  305. except
  306. end;
  307. {$ENDIF}
  308. for RegKey in RegKeyList do
  309. if TryStrToInt(RegKey,n) then
  310. begin
  311. Result := True;
  312. Break;
  313. end;
  314. finally
  315. RegKeyList.Free;
  316. end;
  317. //check if exists RegValue numeric (indicates is a Array)
  318. RegValueList := TStringList.Create;
  319. try
  320. {$IFNDEF FPC}
  321. fRegConfig.GetValueNames(RegValueList);
  322. {$ELSE}
  323. try
  324. fRegConfig.GetValueNames(RegValueList);
  325. except
  326. end;
  327. {$ENDIF}
  328. for RegValue in RegValueList do
  329. if TryStrToInt(RegValue,n) then
  330. begin
  331. Result := True;
  332. Break;
  333. end;
  334. finally
  335. RegValueList.Free;
  336. end;
  337. end;
  338. class function TAppConfigRegistryProvider.IsSimpleJsonValue(v: TJSONValue): Boolean;
  339. begin
  340. Result := (v is {$IFDEF FPC}fpjson.TJsonIntegerNumber{$ELSE}TJSONNumber{$ENDIF})
  341. or (v is {$IFDEF FPC}fpjson.{$ENDIF}TJSONString)
  342. {$IFNDEF FPC}
  343. or (v is TJSONTrue)
  344. or (v is TJSONFalse)
  345. {$ELSE}
  346. or (v is {$IFDEF FPC}fpjson.TJSONBoolean{$ELSE}TJsonBool{$ENDIF})
  347. {$ENDIF}
  348. or (v is {$IFDEF FPC}fpjson.{$ENDIF}TJSONNull);
  349. end;
  350. function TAppConfigRegistryProvider.ReadRegValue(const cCurrentKey, cName : string) : TJSONValue;
  351. var
  352. aValue : string;
  353. RegInfo : TRegDataInfo;
  354. begin
  355. if fRegConfig.OpenKeyReadOnly(cCurrentKey) then
  356. begin
  357. if fRegConfig.GetDataInfo(cName,RegInfo) then
  358. case RegInfo.RegData of
  359. rdInteger : Result := TJSONNumber.Create(fRegConfig.ReadInteger(cName));
  360. rdString :
  361. begin
  362. aValue := fRegConfig.ReadString(cName);
  363. if aValue.ToLower = 'true' then Result := TJSONBool.Create(True)
  364. else if aValue.ToLower = 'false' then Result := TJSONBool.Create(False)
  365. else Result := TJSONString.Create(aValue);
  366. end;
  367. else Result := TJSONNull.Create;
  368. end;
  369. end;
  370. end;
  371. function TAppConfigRegistryProvider.AddRegKey(const cCurrentKey, NewKey : string) : Boolean;
  372. begin
  373. Result := fRegConfig.CreateKey(Format('%s\%s',[cCurrentKey,NewKey]));
  374. end;
  375. procedure TAppConfigRegistryProvider.AddRegValue(const cCurrentKey, cName : string; cValue : TJSONValue);
  376. var
  377. aName : string;
  378. aValue : string;
  379. begin
  380. aName := cName.DeQuotedString('"');
  381. {$IFNDEF FPC}
  382. aValue := cValue.ToString.DeQuotedString('"');
  383. {$ELSE}
  384. aValue := cValue.AsString;// .DeQuotedString('"');
  385. {$ENDIF}
  386. fRegConfig.OpenKey(cCurrentKey,True);
  387. if cValue is {$IFDEF FPC}fpjson.TJSONIntegerNumber{$ELSE}TJSONNumber{$ENDIF} then fRegConfig.WriteInteger(aName,StrToInt64(aValue))
  388. else if cValue is {$IFDEF FPC}fpjson.{$ENDIF}TJSONString then fRegConfig.WriteString(aName,aValue)
  389. else if cValue is {$IFDEF FPC}fpjson.TJSONBoolean{$ELSE}TJSONBool{$ENDIF} then fRegConfig.WriteString(aName,aValue);
  390. //else if cValue is TJSONNull then fRegConfig.WriteString(aName,'');
  391. end;
  392. function TAppConfigRegistryProvider.ProcessPairRead(const cCurrentKey, cRegKey : string; aIndex : Integer) : TJSONValue;
  393. var
  394. i : Integer;
  395. jValue : TJSONValue;
  396. RegValue : string;
  397. RegValueList : TStrings;
  398. RegKey : string;
  399. RegKeyList : TStrings;
  400. newObj : TJSONObject;
  401. begin
  402. newObj := TJSONObject.Create;
  403. //read root values
  404. RegValueList := TStringList.Create;
  405. try
  406. {$IFNDEF FPC}
  407. fRegConfig.GetValueNames(RegValueList);
  408. {$ELSE}
  409. try
  410. fRegConfig.GetValueNames(RegValueList);
  411. except
  412. end;
  413. {$ENDIF}
  414. for RegValue in RegValueList do
  415. begin
  416. newObj.AddPair(RegValue,ReadRegValue(cCurrentKey,RegValue));
  417. end;
  418. finally
  419. RegValueList.Free;
  420. end;
  421. //read root keys
  422. RegKeyList := TStringList.Create;
  423. try
  424. {$IFNDEF FPC}
  425. fRegConfig.GetKeyNames(RegKeyList);
  426. {$ELSE}
  427. try
  428. fRegConfig.GetKeyNames(RegKeyList);
  429. except
  430. end;
  431. {$ENDIF}
  432. for RegKey in RegKeyList do
  433. begin
  434. fRegConfig.OpenKeyReadOnly(cCurrentKey + '\' + RegKey);
  435. if IsRegKeyObject then
  436. begin
  437. jValue := ProcessPairRead(cCurrentKey + '\' + RegKey,Regkey,i);
  438. newObj.AddPair(RegKey,jValue);
  439. end
  440. else if IsRegKeyArray then
  441. begin
  442. jValue := ProcessElementRead(cCurrentKey + '\' + RegKey,Regkey,i);
  443. newObj.AddPair(RegKey,jValue);
  444. end
  445. else raise EAppConfig.Create('Unknow value reading Config Registry');
  446. end;
  447. finally
  448. RegKeyList.Free;
  449. end;
  450. Result := TJsonValue(newObj);
  451. end;
  452. function TAppConfigRegistryProvider.ProcessElementRead(const cCurrentKey, cRegKey : string; aIndex : Integer) : TJSONValue;
  453. var
  454. i : Integer;
  455. jValue : TJSONValue;
  456. RegValue : string;
  457. RegValueList : TStrings;
  458. RegKey : string;
  459. RegKeyList : TStrings;
  460. newObj : TJSONArray;
  461. begin
  462. newObj := TJSONArray.Create;
  463. //read root values
  464. RegValueList := TStringList.Create;
  465. try
  466. {$IFNDEF FPC}
  467. fRegConfig.GetValueNames(RegValueList);
  468. {$ELSE}
  469. try
  470. fRegConfig.GetValueNames(RegValueList);
  471. except
  472. end;
  473. {$ENDIF}
  474. for RegValue in RegValueList do
  475. begin
  476. newObj.AddElement(ReadRegValue(cCurrentKey,RegValue));
  477. end;
  478. finally
  479. RegValueList.Free;
  480. end;
  481. //read root keys
  482. RegKeyList := TStringList.Create;
  483. try
  484. {$IFNDEF FPC}
  485. fRegConfig.GetKeyNames(RegKeyList);
  486. {$ELSE}
  487. try
  488. fRegConfig.GetKeyNames(RegKeyList);
  489. except
  490. end;
  491. {$ENDIF}
  492. for RegKey in RegKeyList do
  493. begin
  494. fRegConfig.OpenKeyReadOnly(cCurrentKey + '\' + RegKey);
  495. if IsRegKeyObject then
  496. begin
  497. jValue := ProcessPairRead(cCurrentKey + '\' + RegKey,Regkey,i);
  498. newObj.AddElement(jValue);
  499. end
  500. else if IsRegKeyArray then
  501. begin
  502. jValue := ProcessElementRead(cCurrentKey + '\' + RegKey,Regkey,i);
  503. newObj.AddElement(jValue);
  504. end
  505. else raise EAppConfig.Create('Unknow value reading Config Registry');
  506. end;
  507. finally
  508. RegKeyList.Free;
  509. end;
  510. Result := TJsonValue(newObj);
  511. end;
  512. procedure TAppConfigRegistryProvider.ProcessPairWrite(const cCurrentKey: string; obj: TJSONObject; aIndex: integer);
  513. var
  514. jPair: TJSONPair;
  515. i : Integer;
  516. aCount: integer;
  517. begin
  518. jPair := obj.Pairs[aIndex];
  519. if IsSimpleJsonValue(jPair.JsonValue) then
  520. begin
  521. AddRegValue(cCurrentKey,jPair.JsonString{$IFNDEF FPC}.ToString{$ENDIF},jPair.JsonValue);
  522. Exit;
  523. end;
  524. if jPair.JsonValue is {$IFDEF FPC}fpjson.{$ENDIF}TJSONObject then
  525. begin
  526. aCount := TJSONObject(jPair.JsonValue).Count;
  527. for i := 0 to aCount - 1 do
  528. ProcessPairWrite(cCurrentKey + '\' + jPair.JsonString{$IFNDEF FPC}.ToString{$ENDIF}.DeQuotedString('"'), TJSONObject(jPair.JsonValue),i);
  529. end
  530. else if jPair.JsonValue is {$IFDEF FPC}fpjson.{$ENDIF}TJSONArray then
  531. begin
  532. aCount := TJSONArray(jPair.JsonValue).Count;
  533. for i := 0 to aCount - 1 do
  534. ProcessElementWrite(cCurrentKey + '\' + jPair.JsonString{$IFNDEF FPC}.ToString{$ENDIF}.DeQuotedString('"'), TJSONArray(jPair.JsonValue),i,aCount);
  535. end
  536. else raise EAppConfig.Create('Error Saving config to Registry');
  537. end;
  538. procedure TAppConfigRegistryProvider.ProcessElementWrite(const cCurrentKey: string; arr: TJSONArray; aIndex, aMax: integer);
  539. var
  540. jValue: TJSONValue;
  541. i : Integer;
  542. aCount: integer;
  543. dig : Integer;
  544. begin
  545. jValue := arr.Items[aIndex];
  546. dig := CountDigits(aMax);
  547. if IsSimpleJsonValue(jValue) then
  548. begin
  549. AddRegValue(cCurrentKey,Zeroes(aIndex,dig),jValue);
  550. Exit;
  551. end;
  552. if jValue is {$IFDEF FPC}fpjson.{$ENDIF}TJSONObject then
  553. begin
  554. aCount := TJSONObject(jValue).Count;
  555. for i := 0 to aCount - 1 do
  556. ProcessPairWrite(cCurrentKey + '\' + Zeroes(aIndex,dig),TJSONObject(jValue),i);
  557. end
  558. else if jValue is {$IFDEF FPC}fpjson.{$ENDIF}TJSONArray then
  559. begin
  560. aCount := TJSONArray(jValue).Count;
  561. for i := 0 to aCount - 1 do
  562. ProcessElementWrite(cCurrentKey + '\' + Zeroes(i,dig),TJSONArray(jValue),i,aCount);
  563. end
  564. else raise EAppConfig.Create('Error Saving config to Registry');
  565. end;
  566. { TAppConfigRegistry }
  567. constructor TAppConfigRegistry.Create(aHRoot : HKEY = HKEY_CURRENT_USER; const aMainKey : string = '');
  568. begin
  569. inherited Create(TAppConfigRegistryProvider.Create(aHRoot,aMainKey));
  570. end;
  571. destructor TAppConfigRegistry.Destroy;
  572. begin
  573. inherited;
  574. end;
  575. function TAppConfigRegistry.GetProvider: TAppConfigRegistryProvider;
  576. begin
  577. if not Assigned(fProvider) then raise EAppConfig.Create('No provider assigned!');
  578. Result := TAppConfigRegistryProvider(fProvider);
  579. end;
  580. end.