1
0

ListViewColProperties.pas 20 KB

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