IEListView.pas 18 KB

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