IEListView.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. unit IEListView;
  2. {==================================================================
  3. Component TCustomIEListView / Version 1.0, September 1999
  4. ==================================================================
  5. Description:
  6. ============
  7. Basic component for TDirView.
  8. Author:
  9. =======
  10. (c) Ingo Eckel 1999
  11. Sodener Weg 38
  12. 65812 Bad Soden
  13. Germany
  14. (c) Martin Prikryl 2001 - 2003
  15. For detailed documentation see the documentation of TDirView.
  16. ==================================================================}
  17. {Required compiler options for TCustomIEListView:}
  18. {$A+,B-,X+,H+,P+}
  19. interface
  20. uses
  21. Windows, Messages, SysUtils, Classes, Graphics, Controls,
  22. Forms, ActiveX, CommCtrl, Extctrls, ImgList,
  23. ComCtrls, NortonLikeListView, ListViewColProperties;
  24. type
  25. TIEListViewColProperties = class(TCustomListViewColProperties)
  26. protected
  27. function GetSortAscending: Boolean;
  28. procedure SetSortColumn(Value: Integer);
  29. function GetSortColumn: Integer;
  30. function GetSortStr: string; virtual;
  31. procedure SetSortAscending(Value: Boolean);
  32. procedure SetSortStr(Value: string); virtual;
  33. function GetParamsStr: string; override;
  34. procedure SetParamsStr(Value: string); override;
  35. public
  36. constructor Create(ListView: TCustomListView; ColCount: Integer);
  37. property SortAscending: Boolean read GetSortAscending write SetSortAscending default True;
  38. property SortColumn: Integer read GetSortColumn write SetSortColumn;
  39. property SortStr: string read GetSortStr write SetSortStr stored False;
  40. end;
  41. type
  42. TCustomIEListView = class;
  43. TListViewSecondaryColumnHeaderEvent =
  44. procedure(Sender: TCustomIEListView; Index: Integer; var SecondaryColumn: Integer) of object;
  45. TCustomIEListView = class(TCustomNortonLikeListView)
  46. private
  47. FSortColumn: Integer;
  48. FSortAscending: Boolean;
  49. FShowColumnIcon: Boolean;
  50. FParentForm: TCustomForm;
  51. FOnHeaderEndDrag: TNotifyEvent;
  52. FOnHeaderEndTrack: TNotifyEvent;
  53. FOnRecreate: TNotifyEvent;
  54. FOnSecondaryColumnHeader: TListViewSecondaryColumnHeaderEvent;
  55. FDragImageList: TDragImageList;
  56. protected
  57. procedure ColPropertiesChange(Sender: TObject); virtual;
  58. procedure SetShowColumnIcon(Value: Boolean); virtual;
  59. procedure SetSortColumn(Value: Integer); virtual;
  60. procedure SetSortAscending(Value: Boolean); virtual;
  61. procedure SortItems; virtual;
  62. procedure SetViewStyle(Value: TViewStyle); override; // CLEAN virtual
  63. procedure HeaderEndDrag(Sender: TObject); virtual;
  64. function SecondaryColumnHeader(Index: Integer): Integer;
  65. function NewColProperties: TCustomListViewColProperties; override;
  66. function SortAscendingByDefault(Index: Integer): Boolean; virtual;
  67. procedure CreateWnd; override;
  68. procedure ColClick(Column: TListColumn); override;
  69. procedure SetSort(Column: Integer; Ascending: Boolean);
  70. procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY;
  71. procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
  72. public
  73. constructor Create(AOwner: TComponent); override;
  74. destructor Destroy; override;
  75. procedure SetColumnImages; virtual;
  76. procedure SortBy(Column: Integer);
  77. property DragImageList: TDragImageList read FDragImageList;
  78. property ParentForm: TCustomForm read FParentForm;
  79. {Set the sort column of the listview}
  80. property SortColumn: Integer read FSortColumn write SetSortColumn;
  81. {Sortorder of actual sort column}
  82. property SortAscending: Boolean
  83. read FSortAscending write SetSortAscending default True;
  84. property OnSecondaryColumnHeader: TListViewSecondaryColumnHeaderEvent
  85. read FOnSecondaryColumnHeader write FOnSecondaryColumnHeader;
  86. published
  87. property OnHeaderEndDrag: TNotifyEvent
  88. read FOnHeaderEndDrag write FOnHeaderEndDrag;
  89. property OnHeaderEndTrack: TNotifyEvent
  90. read FOnHeaderEndTrack write FOnHeaderEndTrack;
  91. property OnRecreate: TNotifyEvent
  92. read FOnRecreate write FOnRecreate;
  93. {Show the sorting symbol in the listview's header:}
  94. property ShowColumnIcon: Boolean
  95. read FShowColumnIcon write SetShowColumnIcon default True;
  96. property Align;
  97. property AllocBy;
  98. property Anchors;
  99. property BiDiMode;
  100. property BorderStyle;
  101. property BorderWidth;
  102. property Checkboxes;
  103. property Color;
  104. property ColumnClick default True;
  105. property Constraints;
  106. property Ctl3D;
  107. property DoubleBuffered;
  108. property Enabled;
  109. property Font;
  110. property FlatScrollBars;
  111. property FullDrag;
  112. property GridLines;
  113. property HideSelection;
  114. property HotTrack;
  115. property HotTrackStyles;
  116. property IconOptions;
  117. property ReadOnly default False;
  118. property RowSelect;
  119. property ParentBiDiMode;
  120. property ParentColor default False;
  121. property ParentDoubleBuffered;
  122. property ParentFont;
  123. property ParentShowHint;
  124. property PopupMenu;
  125. property ShowColumnHeaders;
  126. property ShowHint;
  127. property TabOrder;
  128. property TabStop default True;
  129. property Visible;
  130. property OnChange;
  131. property OnChanging;
  132. property OnClick;
  133. property OnColumnClick;
  134. property OnColumnRightClick;
  135. property OnCustomDraw;
  136. property OwnerDraw;
  137. {Used for internal purposes:}
  138. property OnCustomDrawItem;
  139. property OnCustomDrawSubItem;
  140. property OnDblClick;
  141. property OnDeletion;
  142. property OnDrawItem;
  143. property OnEdited;
  144. property OnEditing;
  145. property OnEndDock;
  146. property OnEnter;
  147. property OnExit;
  148. property OnInsert;
  149. property OnKeyDown;
  150. property OnKeyPress;
  151. property OnKeyUp;
  152. property OnMouseDown;
  153. property OnMouseMove;
  154. property OnMouseUp;
  155. property OnResize;
  156. property OnStartDock;
  157. property NortonLike;
  158. end; {Type TCustomIEListView}
  159. type
  160. TIEListView = class(TCustomIEListView)
  161. published
  162. // copy from TListView, except for marked items
  163. property Action;
  164. property Align;
  165. property AllocBy;
  166. property Anchors;
  167. property BevelEdges;
  168. property BevelInner;
  169. property BevelOuter;
  170. property BevelKind default bkNone;
  171. property BevelWidth;
  172. property BiDiMode;
  173. property BorderStyle;
  174. property BorderWidth;
  175. property Checkboxes;
  176. property Color;
  177. property Columns;
  178. property ColumnClick;
  179. property Constraints;
  180. property Ctl3D;
  181. property DragCursor;
  182. property DragKind;
  183. property DragMode;
  184. property Enabled;
  185. property Font;
  186. property FlatScrollBars;
  187. property FullDrag;
  188. property GridLines;
  189. property HideSelection;
  190. property HotTrack;
  191. property HotTrackStyles;
  192. property HoverTime;
  193. property IconOptions;
  194. property Items;
  195. property LargeImages;
  196. property MultiSelect;
  197. property OwnerData;
  198. property OwnerDraw;
  199. property ReadOnly default False;
  200. property RowSelect;
  201. property ParentBiDiMode;
  202. property ParentColor default False;
  203. property ParentFont;
  204. property ParentShowHint;
  205. property PopupMenu;
  206. property ShowColumnHeaders;
  207. property ShowWorkAreas;
  208. property ShowHint;
  209. property SmallImages;
  210. property SortType;
  211. property StateImages;
  212. property TabOrder;
  213. property TabStop default True;
  214. property ViewStyle;
  215. property Visible;
  216. property OnAdvancedCustomDraw;
  217. property OnAdvancedCustomDrawItem;
  218. property OnAdvancedCustomDrawSubItem;
  219. property OnChange;
  220. property OnChanging;
  221. property OnClick;
  222. property OnColumnClick;
  223. property OnColumnDragged;
  224. property OnColumnRightClick;
  225. property OnCompare;
  226. property OnContextPopup;
  227. property OnCustomDraw;
  228. property OnCustomDrawItem;
  229. property OnCustomDrawSubItem;
  230. property OnData;
  231. property OnDataFind;
  232. property OnDataHint;
  233. property OnDataStateChange;
  234. property OnDblClick;
  235. property OnDeletion;
  236. property OnDrawItem;
  237. property OnEdited;
  238. property OnEditing;
  239. property OnEndDock;
  240. property OnEndDrag;
  241. property OnEnter;
  242. property OnExit;
  243. property OnGetImageIndex;
  244. property OnGetSubItemImage;
  245. property OnDragDrop;
  246. property OnDragOver;
  247. property OnInfoTip;
  248. property OnInsert;
  249. property OnKeyDown;
  250. property OnKeyPress;
  251. property OnKeyUp;
  252. property OnMouseDown;
  253. property OnMouseMove;
  254. property OnMouseUp;
  255. property OnResize;
  256. property OnSelectItem;
  257. property OnStartDock;
  258. property OnStartDrag;
  259. property OnSecondaryColumnHeader; // TCustomIEListView
  260. end;
  261. var
  262. GlobalDragImageList: TDragImageList;
  263. procedure Register;
  264. implementation
  265. uses
  266. PasTools, Types;
  267. procedure Register;
  268. begin
  269. RegisterComponents('Martin', [TIEListView]);
  270. end;
  271. { TIEListViewColProperties }
  272. constructor TIEListViewColProperties.Create(ListView: TCustomListView; ColCount: Integer);
  273. begin
  274. inherited;
  275. end;
  276. procedure TIEListViewColProperties.SetParamsStr(Value: string);
  277. begin
  278. SortStr := CutToChar(Value, '|', True);
  279. inherited SetParamsStr(Value);
  280. end;
  281. procedure TIEListViewColProperties.SetSortAscending(Value: Boolean);
  282. begin
  283. TCustomIEListView(FListView).SortAscending := Value;
  284. end;
  285. procedure TIEListViewColProperties.SetSortColumn(Value: Integer);
  286. begin
  287. if SortColumn <> Value then
  288. begin
  289. TCustomIEListView(FListView).SortColumn := Value;
  290. Changed;
  291. end;
  292. end;
  293. function TIEListViewColProperties.GetParamsStr: string;
  294. begin
  295. Result := Format('%s|%s', [SortStr, inherited GetParamsStr]);
  296. end;
  297. function TIEListViewColProperties.GetSortAscending: Boolean;
  298. begin
  299. Result := TCustomIEListView(FListView).SortAscending;
  300. end;
  301. function TIEListViewColProperties.GetSortColumn: Integer;
  302. begin
  303. Result := TCustomIEListView(FListView).SortColumn;
  304. end;
  305. procedure TIEListViewColProperties.SetSortStr(Value: string);
  306. var
  307. ASortColumn: Integer;
  308. begin
  309. ASortColumn := StrToIntDef(CutToChar(Value, ';', True), SortColumn);
  310. if ASortColumn < Count then SortColumn := ASortColumn;
  311. SortAscending := Boolean(StrToIntDef(CutToChar(Value, ';', True), Integer(SortAscending)));
  312. end;
  313. function TIEListViewColProperties.GetSortStr: string;
  314. begin
  315. Result := Format('%d;%d', [SortColumn, Integer(SortAscending)]);
  316. end;
  317. { TCustomIEListView }
  318. constructor TCustomIEListView.Create(AOwner: TComponent);
  319. begin
  320. inherited;
  321. ColProperties.OnChange := ColPropertiesChange;
  322. FShowColumnIcon := True;
  323. FSortColumn := 0;
  324. FSortAscending := True;
  325. end; {Create}
  326. procedure TCustomIEListView.SetSort(Column: Integer; Ascending: Boolean);
  327. begin
  328. if (SortColumn <> Column) or (SortAscending <> Ascending) then
  329. begin
  330. FSortColumn := Column;
  331. FSortAscending := Ascending;
  332. if Items.Count > 0 then SortItems;
  333. SetColumnImages;
  334. end;
  335. end;
  336. procedure TCustomIEListView.SortBy(Column: Integer);
  337. begin
  338. if Column = SortColumn then SetSort(SortColumn, not SortAscending)
  339. else SetSort(Column, SortAscendingByDefault(Column));
  340. end;
  341. procedure TCustomIEListView.SetSortColumn(Value: Integer);
  342. begin
  343. SetSort(Value, True);
  344. end; {SetSortColumn}
  345. procedure TCustomIEListView.SetViewStyle(Value: TViewStyle);
  346. begin
  347. if Value <> ViewStyle then
  348. begin
  349. inherited SetViewStyle(Value);
  350. if ViewStyle = vsReport then
  351. SetColumnImages;
  352. end;
  353. end; {SetViewStyle}
  354. procedure TCustomIEListView.SetSortAscending(Value: Boolean);
  355. begin
  356. SetSort(SortColumn, Value);
  357. end; {SetSortAscending}
  358. procedure TCustomIEListView.SetColumnImages;
  359. var
  360. HdItem: THdItem;
  361. Index: Integer;
  362. SecondaryColumn: Integer;
  363. ShowImage: Boolean;
  364. NewFmt: Integer;
  365. begin
  366. if ShowColumnHeaders and HandleAllocated then
  367. begin
  368. for Index := 0 to Columns.Count-1 do
  369. begin
  370. HdItem.Mask := HDI_FORMAT;
  371. Header_GetItem(FHeaderHandle, Index, HdItem);
  372. SecondaryColumn := SecondaryColumnHeader(Index);
  373. ShowImage := False;
  374. if FShowColumnIcon then
  375. begin
  376. if (Index = SortColumn) or
  377. ((SecondaryColumn >= 0) and (SecondaryColumn = SortColumn)) then
  378. begin
  379. ShowImage := True;
  380. end;
  381. end;
  382. // for hidden columns, do not show the icon
  383. // as on some systems it is still drawn, but on neighboring columns
  384. if ShowImage and (Columns[Index].Width > 0) then
  385. begin
  386. if SortAscending then
  387. begin
  388. NewFmt := (Hditem.fmt or HDF_SORTUP) and (not HDF_SORTDOWN);
  389. end
  390. else
  391. begin
  392. NewFmt := (Hditem.fmt or HDF_SORTDOWN) and (not HDF_SORTUP);
  393. end;
  394. end
  395. else
  396. begin
  397. NewFmt := HdItem.fmt and (not (HDF_SORTUP or HDF_SORTDOWN));
  398. end;
  399. if NewFmt <> HdItem.fmt then
  400. begin
  401. HdItem.Mask := HDI_FORMAT;
  402. HdItem.fmt := NewFmt;
  403. Header_SetItem(FHeaderHandle, Index, HDItem);
  404. end;
  405. end;
  406. end;
  407. end; {SetColumnImage}
  408. procedure TCustomIEListView.SetShowColumnIcon(Value: Boolean);
  409. begin
  410. if Value <> ShowColumnIcon then
  411. begin
  412. FShowColumnIcon := Value;
  413. SetColumnImages;
  414. end;
  415. end; {SetShowColumnIcon}
  416. function TCustomIEListView.SecondaryColumnHeader(Index: Integer): Integer;
  417. begin
  418. if Assigned(OnSecondaryColumnHeader) then
  419. begin
  420. OnSecondaryColumnHeader(Self, Index, Result);
  421. end
  422. else
  423. begin
  424. Result := -1;
  425. end;
  426. end;
  427. function TCustomIEListView.NewColProperties: TCustomListViewColProperties;
  428. begin
  429. Result := TIEListViewColProperties.Create(Self, 0);
  430. end;
  431. function TCustomIEListView.SortAscendingByDefault(Index: Integer): Boolean;
  432. begin
  433. Result := True;
  434. end;
  435. procedure TCustomIEListView.ColClick(Column: TListColumn);
  436. begin
  437. SortBy(Column.Index);
  438. inherited;
  439. end; {ColClick}
  440. procedure TCustomIEListView.WMNotify(var Msg: TWMNotify);
  441. begin
  442. if (FHeaderHandle <> 0) and (Msg.NMHdr^.hWndFrom = FHeaderHandle) then
  443. case Msg.NMHdr.code of
  444. HDN_BEGINDRAG:
  445. begin
  446. // We probably do not need to eat this message anymore,
  447. // we let's keep it in sync with HDN_ENDDRAG (see comment there)
  448. end;
  449. HDN_ENDDRAG:
  450. begin
  451. // Originally the code to eat this message was here to
  452. // workaround bug in D4 (until Update Pack 3).
  453. // But when we pass the message to VCL, it reorders
  454. // columns in Columns collection, what our code does not handle.
  455. // See also comment in TCustomListViewColProperties.UpdateListViewOrder
  456. HeaderEndDrag(Self);
  457. Invalidate;
  458. Exit;
  459. end;
  460. HDN_ENDTRACKA, HDN_ENDTRACKW:
  461. begin
  462. SetColumnImages;
  463. Invalidate;
  464. inherited;
  465. if Assigned(FOnHeaderEndTrack) then
  466. FOnHeaderEndTrack(Self);
  467. Exit;
  468. end;
  469. HDN_DIVIDERDBLCLICKA, HDN_DIVIDERDBLCLICKW:
  470. begin
  471. inherited;
  472. if Assigned(FOnHeaderEndTrack) then
  473. FOnHeaderEndTrack(Self);
  474. SetColumnImages;
  475. end;
  476. end;
  477. inherited;
  478. end; { TCustomIEListView.WMNotify }
  479. // Might not be always called, see comment in TDriveView.DestroyWnd
  480. procedure TCustomIEListView.CMRecreateWnd(var Message: TMessage);
  481. begin
  482. inherited;
  483. if Assigned(OnRecreate) then OnRecreate(Self);
  484. end;
  485. procedure TCustomIEListView.HeaderEndDrag(Sender : TObject);
  486. begin
  487. if Assigned(FOnHeaderEndDrag) then
  488. FOnHeaderEndDrag(Self);
  489. end; {HeaderEndDrag}
  490. procedure TCustomIEListView.ColPropertiesChange(Sender: TObject);
  491. begin
  492. SetColumnImages;
  493. end;
  494. procedure TCustomIEListView.CreateWnd;
  495. begin
  496. inherited;
  497. FParentForm := GetParentForm(Self);
  498. if not (csDesigning in ComponentState) then
  499. FDragImageList := TDragImageList.Create(Self);
  500. if not Assigned(GlobalDragImageList) then
  501. GlobalDragImageList := DragImageList;
  502. SetColumnImages;
  503. end; {CreateWnd}
  504. destructor TCustomIEListView.Destroy;
  505. begin
  506. if Assigned(FDragImageList) then
  507. begin
  508. if GlobalDragImageList = FDragImageList then
  509. GlobalDragImageList := nil;
  510. FDragImageList.Free;
  511. end;
  512. inherited;
  513. end; {Destroy}
  514. procedure TCustomIEListView.SortItems;
  515. begin
  516. AlphaSort;
  517. ItemsReordered;
  518. end;
  519. end.