CnWizardImage.pas 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. {******************************************************************************}
  2. { CnPack For Delphi/C++Builder }
  3. { 中国人自己的开放源码第三方开发包 }
  4. { (C)Copyright 2001-2018 CnPack 开发组 }
  5. { ------------------------------------ }
  6. { }
  7. { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
  8. { 改和重新发布这一程序。 }
  9. { }
  10. { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
  11. { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
  12. { }
  13. { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
  14. { 还没有,可访问我们的网站: }
  15. { }
  16. { 网站地址:http://www.cnpack.org }
  17. { 电子邮件:master@cnpack.org }
  18. { }
  19. {******************************************************************************}
  20. {******************************************************************************}
  21. { Unit Note: }
  22. { This file is derived from Marley Software }
  23. { }
  24. { Original author: }
  25. { http://marleyware.com/marley/twizardtree.htm }
  26. { Marley <pablo@marleyware.com> }
  27. {******************************************************************************}
  28. unit CnWizardImage;
  29. {* |<PRE>
  30. ================================================================================
  31. * 软件名称:界面组件包
  32. * 单元名称:向导界面图像控件
  33. * 单元作者:周劲羽 (zjy@cnpack.org)
  34. * 备 注:该控件基于 Mr. Marley 的 WizardTree 控件修改而来,增加了大量的改进
  35. * 开发平台:PWin2000Pro + Delphi 5.0
  36. * 兼容测试:PWin9X/2000/XP + Delphi 5/6
  37. * 本 地 化:该单元中的字符串均符合本地化处理方式
  38. * 单元标识:$Id$
  39. * 修改记录:2003.04.06 V1.0
  40. * 创建单元
  41. ================================================================================
  42. |</PRE>}
  43. interface
  44. {$I CnPack.inc}
  45. uses
  46. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;
  47. type
  48. TCnWizardItem = class;
  49. TCnWizardItems = class;
  50. TCnWizardImage = class;
  51. TBackGroundMode = (bmNormal, bmCenter, bmTiled, bmStretched);
  52. { TCnWizardItem }
  53. TCnWizardItem = class(TCollectionItem)
  54. private
  55. FCaption: TCaption;
  56. FBackGround: TPicture;
  57. FWizardItems: TCnWizardItems;
  58. FComment: TStrings;
  59. FBackGroundMode: TBackGroundMode;
  60. FBackGroundX: Integer;
  61. FBackGroundY: Integer;
  62. FVisible: Boolean;
  63. procedure Changed;
  64. procedure OnChange(Sender: TObject);
  65. procedure SetCaption(const Value: TCaption);
  66. procedure SetBackGround(const Value: TPicture);
  67. procedure SetComment(const Value: TStrings);
  68. procedure SetBackGroundMode(const Value: TBackGroundMode);
  69. procedure SetBackGroundTransparent(const Value: Boolean);
  70. function GetBackGroundTransparent: Boolean;
  71. procedure SetBackGroundX(const Value: Integer);
  72. procedure SetBackGroundY(const Value: Integer);
  73. procedure SetVisible(const Value: Boolean);
  74. function BackEmpty: Boolean;
  75. function GetBackGround: TPicture;
  76. protected
  77. function GetDisplayName: string; override;
  78. public
  79. constructor Create(Collection: TCollection); override;
  80. destructor Destroy; override;
  81. procedure Assign(Source: TPersistent); override;
  82. property WizardItems: TCnWizardItems read FWizardItems;
  83. published
  84. property Visible: Boolean read FVisible write SetVisible default True;
  85. property Caption: TCaption read FCaption write SetCaption;
  86. property Comment: TStrings read FComment write SetComment;
  87. property BackGround: TPicture read GetBackGround write SetBackGround;
  88. property BackGroundTransparent: Boolean read GetBackGroundTransparent
  89. write SetBackGroundTransparent default False;
  90. property BackGroundMode: TBackGroundMode read FBackGroundMode write
  91. SetBackGroundMode default bmNormal;
  92. property BackGroundX: Integer read FBackGroundX write SetBackGroundX default 0;
  93. property BackGroundY: Integer read FBackGroundY write SetBackGroundY default 0;
  94. end;
  95. { TCnWizardItems }
  96. TCnWizardItems = class(TOwnedCollection)
  97. private
  98. FWizardImage: TCnWizardImage;
  99. function GetItem(Index: Integer): TCnWizardItem;
  100. procedure SetItem(Index: Integer; const Value: TCnWizardItem);
  101. procedure Changed;
  102. protected
  103. procedure Update(Item: TCollectionItem); override;
  104. public
  105. constructor Create(AOwner: TCnWizardImage);
  106. property Items[Index: Integer]: TCnWizardItem read GetItem write SetItem; default;
  107. property WizardImage: TCnWizardImage read FWizardImage write FWizardImage;
  108. end;
  109. { TCnWizardImage }
  110. THeightRate = 0..100;
  111. TOnChanging = procedure(Sender: TObject; NewItemIndex: Integer; var AllowChange:
  112. Boolean) of object;
  113. TOnChange = procedure(Sender: TObject) of object;
  114. TCnWizardImage = class(TGraphicControl)
  115. private
  116. { Private declarations }
  117. FItemIndex: Integer;
  118. FTopMargin: Integer;
  119. FHorizontalSpace: Integer;
  120. FBoxWidth: Integer;
  121. FLeftMargin: Integer;
  122. FBoxHeight: Integer;
  123. FSelectedBoxColor: TColor;
  124. FBoxColor: TColor;
  125. FLineColor: TColor;
  126. FOnChange: TOnChange;
  127. FOnChanging: TOnChanging;
  128. FItems: TCnWizardItems;
  129. FBottomColor: TColor;
  130. FTopColor: TColor;
  131. FSelectedFont: TFont;
  132. FBackGroundMode: TBackGroundMode;
  133. FBackGround: TPicture;
  134. FBackGroundX: Integer;
  135. FBackGroundY: Integer;
  136. FCommentHeight: THeightRate;
  137. FCommentFont: TFont;
  138. FTreeHeight: THeightRate;
  139. FUpdateCount: Integer;
  140. procedure SetBoxColor(const Value: TColor);
  141. procedure SetBoxHeight(const Value: Integer);
  142. procedure SetBoxWidth(const Value: Integer);
  143. procedure SetHorizontalSpace(const Value: Integer);
  144. procedure SetItemIndex(const Value: Integer);
  145. procedure SetItems(const Value: TCnWizardItems);
  146. procedure SetLeftMargin(const Value: Integer);
  147. procedure SetLineColor(const Value: TColor);
  148. procedure SetSelectedBoxColor(const Value: TColor);
  149. procedure SetTopMargin(const Value: Integer);
  150. procedure SetBottomColor(const Value: TColor);
  151. procedure SetSelectedFont(const Value: TFont);
  152. procedure SetTopColor(const Value: TColor);
  153. function GetBackGround: TPicture;
  154. procedure SetBackGround(const Value: TPicture);
  155. procedure SetBackGroundMode(const Value: TBackGroundMode);
  156. function GetBackGroundTransparent: Boolean;
  157. procedure SetBackGroundTransparent(const Value: Boolean);
  158. procedure SetBackGroundX(const Value: Integer);
  159. procedure SetBackGroundY(const Value: Integer);
  160. procedure SetCommentFont(const Value: TFont);
  161. procedure SetCommentHeight(const Value: THeightRate);
  162. procedure SetTreeHeight(const Value: THeightRate);
  163. function BackEmpty: Boolean;
  164. private
  165. FMemBmp: TBitmap;
  166. FMemBmpValid: Boolean;
  167. procedure DrawBackGnd;
  168. procedure DrawMemBmp;
  169. procedure CheckMemBmp;
  170. private
  171. FRects: TList;
  172. procedure AllocateRects;
  173. procedure FillBox(ACanvas: TCanvas; Index: Integer; Live: Boolean);
  174. protected
  175. { Protected declarations }
  176. procedure Changed; overload;
  177. procedure Changed(Sender: TObject); overload;
  178. procedure Paint; override;
  179. procedure Click; override;
  180. property UpdateCount: Integer read FUpdateCount;
  181. public
  182. { Public declarations }
  183. constructor Create(AOwner: TComponent); override;
  184. destructor Destroy; override;
  185. procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  186. procedure BeginUpdate;
  187. procedure EndUpdate;
  188. published
  189. { Published declarations }
  190. property Align;
  191. property Anchors;
  192. property Constraints;
  193. property Enabled;
  194. property Font;
  195. property ShowHint;
  196. property Hint;
  197. property ParentFont default False;
  198. property ParentShowHint;
  199. property PopupMenu;
  200. property Visible;
  201. property DragCursor;
  202. property DragKind;
  203. property DragMode;
  204. property Height default 240;
  205. property Width default 120;
  206. property Items: TCnWizardItems read FItems write SetItems;
  207. property ItemIndex: Integer read FItemIndex write SetItemIndex;
  208. property LineColor: TColor read FLineColor write SetLineColor default clWhite;
  209. property SelectedBoxColor: TColor read FSelectedBoxColor write
  210. SetSelectedBoxColor default clLime;
  211. property BoxColor: TColor read FBoxColor write SetBoxColor default clGray;
  212. property HorizontalSpace: Integer read FHorizontalSpace write SetHorizontalSpace
  213. default 4;
  214. property TreeHeight: THeightRate read FTreeHeight write SetTreeHeight default 65;
  215. property BoxHeight: Integer read FBoxHeight write SetBoxHeight default 17;
  216. property BoxWidth: Integer read FBoxWidth write SetBoxWidth default 16;
  217. property LeftMargin: Integer read FLeftMargin write SetLeftMargin default 8;
  218. property TopMargin: Integer read FTopMargin write SetTopMargin default 12;
  219. property SelectedFont: TFont read FSelectedFont write SetSelectedFont;
  220. property TopColor: TColor read FTopColor write SetTopColor default clBlue;
  221. property BottomColor: TColor read FBottomColor write SetBottomColor default
  222. clBlack;
  223. property BackGround: TPicture read GetBackGround write SetBackGround;
  224. property BackGroundMode: TBackGroundMode read FBackGroundMode write
  225. SetBackGroundMode default bmNormal;
  226. property BackGroundX: Integer read FBackGroundX write SetBackGroundX default 0;
  227. property BackGroundY: Integer read FBackGroundY write SetBackGroundY default 0;
  228. property BackGroundTransparent: Boolean read GetBackGroundTransparent
  229. write SetBackGroundTransparent default False;
  230. property CommentFont: TFont read FCommentFont write SetCommentFont;
  231. property CommentHeight: THeightRate read FCommentHeight write SetCommentHeight default 25;
  232. property OnClick;
  233. property OnContextPopup;
  234. property OnDblClick;
  235. property OnDragDrop;
  236. property OnDragOver;
  237. property OnEndDock;
  238. property OnEndDrag;
  239. property OnMouseDown;
  240. property OnMouseMove;
  241. property OnMouseUp;
  242. property OnStartDock;
  243. property OnStartDrag;
  244. property OnChanging: TOnChanging read FOnChanging write FOnChanging;
  245. property OnChange: TOnChange read FOnChange write FOnChange;
  246. end;
  247. implementation
  248. {$R-}
  249. uses
  250. Math;
  251. procedure DrawTiled(Canvas: TCanvas; Rect: TRect; G: TGraphic);
  252. var
  253. R, Rows, C, Cols: Integer;
  254. begin
  255. if (G <> nil) and (not G.Empty) then
  256. begin
  257. Rows := ((Rect.Bottom - Rect.Top) div G.Height) + 1;
  258. Cols := ((Rect.Right - Rect.Left) div G.Width) + 1;
  259. for R := 1 to Rows do
  260. for C := 1 to Cols do
  261. Canvas.Draw(Rect.Left + (C - 1) * G.Width, Rect.Top + (R - 1) * G.Height,
  262. G);
  263. end;
  264. end;
  265. procedure DrawBackGround(Canvas: TCanvas; Rect: TRect;
  266. G: TGraphic; Mode: TBackGroundMode);
  267. begin
  268. if (G <> nil) and (not G.Empty) then
  269. begin
  270. case Mode of
  271. bmTiled:
  272. DrawTiled(Canvas, Rect, G);
  273. bmStretched:
  274. Canvas.StretchDraw(Rect, G);
  275. bmCenter:
  276. Canvas.Draw((Rect.Right + Rect.Left - G.Width) div 2,
  277. (Rect.Bottom + Rect.Top - G.Height) div 2, G);
  278. bmNormal:
  279. Canvas.Draw(Rect.Left, Rect.Top, G);
  280. end;
  281. end;
  282. end;
  283. { TCnWizardItem }
  284. procedure TCnWizardItem.Assign(Source: TPersistent);
  285. begin
  286. if Source is TCnWizardItem then
  287. begin
  288. FCaption := TCnWizardItem(Source).FCaption;
  289. FComment.Assign(TCnWizardItem(Source).FComment);
  290. FVisible := TCnWizardItem(Source).FVisible;
  291. BackGround := TCnWizardItem(Source).FBackGround;
  292. FBackGroundMode := TCnWizardItem(Source).FBackGroundMode;
  293. FBackGroundX := TCnWizardItem(Source).FBackGroundX;
  294. FBackGroundY := TCnWizardItem(Source).FBackGroundY;
  295. end
  296. else
  297. inherited;
  298. end;
  299. procedure TCnWizardItem.Changed;
  300. begin
  301. if Assigned(FWizardItems) then
  302. FWizardItems.Changed;
  303. end;
  304. procedure TCnWizardItem.OnChange(Sender: TObject);
  305. begin
  306. Changed;
  307. end;
  308. constructor TCnWizardItem.Create(Collection: TCollection);
  309. begin
  310. inherited;
  311. FWizardItems := TCnWizardItems(Collection);
  312. if Assigned(FWizardItems) then
  313. FCaption := Format('Step%d', [FWizardItems.Count - 1]);
  314. FComment := TStringList.Create;
  315. TStringList(FComment).OnChange := OnChange;
  316. FVisible := True;
  317. FBackGroundMode := bmNormal;
  318. FBackGroundX := 0;
  319. FBackGroundY := 0;
  320. end;
  321. destructor TCnWizardItem.Destroy;
  322. begin
  323. FBackGround.Free;
  324. FComment.Free;
  325. inherited;
  326. end;
  327. function TCnWizardItem.GetDisplayName: string;
  328. begin
  329. Result := FCaption;
  330. end;
  331. procedure TCnWizardItem.SetCaption(const Value: TCaption);
  332. begin
  333. if FCaption <> Value then
  334. begin
  335. FCaption := Value;
  336. Changed;
  337. end;
  338. end;
  339. procedure TCnWizardItem.SetComment(const Value: TStrings);
  340. begin
  341. FComment.Assign(Value);
  342. Changed;
  343. end;
  344. function TCnWizardItem.GetBackGround: TPicture;
  345. begin
  346. if not Assigned(FBackGround) then
  347. begin
  348. FBackGround := TPicture.Create;
  349. FBackGround.OnChange := OnChange;
  350. end;
  351. Result := FBackGround;
  352. end;
  353. procedure TCnWizardItem.SetBackGround(const Value: TPicture);
  354. begin
  355. if not Assigned(Value) or not Assigned(Value.Graphic) or Value.Graphic.Empty then
  356. FreeAndNil(FBackGround)
  357. else
  358. BackGround.Assign(Value);
  359. Changed;
  360. end;
  361. procedure TCnWizardItem.SetBackGroundMode(const Value: TBackGroundMode);
  362. begin
  363. FBackGroundMode := Value;
  364. Changed;
  365. end;
  366. function TCnWizardItem.GetBackGroundTransparent: Boolean;
  367. begin
  368. Result := not BackEmpty;
  369. if Result then
  370. Result := FBackGround.Graphic.Transparent;
  371. end;
  372. procedure TCnWizardItem.SetBackGroundTransparent(const Value: Boolean);
  373. begin
  374. if not BackEmpty then
  375. FBackGround.Graphic.Transparent := Value;
  376. end;
  377. procedure TCnWizardItem.SetBackGroundX(const Value: Integer);
  378. begin
  379. if FBackGroundX <> Value then
  380. begin
  381. FBackGroundX := Value;
  382. Changed;
  383. end;
  384. end;
  385. procedure TCnWizardItem.SetBackGroundY(const Value: Integer);
  386. begin
  387. if FBackGroundY <> Value then
  388. begin
  389. FBackGroundY := Value;
  390. Changed;
  391. end;
  392. end;
  393. procedure TCnWizardItem.SetVisible(const Value: Boolean);
  394. begin
  395. if FVisible <> Value then
  396. begin
  397. FVisible := Value;
  398. Changed;
  399. end;
  400. end;
  401. function TCnWizardItem.BackEmpty: Boolean;
  402. begin
  403. Result := not Assigned(FBackGround) or not Assigned(FBackGround.Graphic)
  404. or FBackGround.Graphic.Empty;
  405. end;
  406. { TCnWizardItems }
  407. procedure TCnWizardItems.Changed;
  408. begin
  409. if Assigned(FWizardImage) then
  410. FWizardImage.Changed;
  411. end;
  412. constructor TCnWizardItems.Create(AOwner: TCnWizardImage);
  413. begin
  414. inherited Create(AOwner, TCnWizardItem);
  415. if Assigned(AOwner) and (csDesigning in AOwner.ComponentState) then
  416. begin
  417. BeginUpdate;
  418. try
  419. with TCnWizardItem(Add) do
  420. begin
  421. Caption := 'Start';
  422. Comment.Text := 'Welcome to wizard!';
  423. end;
  424. with TCnWizardItem(Add) do
  425. Comment.Text := Caption;
  426. with TCnWizardItem(Add) do
  427. Comment.Text := Caption;
  428. with TCnWizardItem(Add) do
  429. begin
  430. Caption := 'Finish';
  431. Comment.Text := 'Finished.';
  432. end;
  433. finally
  434. EndUpdate;
  435. end;
  436. end;
  437. FWizardImage := AOwner;
  438. end;
  439. function TCnWizardItems.GetItem(Index: Integer): TCnWizardItem;
  440. begin
  441. Result := TCnWizardItem(inherited GetItem(Index));
  442. end;
  443. procedure TCnWizardItems.SetItem(Index: Integer; const Value: TCnWizardItem);
  444. begin
  445. inherited SetItem(Index, Value);
  446. end;
  447. procedure TCnWizardItems.Update(Item: TCollectionItem);
  448. begin
  449. inherited;
  450. Changed;
  451. end;
  452. { TCnWizardImage }
  453. constructor TCnWizardImage.Create(AOwner: TComponent);
  454. begin
  455. inherited Create(AOwner);
  456. ControlStyle := ControlStyle + [csOpaque];
  457. FItems := TCnWizardItems.Create(Self);
  458. FRects := TList.Create;
  459. FMemBmp := TBitmap.Create;
  460. FMemBmpValid := False;
  461. Font.Color := clWhite;
  462. FSelectedFont := TFont.Create;
  463. FSelectedFont.Assign(Font);
  464. FSelectedFont.Style := [fsBold];
  465. FCommentFont := TFont.Create;
  466. FCommentFont.Assign(Font);
  467. FBackGroundMode := bmNormal;
  468. FBackGroundX := 0;
  469. FBackGroundY := 0;
  470. FTopColor := clBlue;
  471. FBottomColor := clBlack;
  472. FItemIndex := 0;
  473. FBoxColor := clGray;
  474. FSelectedBoxColor := clLime;
  475. FLineColor := clWhite;
  476. FHorizontalSpace := 4;
  477. FTreeHeight := 65;
  478. FCommentHeight := 25;
  479. FBoxHeight := 17;
  480. FBoxWidth := 16;
  481. FTopMargin := 12;
  482. FLeftMargin := 8;
  483. Width := 120;
  484. Height := 240;
  485. Font.OnChange := Changed;
  486. FSelectedFont.OnChange := Changed;
  487. FCommentFont.OnChange := Changed;
  488. end;
  489. destructor TCnWizardImage.Destroy;
  490. begin
  491. FSelectedFont.Free;
  492. FMemBmp.Free;
  493. FItems.Clear;
  494. AllocateRects;
  495. FItems.Free;
  496. FRects.Free;
  497. FCommentFont.Free;
  498. inherited;
  499. end;
  500. procedure TCnWizardImage.Changed;
  501. begin
  502. FMemBmpValid := False;
  503. if FItemIndex > FItems.Count - 1 then
  504. FItemIndex := FItems.Count - 1;
  505. if ([csLoading, csDestroying, csReading, csUpdating, csWriting] *
  506. ComponentState = []) and (UpdateCount = 0) then
  507. Refresh;
  508. end;
  509. procedure TCnWizardImage.Changed(Sender: TObject);
  510. begin
  511. Changed;
  512. end;
  513. procedure TCnWizardImage.SetItemIndex(const Value: Integer);
  514. begin
  515. if (Value >= -1) and (Value < FItems.Count) then
  516. if (Value <> FItemIndex) then
  517. begin
  518. FItemIndex := Value;
  519. Changed;
  520. end;
  521. end;
  522. procedure TCnWizardImage.Click;
  523. var
  524. Index: Integer;
  525. P: TPoint;
  526. AllowChange: Boolean;
  527. begin
  528. inherited;
  529. GetCursorPos(P);
  530. P := ScreenToClient(P);
  531. for Index := 0 to FRects.Count - 1 do
  532. begin
  533. if PtInRect(TRect(FRects[Index]^), P) then
  534. begin
  535. if ItemIndex <> Index then
  536. begin
  537. AllowChange := True;
  538. if Assigned(FOnChanging) then
  539. FOnChanging(Self, Index, AllowChange);
  540. if AllowChange then
  541. begin
  542. ItemIndex := Index;
  543. if Assigned(FOnChange) then
  544. FOnChange(Self);
  545. end;
  546. end;
  547. Break;
  548. end;
  549. end;
  550. end;
  551. procedure TCnWizardImage.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
  552. begin
  553. inherited;
  554. Changed;
  555. end;
  556. procedure TCnWizardImage.BeginUpdate;
  557. begin
  558. Inc(FUpdateCount);
  559. end;
  560. procedure TCnWizardImage.EndUpdate;
  561. begin
  562. Dec(FUpdateCount);
  563. if FUpdateCount = 0 then
  564. Changed;
  565. end;
  566. procedure TCnWizardImage.AllocateRects;
  567. var
  568. Index: Integer;
  569. P: Pointer;
  570. begin
  571. if FRects.Count < FItems.Count then
  572. for Index := FRects.Count to FItems.Count - 1 do
  573. begin
  574. GetMem(P, SizeOf(TRect));
  575. FRects.Add(P);
  576. end
  577. else if FRects.Count > FItems.Count then
  578. for Index := FRects.Count - 1 downto FItems.Count do
  579. begin
  580. FreeMem(FRects[Index]);
  581. FRects.Delete(Index);
  582. end;
  583. end;
  584. procedure TCnWizardImage.FillBox(ACanvas: TCanvas; Index: Integer; Live: Boolean);
  585. var
  586. BoxRect: TRect;
  587. TextRect: TRect;
  588. Text: string;
  589. begin
  590. if (Index < 0) or (Index >= FItems.Count) then
  591. Exit;
  592. ACanvas.Brush.Style := bsSolid;
  593. if Live then
  594. ACanvas.Brush.Color := SelectedBoxColor
  595. else
  596. ACanvas.Brush.Color := BoxColor;
  597. BoxRect := TRect(FRects[Index]^);
  598. TextRect := BoxRect;
  599. BoxRect.Right := BoxRect.Left + BoxWidth;
  600. TextRect.Left := BoxRect.Right + HorizontalSpace;
  601. if (Index = 0) or (Index = FItems.Count - 1) then
  602. Inc(TextRect.Left, HorizontalSpace + BoxWidth div 2);
  603. ACanvas.FillRect(BoxRect);
  604. ACanvas.Brush.Style := bsClear;
  605. if Live then
  606. ACanvas.Font := FSelectedFont
  607. else
  608. ACanvas.Font := Font;
  609. Text := FItems[Index].Caption;
  610. ACanvas.TextOut(TextRect.Left, TextRect.Top + ((BoxHeight -
  611. ACanvas.TextHeight(Text)) div 2), Text);
  612. TRect(FRects[Index]^) := Rect(BoxRect.Left, BoxRect.Top, BoxRect.Left + BoxWidth +
  613. HorizontalSpace + ACanvas.TextWidth(Text), BoxRect.Top +
  614. BoxHeight);
  615. if (Index = 0) or (Index = FItems.Count - 1) then
  616. Inc(TRect(FRects[Index]^).Right, BoxWidth + HorizontalSpace);
  617. if Live and (FCommentHeight > 0) then
  618. begin
  619. Text := FItems[Index].Comment.Text;
  620. ACanvas.Font := FCommentFont;
  621. TextRect := Rect(LeftMargin, Height * (100 - FCommentHeight)
  622. div 100, Width - LeftMargin, Height);
  623. DrawText(ACanvas.Handle, PChar(Text), Length(Text), TextRect,
  624. DT_EXPANDTABS or DT_WORDBREAK or DT_LEFT);
  625. end;
  626. end;
  627. procedure TCnWizardImage.DrawBackGnd;
  628. type
  629. PRGBArray = ^TRGBArray;
  630. TRGBArray = array[0..0] of TRGBTriple;
  631. var
  632. pLine: PRGBArray;
  633. i, j: Integer;
  634. RGB: TRGBTriple;
  635. tr, tg, tb: Byte;
  636. br, bg, bb: Byte;
  637. begin
  638. FMemBmp.Width := Width;
  639. FMemBmp.Height := Height;
  640. FMemBmp.PixelFormat := pf24Bit;
  641. if FTopColor = FBottomColor then
  642. begin
  643. FMemBmp.Canvas.Brush.Color := FTopColor;
  644. FMemBmp.Canvas.Brush.Style := bsSolid;
  645. FMemBmp.Canvas.FillRect(Rect(0, 0, Width, Height));
  646. end
  647. else
  648. for i := 0 to FMemBmp.Height - 1 do
  649. begin
  650. pLine := FMemBmp.ScanLine[i];
  651. tr := GetRValue(ColorToRGB(FTopColor));
  652. tg := GetGValue(ColorToRGB(FTopColor));
  653. tb := GetBValue(ColorToRGB(FTopColor));
  654. br := GetRValue(ColorToRGB(FBottomColor));
  655. bg := GetGValue(ColorToRGB(FBottomColor));
  656. bb := GetBValue(ColorToRGB(FBottomColor));
  657. RGB.rgbtRed := tr + (br - tr) * i div FMemBmp.Height;
  658. RGB.rgbtGreen := tg + (bg - tg) * i div FMemBmp.Height;
  659. RGB.rgbtBlue := tb + (bb - tb) * i div FMemBmp.Height;
  660. for j := 0 to FMemBmp.Width - 1 do
  661. pLine^[j] := RGB;
  662. end;
  663. if (FItems.Count > 0) and (FItemIndex >= 0) and not FItems[FItemIndex].BackEmpty then
  664. begin
  665. with FMemBmp do
  666. if FItems[FItemIndex].FBackGroundMode = bmNormal then
  667. Canvas.Draw(FItems[FItemIndex].BackGroundX, FItems[FItemIndex].BackGroundY,
  668. FItems[FItemIndex].FBackGround.Graphic)
  669. else
  670. DrawBackGround(Canvas, Rect(0, 0, Width, Height),
  671. FItems[FItemIndex].FBackGround.Graphic,
  672. FItems[FItemIndex].FBackGroundMode);
  673. end
  674. else if not BackEmpty then
  675. begin
  676. with FMemBmp do
  677. if FBackGroundMode = bmNormal then
  678. Canvas.Draw(BackGroundX, BackGroundY, FBackGround.Graphic)
  679. else
  680. DrawBackGround(Canvas, Rect(0, 0, Width, Height), FBackGround.Graphic,
  681. FBackGroundMode);
  682. end;
  683. end;
  684. procedure TCnWizardImage.DrawMemBmp;
  685. var
  686. Index: Integer;
  687. X, Y: Integer;
  688. DrawHeight: Integer;
  689. RSpace: Double;
  690. VerticalSpace: Integer;
  691. VisibleCount: Integer;
  692. CurrCount: Integer;
  693. begin
  694. AllocateRects;
  695. DrawBackGnd;
  696. if FItems.Count < 3 then
  697. Exit;
  698. VisibleCount := 0;
  699. for Index := 1 to FItems.Count - 2 do
  700. begin
  701. if FItems[Index].Visible then
  702. Inc(VisibleCount);
  703. end;
  704. if VisibleCount < 1 then
  705. Exit;
  706. DrawHeight := Height * FTreeHeight div 100 - TopMargin - BoxHeight;
  707. RSpace := (DrawHeight - BoxHeight * VisibleCount) / (VisibleCount + 1);
  708. VerticalSpace := Round(RSpace);
  709. CurrCount := 0;
  710. for Index := 0 to FItems.Count - 1 do
  711. begin
  712. if (Index = 0) or (Index = FItems.Count - 1) or FItems[Index].Visible then
  713. begin
  714. if Index = 0 then
  715. begin
  716. X := LeftMargin;
  717. Y := TopMargin;
  718. end
  719. else if Index = FItems.Count - 1 then
  720. begin
  721. X := LeftMargin;
  722. Y := TopMargin + DrawHeight;
  723. end
  724. else
  725. begin
  726. Inc(CurrCount);
  727. X := LeftMargin + BoxWidth + HorizontalSpace;
  728. Y := Round(TopMargin + BoxHeight / 2 + CurrCount * RSpace +
  729. (CurrCount - 1) * BoxHeight);
  730. end;
  731. TRect(FRects[Index]^) := Rect(X, Y, X + BoxWidth + HorizontalSpace +
  732. FMemBmp.Canvas.TextWidth(FItems[Index].FCaption), Y + BoxHeight);
  733. FillBox(FMemBmp.Canvas, Index, ItemIndex = Index);
  734. FMemBmp.Canvas.Pen.Color := LineColor;
  735. if Index = 0 then
  736. begin
  737. FMemBmp.Canvas.MoveTo(X + BoxWidth, Y + BoxHeight div 2);
  738. FMemBmp.Canvas.LineTo(X + HorizontalSpace + BoxWidth + BoxWidth div 2,
  739. Y + BoxHeight div 2);
  740. FMemBmp.Canvas.LineTo(X + HorizontalSpace + BoxWidth + BoxWidth div 2,
  741. Y + BoxHeight div 2 + VerticalSpace + 1);
  742. end
  743. else if Index = FItems.Count - 1 then
  744. begin
  745. FMemBmp.Canvas.MoveTo(X + BoxWidth, Y + BoxHeight div 2);
  746. FMemBmp.Canvas.LineTo(X + HorizontalSpace + BoxWidth + BoxWidth div 2,
  747. Y + BoxHeight div 2);
  748. end
  749. else if (Index < FItems.Count - 1) then
  750. begin
  751. FMemBmp.Canvas.MoveTo(X + BoxWidth div 2, Y + BoxHeight);
  752. FMemBmp.Canvas.LineTo(X + BoxWidth div 2, Min(TopMargin + DrawHeight
  753. + BoxHeight div 2, Y + BoxHeight + VerticalSpace) + 1);
  754. end;
  755. end
  756. else
  757. begin
  758. TRect(FRects[Index]^) := Rect(0, 0, 0, 0);
  759. end;
  760. end;
  761. FMemBmp.Canvas.Pen.Color := LineColor;
  762. X := LeftMargin + BoxWidth div 2;
  763. Y := TopMargin + BoxHeight;
  764. FMemBmp.Canvas.MoveTo(X, Y);
  765. FMemBmp.Canvas.LineTo(X, Y + DrawHeight - BoxHeight);
  766. end;
  767. procedure TCnWizardImage.CheckMemBmp;
  768. begin
  769. if not FMemBmpValid then
  770. begin
  771. DrawMemBmp;
  772. FMemBmpValid := True;
  773. end;
  774. end;
  775. procedure TCnWizardImage.Paint;
  776. begin
  777. inherited;
  778. CheckMemBmp;
  779. Bitblt(Canvas.Handle, 0, 0, Width, Height, FMemBmp.Canvas.Handle, 0, 0, SRCCOPY);
  780. end;
  781. procedure TCnWizardImage.SetItems(const Value: TCnWizardItems);
  782. begin
  783. FItems.Assign(Value);
  784. Changed;
  785. end;
  786. procedure TCnWizardImage.SetBoxColor(const Value: TColor);
  787. begin
  788. if FBoxColor <> Value then
  789. begin
  790. FBoxColor := Value;
  791. Changed;
  792. end;
  793. end;
  794. procedure TCnWizardImage.SetBoxHeight(const Value: Integer);
  795. begin
  796. if FBoxHeight <> Value then
  797. begin
  798. FBoxHeight := Value;
  799. Changed;
  800. end;
  801. end;
  802. procedure TCnWizardImage.SetBoxWidth(const Value: Integer);
  803. begin
  804. if FBoxWidth <> Value then
  805. begin
  806. FBoxWidth := Value;
  807. Changed;
  808. end;
  809. end;
  810. procedure TCnWizardImage.SetHorizontalSpace(const Value: Integer);
  811. begin
  812. if FHorizontalSpace <> Value then
  813. begin
  814. FHorizontalSpace := Value;
  815. Changed;
  816. end;
  817. end;
  818. procedure TCnWizardImage.SetLeftMargin(const Value: Integer);
  819. begin
  820. if Value <> FLeftMargin then
  821. begin
  822. FLeftMargin := Value;
  823. Changed;
  824. end;
  825. end;
  826. procedure TCnWizardImage.SetLineColor(const Value: TColor);
  827. begin
  828. if FLineColor <> Value then
  829. begin
  830. FLineColor := Value;
  831. Changed;
  832. end;
  833. end;
  834. procedure TCnWizardImage.SetSelectedBoxColor(const Value: TColor);
  835. begin
  836. if FSelectedBoxColor <> Value then
  837. begin
  838. FSelectedBoxColor := Value;
  839. Changed;
  840. end;
  841. end;
  842. procedure TCnWizardImage.SetTopMargin(const Value: Integer);
  843. begin
  844. if Value <> FTopMargin then
  845. begin
  846. FTopMargin := Value;
  847. Changed;
  848. end;
  849. end;
  850. procedure TCnWizardImage.SetTreeHeight(const Value: THeightRate);
  851. begin
  852. if FTreeHeight <> Value then
  853. begin
  854. FTreeHeight := Value;
  855. Changed;
  856. end;
  857. end;
  858. procedure TCnWizardImage.SetCommentFont(const Value: TFont);
  859. begin
  860. FCommentFont.Assign(Value);
  861. Changed;
  862. end;
  863. procedure TCnWizardImage.SetCommentHeight(const Value: THeightRate);
  864. begin
  865. if FCommentHeight <> Value then
  866. begin
  867. FCommentHeight := Value;
  868. Changed;
  869. end;
  870. end;
  871. procedure TCnWizardImage.SetTopColor(const Value: TColor);
  872. begin
  873. if FTopColor <> Value then
  874. begin
  875. FTopColor := Value;
  876. Changed;
  877. end;
  878. end;
  879. procedure TCnWizardImage.SetBottomColor(const Value: TColor);
  880. begin
  881. if FBottomColor <> Value then
  882. begin
  883. FBottomColor := Value;
  884. Changed;
  885. end;
  886. end;
  887. procedure TCnWizardImage.SetSelectedFont(const Value: TFont);
  888. begin
  889. FSelectedFont.Assign(Value);
  890. Changed;
  891. end;
  892. function TCnWizardImage.GetBackGround: TPicture;
  893. begin
  894. if not Assigned(FBackGround) then
  895. begin
  896. FBackGround := TPicture.Create;
  897. FBackGround.OnChange := Changed;
  898. end;
  899. Result := FBackGround;
  900. end;
  901. procedure TCnWizardImage.SetBackGround(const Value: TPicture);
  902. begin
  903. if not Assigned(Value) or not Assigned(Value.Graphic) or Value.Graphic.Empty then
  904. FreeAndNil(FBackGround)
  905. else
  906. BackGround.Assign(Value);
  907. Changed;
  908. end;
  909. procedure TCnWizardImage.SetBackGroundMode(const Value: TBackGroundMode);
  910. begin
  911. if FBackGroundMode <> Value then
  912. begin
  913. FBackGroundMode := Value;
  914. Changed;
  915. end;
  916. end;
  917. function TCnWizardImage.GetBackGroundTransparent: Boolean;
  918. begin
  919. Result := not BackEmpty;
  920. if Result then
  921. Result := FBackGround.Graphic.Transparent;
  922. end;
  923. procedure TCnWizardImage.SetBackGroundTransparent(const Value: Boolean);
  924. begin
  925. if not BackEmpty then
  926. FBackGround.Graphic.Transparent := Value;
  927. end;
  928. procedure TCnWizardImage.SetBackGroundX(const Value: Integer);
  929. begin
  930. if FBackGroundX <> Value then
  931. begin
  932. FBackGroundX := Value;
  933. Changed;
  934. end;
  935. end;
  936. procedure TCnWizardImage.SetBackGroundY(const Value: Integer);
  937. begin
  938. if FBackGroundY <> Value then
  939. begin
  940. FBackGroundY := Value;
  941. Changed;
  942. end;
  943. end;
  944. function TCnWizardImage.BackEmpty: Boolean;
  945. begin
  946. Result := not Assigned(FBackGround) or not Assigned(FBackGround.Graphic)
  947. or FBackGround.Graphic.Empty;
  948. end;
  949. end.