bgraformatui.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. {*******************************************************************************
  3. (c) 2025 - Massimo Magnano
  4. ********************************************************************************
  5. Form that contains the various UI of the graphic formats inside panels.
  6. When it is executed calling Execute ONLY the panel of the selected format will be
  7. visible and the form will be resized accordingly.
  8. Another way to use it is to call the GetUI method to take the panel of the
  9. selected format, so that you can change its parent and use it in another form.
  10. In this case the user is responsible for releasing the TBGRAFormatUIContainer class.
  11. }
  12. unit BGRAFormatUI;
  13. {$mode ObjFPC}{$H+}
  14. interface
  15. uses
  16. Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, ComCtrls, Buttons,
  17. TypInfo, Rtti, FpImage,
  18. BCPanel, BCTrackbarUpdown, BCFluentSlider,
  19. BGRABitmapTypes;
  20. type
  21. //To implement a new panel of a format, which I will probably do all of them myself :-) :
  22. //
  23. //The container panel (which must be a TBCPanel) must be named like the Format
  24. //enum TBGRAImageFormat, so for example the panel for the Jpeg format will be named ifJpeg.
  25. //The position at design time does not matter because the position is changed at runtime.
  26. //
  27. //If you want to use autofill to and from the UI
  28. // - the Writer class must have the properties of interest declared as published
  29. // - the names of the Panel sub controls must be panelname_propertyname
  30. //
  31. // for example we have the ifJpeg Writer TBGRAWriterJPEG
  32. // published
  33. // property ProgressiveEncoding;
  34. // property GrayScale;
  35. // property CompressionQuality;
  36. //
  37. // the corresponding UI will be
  38. // ifJpeg : TBCPanel
  39. // ifJpeg_ProgressiveEncoding: TCheckBox;
  40. // ifJpeg_GrayScale: TCheckBox;
  41. // ifJpeg_CompressionQuality: TBCTrackbarUpdown;
  42. //
  43. // - for controls that have a list of Items, like ComboBox or RadioGroup, there are 3 ways to use them:
  44. // Tag=0 the value will be taken/set directly from ItemIndex;
  45. // Tag=1 the value will be taken/set from the corresponding Objects[ItemIndex]
  46. // (it is the UI creator's responsibility to fill Objects in the Create event;
  47. // Tag=2 same as Tag=1 but Items are filled automatically with Enum Names;
  48. { TBGRAFormatUIContainer }
  49. TBGRAFormatUIContainer = class(TForm)
  50. ifWebP: TBCPanel;
  51. ifWebP_QualityPercent: TBCTrackbarUpdown;
  52. ifWebP_Lossless: TCheckBox;
  53. ifTiff_Compression: TCheckBox;
  54. ifLazPaint_Caption: TEdit;
  55. ifPcx: TBCPanel;
  56. ifBmp_BitsPerPixel: TComboBox;
  57. ifBmp_GrayScale: TCheckBox;
  58. ifPcx_Compressed: TCheckBox;
  59. ifPng_CompressionLevel: TBCFluentSlider;
  60. ifPng: TBCPanel;
  61. ifPng_GrayScale: TCheckBox;
  62. ifPng_WordSized: TCheckBox;
  63. ifBmp: TBCPanel;
  64. ifBmp_RLECompress: TCheckBox;
  65. ifLazPaint: TBCPanel;
  66. ifTiff_SaveCMYKAsRGB: TCheckBox;
  67. ifTiff_PremultiplyRGB: TCheckBox;
  68. ifTiff: TBCPanel;
  69. btCancel: TBitBtn;
  70. btOk: TBitBtn;
  71. ifJpeg_CompressionQuality: TBCTrackbarUpdown;
  72. ifJpeg_GrayScale: TCheckBox;
  73. ifJpeg: TBCPanel;
  74. ifLazPaint_IncludeThumbnail: TCheckBox;
  75. Label1: TLabel;
  76. Label2: TLabel;
  77. Label3: TLabel;
  78. Label4: TLabel;
  79. Label5: TLabel;
  80. Label6: TLabel;
  81. Label7: TLabel;
  82. Label8: TLabel;
  83. Label9: TLabel;
  84. panelButtons: TPanel;
  85. ifJpeg_ProgressiveEncoding: TCheckBox;
  86. ifLazPaint_Compression: TRadioGroup;
  87. procedure FormCreate(Sender: TObject);
  88. procedure ifBmp_BitsPerPixelChange(Sender: TObject);
  89. procedure ifBmp_GrayScaleChange(Sender: TObject);
  90. private
  91. curFormat: TBGRAImageFormat;
  92. curWriter: TFPCustomImageWriter;
  93. rPanelFormat: TBCPanel;
  94. //some var for format specific UI
  95. oldBmp_BitsPerPixel: Integer;
  96. function AdjustPanels: Boolean;
  97. function SelectPanel: TBCPanel;
  98. function SetControlValue(const AValue: TValue; const AControl: TControl): Boolean;
  99. function GetControlValue(var AValue: TValue; const AControl: TControl): Boolean;
  100. //Copy Properties form TFPCustomImageWriter to UI
  101. procedure GetWriterProperties;
  102. public
  103. class function Execute(const AFormat: TBGRAImageFormat;
  104. var AWriter: TFPCustomImageWriter): Boolean;
  105. class function GetUI(const AFormat: TBGRAImageFormat;
  106. var AWriter: TFPCustomImageWriter;
  107. var APanel: TBCPanel): Boolean;
  108. class function BuildSaveFormats(const AControl: TControl;
  109. const ASelectFormat: TBGRAImageFormat=ifUnknown): Integer;
  110. //Set TFPCustomImageWriter Properties from UI
  111. procedure SetWriterProperties(var AWriter: TFPCustomImageWriter);
  112. property PanelFormat: TBCPanel read rPanelFormat;
  113. end;
  114. var
  115. BGRAFormatUIContainer: TBGRAFormatUIContainer = nil;
  116. implementation
  117. {$R *.lfm}
  118. uses BCComboBox;
  119. const
  120. BMP_BitsValidValues: array[0..6] of Integer = (1,4,8,15,16,24,32);
  121. type
  122. TRttiPropertyArray = specialize TArray<TRttiProperty>;
  123. { TBGRAFormatUIContainer }
  124. class function TBGRAFormatUIContainer.Execute(const AFormat: TBGRAImageFormat;
  125. var AWriter: TFPCustomImageWriter): Boolean;
  126. begin
  127. Result:= False;
  128. if (AFormat = ifUnknown) or
  129. ((AWriter = nil) and (DefaultBGRAImageWriter[AFormat] = nil))
  130. then exit;
  131. if (BGRAFormatUIContainer = nil)
  132. then BGRAFormatUIContainer :=TBGRAFormatUIContainer.Create(nil);
  133. if (BGRAFormatUIContainer <> nil) then
  134. with BGRAFormatUIContainer do
  135. try
  136. if (AWriter = nil) then AWriter:= CreateBGRAImageWriter(AFormat, True);
  137. curFormat:= AFormat;
  138. curWriter:= AWriter;
  139. AdjustPanels;
  140. GetWriterProperties;
  141. if (rPanelFormat <> nil) and (ShowModal = mrOk) then
  142. begin
  143. SetWriterProperties(AWriter);
  144. Result:= True;
  145. end;
  146. finally
  147. BGRAFormatUIContainer.Free; BGRAFormatUIContainer:= nil;
  148. end;
  149. end;
  150. class function TBGRAFormatUIContainer.GetUI(const AFormat: TBGRAImageFormat;
  151. var AWriter: TFPCustomImageWriter;
  152. var APanel: TBCPanel): Boolean;
  153. begin
  154. Result:= False;
  155. if (AFormat = ifUnknown) or
  156. ((AWriter = nil) and (DefaultBGRAImageWriter[AFormat] = nil))
  157. then exit;
  158. if (BGRAFormatUIContainer = nil)
  159. then BGRAFormatUIContainer :=TBGRAFormatUIContainer.Create(nil);
  160. if (BGRAFormatUIContainer <> nil) then
  161. with BGRAFormatUIContainer do
  162. try
  163. if (AWriter = nil) then AWriter:= CreateBGRAImageWriter(AFormat, True);
  164. curFormat:= AFormat;
  165. curWriter:= AWriter;
  166. APanel:= SelectPanel;
  167. GetWriterProperties;
  168. finally
  169. end;
  170. end;
  171. class function TBGRAFormatUIContainer.BuildSaveFormats(const AControl: TControl;
  172. const ASelectFormat: TBGRAImageFormat): Integer;
  173. var
  174. iFormat: TBGRAImageFormat;
  175. aItems: TStrings;
  176. procedure SetItemIndex(AValue: Integer);
  177. begin
  178. if (AControl is TComboBox)
  179. then TComboBox(AControl).ItemIndex:= AValue
  180. else
  181. if (AControl is TBCComboBox)
  182. then TBCComboBox(AControl).ItemIndex:= AValue
  183. else
  184. if (AControl is TRadioGroup)
  185. then TRadioGroup(AControl).ItemIndex:= AValue;
  186. end;
  187. begin
  188. Result:= 0;
  189. if (AControl is TComboBox)
  190. then with TComboBox(AControl) do
  191. begin
  192. Clear;
  193. aItems:= Items;
  194. end
  195. else
  196. if (AControl is TBCComboBox)
  197. then with TBCComboBox(AControl) do
  198. begin
  199. Clear;
  200. aItems:= Items;
  201. end
  202. else
  203. if (AControl is TRadioGroup)
  204. then with TRadioGroup(AControl) do
  205. begin
  206. aItems:= Items;
  207. aItems.Clear;
  208. end
  209. else exit;
  210. for iFormat:=Low(TBGRAImageFormat) to High(TBGRAImageFormat) do
  211. if (iFormat <> ifUnknown) and (DefaultBGRAImageWriter[iFormat] <> nil) then
  212. aItems.AddObject(BGRAImageFormat[iFormat].TypeName+' (.'+SuggestImageExtension(iFormat)+')',
  213. TObject(PTRUInt(iFormat)));
  214. Result:= aItems.Count;
  215. if (Result > 0)
  216. then if (ASelectFormat = ifUnknown)
  217. then SetItemIndex(0)
  218. else SetItemIndex(aItems.IndexOfObject(TObject(PTRUInt(ASelectFormat))));
  219. end;
  220. function TBGRAFormatUIContainer.SetControlValue(const AValue: TValue; const AControl: TControl): Boolean;
  221. var
  222. minVal, maxVal, intVal,
  223. iIndex: Integer;
  224. function SetControlItems(AItems: TStrings): Boolean;
  225. var
  226. PS: PShortString;
  227. i: Integer;
  228. begin
  229. Result:= False;
  230. Case AControl.Tag of
  231. 0: begin
  232. iIndex:= intVal;
  233. Result:= True;
  234. end;
  235. 1, -1: begin
  236. iIndex:= AItems.IndexOfObject(TObject(PtrUInt(intVal)));
  237. Result := (iIndex > -1);
  238. end;
  239. 2: if (AValue.Kind = tkEnumeration)
  240. then begin
  241. Result:= False;
  242. AControl.Tag:= -1; //Avoid Re-Fill already filled Items
  243. AItems.Clear;
  244. PS:= @AValue.TypeData^.NameList;
  245. for i:=AValue.TypeData^.MinValue to AValue.TypeData^.MaxValue do
  246. begin
  247. if PS=nil then break;
  248. AItems.AddObject(PS^, TObject(PtrUInt(i)));
  249. if (i = intVal) then
  250. begin
  251. iIndex:= intVal;
  252. Result:= True;
  253. end;
  254. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  255. end;
  256. end
  257. else begin
  258. iIndex:= AItems.IndexOfObject(TObject(PtrUInt(intVal)));
  259. Result := (iIndex > -1);
  260. end;
  261. end;
  262. end;
  263. begin
  264. Result:= False;
  265. //If we are here the corresponding property is present
  266. AControl.Visible:= True;
  267. if AControl.Enabled then
  268. try
  269. {#to-do Set with TCheckGroup}
  270. Case AValue.Kind of
  271. tkInteger: intVal:= AValue.AsInteger;
  272. tkEnumeration: begin
  273. minVal:= AValue.TypeData^.MinValue;
  274. maxVal:= AValue.TypeData^.MaxValue;
  275. intVal:= AValue.AsOrdinal;
  276. end;
  277. tkFloat: intVal:= Round(AValue.AsExtended);
  278. end;
  279. //Types will be added as we use them,
  280. //it is the responsibility of the UI creator not to put in crap like
  281. //a checkbox that takes the value from a string, etc...
  282. if (AControl is TEdit)
  283. then TEdit(AControl).Caption:= AValue.AsString
  284. else
  285. if (AControl is TCheckBox)
  286. then TCheckBox(AControl).Checked:= AValue.AsBoolean
  287. else
  288. if (AControl is TBCTrackbarUpdown)
  289. then with TBCTrackbarUpdown(AControl) do
  290. begin
  291. if (AValue.Kind = tkEnumeration) then
  292. begin
  293. MinValue:= minVal;
  294. MaxValue:= maxVal;
  295. end;
  296. Value:= intVal;
  297. end
  298. else
  299. (*if (AControl is TTrackbar)
  300. then with TTrackbar(AControl) do
  301. begin
  302. if (AValue.Kind = tkEnumeration) then
  303. begin
  304. Min:= minVal;
  305. Max:= maxVal;
  306. end;
  307. Position:= intVal;
  308. end
  309. else*)
  310. if (AControl is TComboBox)
  311. then with TComboBox(AControl) do
  312. begin
  313. if SetControlItems(Items) then ItemIndex:= iIndex;
  314. end
  315. else
  316. if (AControl is TRadioGroup)
  317. then with TRadioGroup(AControl) do
  318. begin
  319. if SetControlItems(Items) then ItemIndex:= iIndex;
  320. end
  321. else
  322. if (AControl is TBCFluentSlider)
  323. then with TBCFluentSlider(AControl) do
  324. begin
  325. if (AValue.Kind = tkEnumeration) then
  326. begin
  327. MinValue:= minVal;
  328. MaxValue:= maxVal;
  329. end;
  330. Value:= intVal;
  331. end;
  332. Result:= True;
  333. except
  334. Result:= False;
  335. end;
  336. end;
  337. function TBGRAFormatUIContainer.GetControlValue(var AValue: TValue; const AControl: TControl): Boolean;
  338. begin
  339. Result:= False;
  340. if AControl.Visible and AControl.Enabled then
  341. try
  342. //Types will be added as we use them,
  343. //it is the responsibility of the UI creator not to put in crap like
  344. //a Boolean that takes the value from an Trackbar, etc...
  345. {#to-do Set with TCheckGroup}
  346. if (AControl is TEdit)
  347. then AValue:= TEdit(AControl).Caption
  348. else
  349. if (AControl is TCheckBox)
  350. then AValue:= TCheckBox(AControl).Checked
  351. else
  352. if (AControl is TBCTrackbarUpdown)
  353. then AValue:= TBCTrackbarUpdown(AControl).Value
  354. else
  355. (*if (AControl is TTrackbar)
  356. then AValue:= TTrackbar(AControl).Position
  357. else*)
  358. if (AControl is TComboBox)
  359. then with TComboBox(AControl) do
  360. begin
  361. if (Tag = 0)
  362. then AValue:= ItemIndex
  363. else if (ItemIndex > -1) then AValue:= Integer(PtrUInt(Items.Objects[ItemIndex]));
  364. end
  365. else
  366. if (AControl is TRadioGroup)
  367. then with TRadioGroup(AControl) do
  368. begin
  369. if (Tag = 0)
  370. then AValue:= ItemIndex
  371. else if (ItemIndex > -1) then AValue:= Integer(PtrUInt(Items.Objects[ItemIndex]));
  372. end
  373. else
  374. if (AControl is TBCFluentSlider)
  375. then AValue:= TBCFluentSlider(AControl).Value;
  376. Result:= True;
  377. except
  378. Result:= False;
  379. end;
  380. end;
  381. //Set Writer Properties from UI
  382. procedure TBGRAFormatUIContainer.SetWriterProperties(var AWriter: TFPCustomImageWriter);
  383. var
  384. LContext: TRttiContext;
  385. procedure SetClassValues(const subPath: String; aInstance: TObject);
  386. var
  387. i: Integer;
  388. LType: TRttiType;
  389. PropList: TRttiPropertyArray;
  390. aValue: TValue;
  391. curControl: TControl;
  392. begin
  393. try
  394. LType:= LContext.GetType(aInstance.ClassType);
  395. //Read properties list
  396. PropList := LType.GetProperties;
  397. for i:= 0 to length(PropList)-1 do
  398. if PropList[i].IsReadable and PropList[i].IsWritable then
  399. begin
  400. aValue:= PropList[i].GetValue(aInstance);
  401. if aValue.IsObject
  402. then begin
  403. //Call recursively passing the object
  404. if (aValue.AsObject <> nil)
  405. then SetClassValues(subPath+'_'+PropList[i].Name, aValue.AsObject);
  406. end
  407. else if not(aValue.Kind = tkMethod) then
  408. begin
  409. //Find corresponding Control if any and Set Property value from it's Value
  410. curControl:= rPanelFormat.FindChildControl(subPath+'_'+PropList[i].Name);
  411. if (curControl <> nil) and
  412. GetControlValue(aValue, curControl)
  413. then PropList[i].SetValue(aInstance, aValue);
  414. end;
  415. end;
  416. finally
  417. PropList:=nil;
  418. end;
  419. end;
  420. begin
  421. if (curWriter <> nil) and (rPanelFormat <> nil) then
  422. try
  423. LContext:= TRttiContext.Create;
  424. SetClassValues(rPanelFormat.Name, curWriter);
  425. finally
  426. LContext.Free;
  427. end;
  428. end;
  429. //Set UI Control Values from Writer Properties
  430. procedure TBGRAFormatUIContainer.GetWriterProperties;
  431. var
  432. LContext: TRttiContext;
  433. procedure GetClassValues(const subPath: String; aInstance: TObject);
  434. var
  435. i: Integer;
  436. LType: TRttiType;
  437. PropList: TRttiPropertyArray;
  438. aValue: TValue;
  439. curControl: TControl;
  440. begin
  441. try
  442. LType:= LContext.GetType(aInstance.ClassType);
  443. //Read properties list
  444. PropList := LType.GetProperties;
  445. for i:= 0 to length(PropList)-1 do
  446. if PropList[i].IsReadable then
  447. begin
  448. aValue:= PropList[i].GetValue(aInstance);
  449. if aValue.IsObject
  450. then begin
  451. //Call recursively passing the object
  452. if (aValue.AsObject <> nil)
  453. then GetClassValues(subPath+'_'+PropList[i].Name, aValue.AsObject);
  454. end
  455. else if not(aValue.Kind = tkMethod) then
  456. begin
  457. //Find corresponding Control if any and Set it's value
  458. curControl:= rPanelFormat.FindChildControl(subPath+'_'+PropList[i].Name);
  459. if (curControl <> nil) then SetControlValue(aValue, curControl);
  460. end;
  461. end;
  462. finally
  463. PropList:=nil;
  464. end;
  465. end;
  466. begin
  467. if (curWriter <> nil) and (rPanelFormat <> nil) then
  468. try
  469. LContext:= TRttiContext.Create;
  470. GetClassValues(rPanelFormat.Name, curWriter);
  471. finally
  472. LContext.Free;
  473. end;
  474. end;
  475. procedure TBGRAFormatUIContainer.FormCreate(Sender: TObject);
  476. var
  477. i: Integer;
  478. begin
  479. //Bitmap Format
  480. oldBmp_BitsPerPixel:= -1;
  481. //Fill Bits x Pixels Objects Values
  482. for i:=0 to ifBmp_BitsPerPixel.Items.Count-1 do
  483. ifBmp_BitsPerPixel.Items.Objects[i]:= TObject(PtrUInt(BMP_BitsValidValues[i]));
  484. end;
  485. procedure TBGRAFormatUIContainer.ifBmp_GrayScaleChange(Sender: TObject);
  486. begin
  487. if ifBmp_GrayScale.Checked
  488. then begin
  489. oldBmp_BitsPerPixel:= ifBmp_BitsPerPixel.ItemIndex;
  490. ifBmp_BitsPerPixel.ItemIndex:= 2; //GrayScale
  491. end
  492. else if (oldBmp_BitsPerPixel > -1)
  493. then ifBmp_BitsPerPixel.ItemIndex:= oldBmp_BitsPerPixel;
  494. ifBmp_RLECompress.Enabled:= ifBmp_GrayScale.Checked;
  495. ifBmp_BitsPerPixel.Enabled:= not(ifBmp_GrayScale.Checked);
  496. end;
  497. procedure TBGRAFormatUIContainer.ifBmp_BitsPerPixelChange(Sender: TObject);
  498. begin
  499. ifBmp_RLECompress.Enabled:= (ifBmp_BitsPerPixel.ItemIndex in [1,2]);
  500. ifBmp_GrayScale.Enabled:= (ifBmp_BitsPerPixel.ItemIndex = 2);
  501. end;
  502. function TBGRAFormatUIContainer.AdjustPanels: Boolean;
  503. var
  504. pName: String;
  505. curControl: TControl;
  506. i: Integer;
  507. begin
  508. rPanelFormat:= nil;
  509. Result:= False;
  510. pName:= GetEnumName(TypeInfo(TBGRAImageFormat), Integer(curFormat));
  511. for i:=0 to ControlCount-1 do
  512. begin
  513. curControl:= Controls[i];
  514. if (curControl <> nil) and
  515. (curControl is TBCPanel) and
  516. (curControl.Enabled) then
  517. begin
  518. if (CompareText(curControl.Name, pName) = 0) then
  519. begin
  520. rPanelFormat:= TBCPanel(curControl);
  521. Result:= True;
  522. end;
  523. curControl.Visible:= False;
  524. end;
  525. end;
  526. if Result then
  527. begin
  528. rPanelFormat.Top:= 0; rPanelFormat.Left:= 0;
  529. rPanelFormat.BevelInner:= bvNone;
  530. rPanelFormat.BevelOuter:= bvNone;
  531. rPanelFormat.Caption:='';
  532. Self.Width:= rPanelFormat.Width;
  533. Self.Height:= rPanelFormat.Height+panelButtons.Height;
  534. rPanelFormat.Visible:= True;
  535. end;
  536. end;
  537. function TBGRAFormatUIContainer.SelectPanel: TBCPanel;
  538. var
  539. pName: String;
  540. curControl: TControl;
  541. i: Integer;
  542. begin
  543. rPanelFormat:= nil;
  544. Result:= nil;
  545. pName:= GetEnumName(TypeInfo(TBGRAImageFormat), Integer(curFormat));
  546. //I use Components because when the Panels parent is changed they are removed from Controls
  547. for i:=0 to ComponentCount-1 do
  548. if (Components[i] is TControl) then
  549. begin
  550. curControl:= TControl(Components[i]);
  551. if (curControl <> nil) and
  552. (curControl is TBCPanel) and
  553. (curControl.Enabled) and
  554. (CompareText(curControl.Name, pName) = 0) then
  555. begin
  556. Result:= TBCPanel(curControl);
  557. break;
  558. end;
  559. end;
  560. if (Result <> nil) then
  561. begin
  562. Result.Top:= 0; Result.Left:= 0;
  563. Result.BevelInner:= bvNone;
  564. Result.BevelOuter:= bvNone;
  565. Result.Caption:='';
  566. end;
  567. rPanelFormat:= Result;
  568. end;
  569. end.