IEListView.pas 18 KB

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