ListViewColProperties.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. unit ListViewColProperties;
  2. interface
  3. uses
  4. Classes, ComCtrls, Contnrs;
  5. type
  6. TCustomListViewColProperty = class(TObject)
  7. Alignment: TAlignment;
  8. Caption: string;
  9. Width: Integer;
  10. MaxWidth: Integer;
  11. MinWidth: Integer;
  12. Visible: Boolean;
  13. Order: Integer;
  14. constructor Create(AOrder: Integer);
  15. end;
  16. type
  17. TCustomListViewColProperties = class(TPersistent)
  18. private
  19. FChanged: Boolean;
  20. FOnChange: TNotifyEvent;
  21. FUpdating: Integer;
  22. FProperties: TObjectList;
  23. FCreated: Boolean;
  24. function GetColumns: TListColumns;
  25. function GetCount: Integer;
  26. function GetOrderStr: string;
  27. procedure CheckBounds(Index: Integer);
  28. procedure SetWidthsStr(Value: string; PixelsPerInch: Integer);
  29. function GetWidthsStr: string;
  30. procedure SetOrderStr(Value: string);
  31. protected
  32. FListView: TCustomListView;
  33. FListViewManaged: Boolean;
  34. FConstraintsInitialized: Boolean;
  35. function GetAlignments(Index: Integer): TAlignment;
  36. function GetParamsStr: string; virtual;
  37. function GetVisible(Index: Integer): Boolean;
  38. function GetWidths(Index: Integer): Integer;
  39. procedure SetAlignments(Index: Integer; Value: TAlignment);
  40. procedure SetVisibleInternal(Index: Integer; Value: Boolean; SaveWidth: Boolean);
  41. procedure SetVisible(Index: Integer; Value: Boolean);
  42. procedure SetWidths(Index: Integer; Value: Integer);
  43. function GetCaptions(Index: Integer): string;
  44. procedure Changed; virtual;
  45. procedure SetCaptions(Index: Integer; Value: string); virtual;
  46. procedure SetParamsStr(Value: string); virtual;
  47. procedure UpdateListView;
  48. procedure UpdateFromListView;
  49. procedure UpdateOrderFromListView;
  50. procedure UpdateListViewOrder;
  51. procedure UpdateListViewMaxMinWidth;
  52. function GetProperties(Index: Integer): TCustomListViewColProperty;
  53. function GetIndexByOrder(Order: Integer): Integer;
  54. function ColumnsExists: Boolean;
  55. procedure SetRuntimeVisible(Index: Integer; Value: Boolean; SaveWidth: Boolean);
  56. function GetColumn(Index: Integer): TListColumn;
  57. procedure CreateProperties(ACount: Integer);
  58. property Columns: TListColumns read GetColumns stored False;
  59. public
  60. constructor Create(ListView: TCustomListView; ColCount: Integer);
  61. destructor Destroy; override;
  62. procedure EndUpdate;
  63. procedure BeginUpdate;
  64. procedure ListViewWndCreated;
  65. procedure ListViewWndDestroying;
  66. procedure ListViewWndDestroyed;
  67. property Count: Integer read GetCount stored False;
  68. property Alignments[Index: Integer]: TAlignment read GetAlignments write SetAlignments;
  69. property Captions[Index: Integer]: string read GetCaptions write SetCaptions;
  70. property Widths[Index: Integer]: Integer read GetWidths write SetWidths;
  71. property Visible[Index: Integer]: Boolean read GetVisible write SetVisible;
  72. procedure RecreateColumns;
  73. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  74. property ParamsStr: string read GetParamsStr write SetParamsStr stored False;
  75. end; { TCustomListViewColProperties }
  76. type
  77. TListViewColProperties = class(TCustomListViewColProperties)
  78. published
  79. end; { TListViewColProperties }
  80. implementation
  81. uses
  82. SysUtils, CommCtrl, Windows, PasTools, Controls, Forms;
  83. const
  84. DefaultListViewMaxWidth = 1000;
  85. DefaultListViewMinWidth = 20;
  86. { TODO : V ListView zamezit zmenu velikosti neviditelnych sloupecku }
  87. constructor TCustomListViewColProperty.Create(AOrder: Integer);
  88. begin
  89. Alignment := taLeftJustify;
  90. Caption := '';
  91. Width := 50;
  92. Visible := True;
  93. Order := AOrder;
  94. end;
  95. { TCustomListViewColProperties }
  96. constructor TCustomListViewColProperties.Create(
  97. ListView: TCustomListView; ColCount: Integer);
  98. var
  99. ACount: Integer;
  100. begin
  101. // This contructor (and constructors of descendants)
  102. // is only even called from implementations of
  103. // TCustomNortonLikeListView.NewColProperties
  104. inherited Create;
  105. FConstraintsInitialized := False;
  106. FCreated := False;
  107. FUpdating := 0;
  108. FChanged := False;
  109. // ColCount is not 0 for file panels (TDirView and TCustomUnixDirView).
  110. // It is 0 otherwise.
  111. FListViewManaged := (ColCount = 0);
  112. FListView := ListView;
  113. FProperties := TObjectList.Create;
  114. if FListViewManaged then ACount := GetColumns.Count
  115. else ACount := ColCount;
  116. CreateProperties(ACount);
  117. if not Assigned(FListView) then
  118. raise Exception.Create('NIL ListView pointer.');
  119. end;
  120. destructor TCustomListViewColProperties.Destroy;
  121. begin
  122. inherited;
  123. FProperties.Free;
  124. end;
  125. procedure TCustomListViewColProperties.SetWidthsStr(Value: string; PixelsPerInch: Integer);
  126. var
  127. ColStr: string;
  128. Index: Integer;
  129. NeedInvalidate, NewVisible: Boolean;
  130. NewWidth: Integer;
  131. begin
  132. Index := 0;
  133. NeedInvalidate := False;
  134. BeginUpdate;
  135. try
  136. while (Value <> '') and (Index < Count) do
  137. begin
  138. ColStr := CutToChar(Value, ';', True);
  139. NewWidth := LoadDimension(StrToInt(CutToChar(ColStr, ',', True)), PixelsPerInch, FListView);
  140. Widths[Index] := NewWidth;
  141. NewVisible := Boolean(StrToInt(CutToChar(ColStr, ',', True)));
  142. if Visible[Index] <> NewVisible then
  143. begin
  144. // As we are within BeginUpdate guard, the width set just above is not propadated to WinAPI.
  145. // As reading width retrieves it from WinAPI (if the control is already allocated), we actually save wrong width.
  146. SetVisibleInternal(Index, NewVisible, False);
  147. NeedInvalidate := True;
  148. end;
  149. Inc(Index);
  150. end;
  151. finally
  152. EndUpdate;
  153. end;
  154. // When visibility changes (particularly while reseting layout) redraw is needed
  155. // (Invalidate is called in SetVisible too, but maybe it has no effect there, because it is within BeginUpdate/EndUpdate)
  156. if NeedInvalidate and FListView.HandleAllocated then
  157. FListView.Invalidate;
  158. end;
  159. function TCustomListViewColProperties.GetWidthsStr: string;
  160. var
  161. Index: Integer;
  162. begin
  163. Result := '';
  164. for Index := 0 to Count-1 do
  165. begin
  166. Result := Format('%s;%d,%d', [Result, SaveDimension(Widths[Index]), Integer(Visible[Index])]);
  167. end;
  168. Delete(Result, 1, 1);
  169. end;
  170. procedure TCustomListViewColProperties.BeginUpdate;
  171. begin
  172. Columns.BeginUpdate;
  173. Inc(FUpdating);
  174. end;
  175. procedure TCustomListViewColProperties.EndUpdate;
  176. begin
  177. Columns.EndUpdate;
  178. Dec(FUpdating);
  179. if FUpdating = 0 then
  180. begin
  181. // call Changed() even when FChange is false
  182. Changed;
  183. FChanged := False;
  184. end;
  185. end;
  186. procedure TCustomListViewColProperties.Changed;
  187. begin
  188. if FUpdating > 0 then FChanged := True
  189. else
  190. if Assigned(FOnChange) then FOnChange(Self);
  191. end;
  192. procedure TCustomListViewColProperties.CheckBounds(Index: Integer);
  193. begin
  194. if (Index < 0) or (Index >= Count) then
  195. raise Exception.Create('Index out of bounds.');
  196. end;
  197. function TCustomListViewColProperties.GetProperties(Index: Integer): TCustomListViewColProperty;
  198. begin
  199. Result := TCustomListViewColProperty(FProperties.Items[Index]);
  200. end;
  201. function TCustomListViewColProperties.GetIndexByOrder(Order: Integer): Integer;
  202. var
  203. I: Integer;
  204. begin
  205. for I := 0 to Count - 1 do
  206. begin
  207. if GetProperties(I).Order = Order then
  208. begin
  209. Result := I;
  210. Exit;
  211. end;
  212. end;
  213. raise Exception.Create('Column order out of bounds');
  214. end;
  215. function TCustomListViewColProperties.ColumnsExists: Boolean;
  216. begin
  217. Result := FListView.HandleAllocated;
  218. if Result and (not FCreated) and (not FListViewManaged) then
  219. UpdateListView;
  220. end;
  221. procedure TCustomListViewColProperties.SetAlignments(Index: Integer; Value: TAlignment);
  222. begin
  223. CheckBounds(Index);
  224. if Alignments[Index] <> Value then
  225. begin
  226. GetProperties(Index).Alignment := Value;
  227. if ColumnsExists then GetColumn(Index).Alignment := Value;
  228. Changed;
  229. end;
  230. end;
  231. procedure TCustomListViewColProperties.SetCaptions(Index: Integer; Value: string);
  232. begin
  233. CheckBounds(Index);
  234. if Captions[Index] <> Value then
  235. begin
  236. if ColumnsExists then GetColumn(Index).Caption := Value
  237. else GetProperties(Index).Caption := Value;
  238. Changed;
  239. end;
  240. end;
  241. function TCustomListViewColProperties.GetAlignments(Index: Integer): TAlignment;
  242. begin
  243. CheckBounds(Index);
  244. if ColumnsExists then Result := GetColumn(Index).Alignment
  245. else Result := GetProperties(Index).Alignment;
  246. end;
  247. function TCustomListViewColProperties.GetCaptions(Index: Integer): string;
  248. begin
  249. CheckBounds(Index);
  250. if ColumnsExists then Result := GetColumn(Index).Caption
  251. else Result := GetProperties(Index).Caption;
  252. end;
  253. procedure TCustomListViewColProperties.SetOrderStr(Value: string);
  254. var
  255. Order, Index: Integer;
  256. Properties: TCustomListViewColProperty;
  257. STemp: string;
  258. Phase: Boolean;
  259. begin
  260. BeginUpdate;
  261. try
  262. for Index := 0 to Count - 1 do
  263. GetProperties(Index).Order := -1;
  264. // First order invisible columns (not True), then visible (not not True)
  265. Phase := True;
  266. Order := 0;
  267. repeat
  268. Phase := not Phase;
  269. STemp := Value;
  270. while (STemp <> '') and (Order < Count) do
  271. begin
  272. Index := StrToInt(CutToChar(STemp, ';', True));
  273. Properties := GetProperties(Index);
  274. if (Properties.Visible = Phase) and
  275. (Properties.Order < 0) { robustness } then
  276. begin
  277. Properties.Order := Order;
  278. Inc(Order);
  279. end;
  280. end;
  281. // add missing columns from the same visibility class
  282. for Index := 0 to Count - 1 do
  283. begin
  284. Properties := GetProperties(Index);
  285. if (Properties.Visible = Phase) and
  286. (Properties.Order < 0) then
  287. begin
  288. Properties.Order := Order;
  289. Inc(Order);
  290. end;
  291. end;
  292. until Phase;
  293. if ColumnsExists then
  294. UpdateListViewOrder;
  295. finally
  296. EndUpdate;
  297. end;
  298. end;
  299. procedure TCustomListViewColProperties.SetParamsStr(Value: string);
  300. var
  301. S: string;
  302. WidthsStr: string;
  303. OrderStr: string;
  304. PixelsPerInch: Integer;
  305. begin
  306. // TFileFindDialog uses / as separator of its settings
  307. S := CutToChar(Value, '|', True);
  308. WidthsStr := CutToChar(S, '@', True);
  309. PixelsPerInch := LoadPixelsPerInch(S, FListView);
  310. SetWidthsStr(WidthsStr, PixelsPerInch);
  311. // Have to set order after visibility, otherwise we lost ordering of columns that are invisible by default,
  312. // but visible by configuration (as they would get ordered to the front)
  313. OrderStr := CutToChar(Value, '|', True);
  314. SetOrderStr(OrderStr);
  315. end;
  316. procedure TCustomListViewColProperties.SetVisibleInternal(Index: Integer; Value: Boolean; SaveWidth: Boolean);
  317. var
  318. I: Integer;
  319. Properties: TCustomListViewColProperty;
  320. begin
  321. CheckBounds(Index);
  322. if Visible[Index] <> Value then
  323. begin
  324. Properties := GetProperties(Index);
  325. if ColumnsExists then
  326. UpdateOrderFromListView;
  327. if Value then
  328. begin
  329. // shown column is moved to the back
  330. for I := 0 to Count - 1 do
  331. begin
  332. if GetProperties(I).Order > Properties.Order then
  333. Dec(GetProperties(I).Order);
  334. end;
  335. Properties.Order := Count - 1;
  336. if ColumnsExists then
  337. UpdateListViewOrder;
  338. // show only after reordering column
  339. Properties.Visible := True;
  340. if ColumnsExists then
  341. SetRuntimeVisible(Index, True, SaveWidth);
  342. end
  343. else
  344. begin
  345. // hide before reordering column
  346. Properties.Visible := False;
  347. if ColumnsExists then
  348. SetRuntimeVisible(Index, False, SaveWidth);
  349. // hidden column is moved to the front,
  350. // unless column to the left is not hidden already
  351. // (or unless it is first already, in which case the
  352. // condition in the loop is never satisfied)
  353. if (Properties.Order > 0) and
  354. GetProperties(GetIndexByOrder(Properties.Order - 1)).Visible then
  355. begin
  356. for I := 0 to Count - 1 do
  357. begin
  358. if GetProperties(I).Order < Properties.Order then
  359. Inc(GetProperties(I).Order);
  360. end;
  361. Properties.Order := 0;
  362. end;
  363. if ColumnsExists then
  364. UpdateListViewOrder;
  365. end;
  366. Changed;
  367. // It does not refresh itself at last one on Win7 when DoubleBuffered
  368. if FListView.HandleAllocated then
  369. FListView.Invalidate;
  370. end;
  371. end;
  372. procedure TCustomListViewColProperties.SetVisible(Index: Integer; Value: Boolean);
  373. begin
  374. SetVisibleInternal(Index, Value, True);
  375. end;
  376. procedure TCustomListViewColProperties.SetRuntimeVisible(
  377. Index: Integer; Value: Boolean; SaveWidth: Boolean);
  378. var
  379. Properties: TCustomListViewColProperty;
  380. begin
  381. // This is probably only ever called from file panels (DirViews)
  382. // as other uses ("sychronization checklist" and "file find")
  383. // have FListViewManaged = False and never change Visible property
  384. // (though user can hide some columns manually in configuration storage)
  385. with GetColumn(Index) do
  386. begin
  387. Properties := GetProperties(Index);
  388. if Value then
  389. begin
  390. MaxWidth := Properties.MaxWidth;
  391. MinWidth := Properties.MinWidth;
  392. Width := Properties.Width;
  393. end
  394. else
  395. begin
  396. if SaveWidth then
  397. Properties.Width := Width;
  398. MaxWidth := 1;
  399. MinWidth := 0;
  400. Width := 0
  401. end;
  402. end;
  403. end;
  404. procedure TCustomListViewColProperties.SetWidths(Index: Integer; Value: Integer);
  405. var
  406. Properties: TCustomListViewColProperty;
  407. begin
  408. CheckBounds(Index);
  409. Properties := GetProperties(Index);
  410. if (Properties.MinWidth > 0) and (Value < Properties.MinWidth) then
  411. begin
  412. Value := Properties.MinWidth;
  413. end
  414. else
  415. if (Properties.MaxWidth > 0) and (Value > Properties.MaxWidth) then
  416. begin
  417. Value := Properties.MaxWidth;
  418. end;
  419. if Widths[Index] <> Value then
  420. begin
  421. Properties.Width := Value;
  422. if ColumnsExists and Visible[Index] then GetColumn(Index).Width := Value;
  423. Changed;
  424. end;
  425. end;
  426. function TCustomListViewColProperties.GetColumns: TListColumns;
  427. begin
  428. Result := TListView(FListView).Columns;
  429. end;
  430. function TCustomListViewColProperties.GetColumn(Index: Integer): TListColumn;
  431. begin
  432. Result := Columns[Index];
  433. end;
  434. function TCustomListViewColProperties.GetCount: Integer;
  435. begin
  436. Result := FProperties.Count;
  437. end;
  438. function TCustomListViewColProperties.GetOrderStr: string;
  439. var
  440. Index: Integer;
  441. begin
  442. Result := '';
  443. if ColumnsExists then
  444. UpdateOrderFromListView;
  445. for Index := 0 to Count - 1 do
  446. Result := Format('%s;%d', [Result, GetIndexByOrder(Index)]);
  447. Delete(Result, 1, 1);
  448. end;
  449. function TCustomListViewColProperties.GetParamsStr: string;
  450. begin
  451. // WORKAROUND
  452. // Adding an additional semicolon after the list,
  453. // to ensure that old versions that did not expect the pixels-per-inch part,
  454. // stop at the semicolon, otherwise they try to parse the
  455. // "last-column-width|pixels-per-inch" as integer and throw.
  456. // For the other instance of this hack, see GetListViewStr.
  457. // The new pixels-per-inch part is inserted after the widths part
  458. // as parsing of this was always robust to stop at "count" elements,
  459. // what order part was not (due to its logic of skipping hidden columns)
  460. Result := Format('%s;@%s|%s', [GetWidthsStr, SavePixelsPerInch(FListView), GetOrderStr]);
  461. end;
  462. function TCustomListViewColProperties.GetVisible(Index: Integer): Boolean;
  463. begin
  464. CheckBounds(Index);
  465. Result := GetProperties(Index).Visible;
  466. end;
  467. function TCustomListViewColProperties.GetWidths(Index: Integer): Integer;
  468. begin
  469. CheckBounds(Index);
  470. if ColumnsExists and Visible[Index] then
  471. begin
  472. Result := GetColumn(Index).Width;
  473. end
  474. else
  475. begin
  476. Result := GetProperties(Index).Width;
  477. end;
  478. end;
  479. procedure TCustomListViewColProperties.RecreateColumns;
  480. var
  481. Copy: TListColumns;
  482. begin
  483. Copy := TListColumns.Create(nil);
  484. try
  485. Copy.Assign(Columns);
  486. Columns.Assign(Copy);
  487. finally
  488. Copy.Free;
  489. end;
  490. end;
  491. procedure TCustomListViewColProperties.CreateProperties(ACount: Integer);
  492. var
  493. Index: Integer;
  494. Properties: TCustomListViewColProperty;
  495. begin
  496. for Index := 0 to ACount - 1 do
  497. begin
  498. Properties := TCustomListViewColProperty.Create(Index);
  499. FProperties.Add(Properties);
  500. end;
  501. end;
  502. procedure TCustomListViewColProperties.ListViewWndCreated;
  503. var
  504. Index: Integer;
  505. Properties: TCustomListViewColProperty;
  506. Column: TListColumn;
  507. W: Integer;
  508. begin
  509. if FListViewManaged then
  510. begin
  511. if (FProperties.Count = 0) and (Columns.Count > 0) then
  512. CreateProperties(Columns.Count);
  513. UpdateFromListView;
  514. end
  515. else
  516. begin
  517. UpdateListView;
  518. end;
  519. if not FConstraintsInitialized then
  520. begin
  521. FConstraintsInitialized := True;
  522. for Index := 0 to Count - 1 do
  523. begin
  524. Column := GetColumn(Index);
  525. Properties := GetProperties(Index);
  526. // Is this branching needed?
  527. if Properties.Visible then
  528. begin
  529. W := Column.MaxWidth;
  530. if W = 0 then W := DefaultListViewMaxWidth;
  531. Properties.MaxWidth := ScaleByTextHeight(FListView, W);
  532. W := Column.MinWidth;
  533. if W = 0 then W := DefaultListViewMinWidth;
  534. Properties.MinWidth := ScaleByTextHeight(FListView, W);
  535. end
  536. else
  537. begin
  538. Column.MaxWidth := ScaleByTextHeight(FListView, Column.MaxWidth);
  539. Column.MinWidth := ScaleByTextHeight(FListView, Column.MinWidth);
  540. end;
  541. end;
  542. end;
  543. // To apply the default constraints to columns that do not have their own
  544. UpdateListViewMaxMinWidth;
  545. end;
  546. procedure TCustomListViewColProperties.ListViewWndDestroying;
  547. begin
  548. UpdateFromListView;
  549. end;
  550. procedure TCustomListViewColProperties.ListViewWndDestroyed;
  551. begin
  552. if not FListViewManaged then
  553. FCreated := False;
  554. end;
  555. procedure TCustomListViewColProperties.UpdateListViewOrder;
  556. var
  557. Index: Integer;
  558. Properties: TCustomListViewColProperty;
  559. Temp: array of Integer;
  560. begin
  561. SetLength(Temp, Count);
  562. // Seemingly useless,
  563. // but probably only because we swallow HDN_ENDDRAG in TCustomIEListView.WMNotify,
  564. // what prevents VLC from actually reordering columns collection
  565. ListView_GetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
  566. for Index := 0 to Count - 1 do
  567. begin
  568. Properties := GetProperties(Index);
  569. Temp[Properties.Order] := Index;
  570. end;
  571. ListView_SetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
  572. end;
  573. procedure TCustomListViewColProperties.UpdateListViewMaxMinWidth;
  574. var
  575. Index: Integer;
  576. Column: TListColumn;
  577. Properties: TCustomListViewColProperty;
  578. begin
  579. Assert(ColumnsExists);
  580. for Index := 0 to Count-1 do
  581. begin
  582. Column := GetColumn(Index);
  583. Properties := GetProperties(Index);
  584. if Properties.Visible then
  585. begin
  586. Column.MaxWidth := Properties.MaxWidth;
  587. if Column.Width > Column.MaxWidth then Column.Width := Column.MaxWidth;
  588. Column.MinWidth := Properties.MinWidth;
  589. if Column.Width < Column.MinWidth then Column.Width := Column.MinWidth;
  590. end;
  591. end;
  592. end;
  593. procedure TCustomListViewColProperties.UpdateListView;
  594. var
  595. Index: Integer;
  596. Column: TListColumn;
  597. Properties: TCustomListViewColProperty;
  598. begin
  599. // Only called when FListViewManaged = False
  600. BeginUpdate;
  601. try
  602. for Index := 0 to Count-1 do
  603. begin
  604. if Index < Columns.Count then
  605. Column := GetColumn(Index)
  606. else
  607. Column := Columns.Add;
  608. Properties := GetProperties(Index);
  609. Column.Alignment := Properties.Alignment;
  610. Column.Caption := Properties.Caption;
  611. SetRuntimeVisible(Index, Properties.Visible, False);
  612. end;
  613. UpdateListViewOrder;
  614. finally
  615. FCreated := True;
  616. EndUpdate;
  617. end;
  618. end;
  619. procedure TCustomListViewColProperties.UpdateOrderFromListView;
  620. var
  621. Index: Integer;
  622. Temp: array of Integer;
  623. begin
  624. SetLength(Temp, Count);
  625. ListView_GetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
  626. for Index := 0 to Count - 1 do
  627. begin
  628. GetProperties(Temp[Index]).Order := Index;
  629. end;
  630. end;
  631. procedure TCustomListViewColProperties.UpdateFromListView;
  632. var
  633. Index: Integer;
  634. Column: TListColumn;
  635. Properties: TCustomListViewColProperty;
  636. begin
  637. Assert(FProperties.Count = Columns.Count);
  638. for Index := 0 to Count-1 do
  639. begin
  640. Column := GetColumn(Index);
  641. Properties := GetProperties(Index);
  642. Properties.Alignment := Column.Alignment;
  643. Properties.Caption := Column.Caption;
  644. if Properties.Visible then
  645. begin
  646. Properties.Width := Column.Width;
  647. if Column.MaxWidth > 0 then
  648. Properties.MaxWidth := Column.MaxWidth;
  649. if Column.MinWidth > 0 then
  650. Properties.MinWidth := Column.MinWidth;
  651. end;
  652. end;
  653. UpdateOrderFromListView;
  654. end;
  655. end.