2
0

Quick.Config.Registry.pas 18 KB

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