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. property OnSelectByMask;
  167. end; {Type TCustomIEListView}
  168. type
  169. TIEListView = class(TCustomIEListView)
  170. published
  171. // copy from TListView, except for marked items
  172. property Action;
  173. property Align;
  174. property AllocBy;
  175. property Anchors;
  176. property BevelEdges;
  177. property BevelInner;
  178. property BevelOuter;
  179. property BevelKind default bkNone;
  180. property BevelWidth;
  181. property BiDiMode;
  182. property BorderStyle;
  183. property BorderWidth;
  184. property Checkboxes;
  185. property Color;
  186. property Columns;
  187. property ColumnClick;
  188. property Constraints;
  189. property Ctl3D;
  190. property DragCursor;
  191. property DragKind;
  192. property DragMode;
  193. property Enabled;
  194. property Font;
  195. property FlatScrollBars;
  196. property FullDrag;
  197. property GridLines;
  198. property HideSelection;
  199. property HotTrack;
  200. property HotTrackStyles;
  201. property HoverTime;
  202. property IconOptions;
  203. property Items;
  204. property LargeImages;
  205. property MultiSelect;
  206. property OwnerData;
  207. property OwnerDraw;
  208. property ReadOnly default False;
  209. property RowSelect;
  210. property ParentBiDiMode;
  211. property ParentColor default False;
  212. property ParentFont;
  213. property ParentShowHint;
  214. property PopupMenu;
  215. property ShowColumnHeaders;
  216. property ShowWorkAreas;
  217. property ShowHint;
  218. property SmallImages;
  219. property SortType;
  220. property StateImages;
  221. property TabOrder;
  222. property TabStop default True;
  223. property ViewStyle;
  224. property Visible;
  225. property OnAdvancedCustomDraw;
  226. property OnAdvancedCustomDrawItem;
  227. property OnAdvancedCustomDrawSubItem;
  228. property OnChange;
  229. property OnChanging;
  230. property OnClick;
  231. property OnColumnClick;
  232. property OnColumnDragged;
  233. property OnColumnRightClick;
  234. property OnCompare;
  235. property OnContextPopup;
  236. property OnCustomDraw;
  237. property OnCustomDrawItem;
  238. property OnCustomDrawSubItem;
  239. property OnData;
  240. property OnDataFind;
  241. property OnDataHint;
  242. property OnDataStateChange;
  243. property OnDblClick;
  244. property OnDeletion;
  245. property OnDrawItem;
  246. property OnEdited;
  247. property OnEditing;
  248. property OnEndDock;
  249. property OnEndDrag;
  250. property OnEnter;
  251. property OnExit;
  252. property OnGetImageIndex;
  253. property OnGetSubItemImage;
  254. property OnDragDrop;
  255. property OnDragOver;
  256. property OnInfoTip;
  257. property OnInsert;
  258. property OnKeyDown;
  259. property OnKeyPress;
  260. property OnKeyUp;
  261. property OnMouseDown;
  262. property OnMouseMove;
  263. property OnMouseUp;
  264. property OnResize;
  265. property OnSelectItem;
  266. property OnStartDock;
  267. property OnStartDrag;
  268. property OnSecondaryColumnHeader; // TCustomIEListView
  269. end;
  270. var
  271. GlobalDragImageList: TDragImageList;
  272. procedure Register;
  273. implementation
  274. uses
  275. PasTools, Types;
  276. procedure Register;
  277. begin
  278. RegisterComponents('Martin', [TIEListView]);
  279. end;
  280. { TIEListViewColProperties }
  281. constructor TIEListViewColProperties.Create(ListView: TCustomListView; ColCount: Integer);
  282. begin
  283. inherited;
  284. end;
  285. procedure TIEListViewColProperties.SetParamsStr(Value: string);
  286. begin
  287. SortStr := CutToChar(Value, '|', True);
  288. inherited SetParamsStr(Value);
  289. end;
  290. procedure TIEListViewColProperties.SetSortAscending(Value: Boolean);
  291. begin
  292. TCustomIEListView(FListView).SortAscending := Value;
  293. end;
  294. procedure TIEListViewColProperties.SetSortColumn(Value: Integer);
  295. begin
  296. if SortColumn <> Value then
  297. begin
  298. TCustomIEListView(FListView).SortColumn := Value;
  299. Changed;
  300. end;
  301. end;
  302. function TIEListViewColProperties.GetParamsStr: string;
  303. begin
  304. Result := Format('%s|%s', [SortStr, inherited GetParamsStr]);
  305. end;
  306. function TIEListViewColProperties.GetSortAscending: Boolean;
  307. begin
  308. Result := TCustomIEListView(FListView).SortAscending;
  309. end;
  310. function TIEListViewColProperties.GetSortColumn: Integer;
  311. begin
  312. Result := TCustomIEListView(FListView).SortColumn;
  313. end;
  314. procedure TIEListViewColProperties.SetSortStr(Value: string);
  315. var
  316. ASortColumn: Integer;
  317. begin
  318. ASortColumn := StrToIntDef(CutToChar(Value, ';', True), SortColumn);
  319. if ASortColumn < Count then SortColumn := ASortColumn;
  320. SortAscending := Boolean(StrToIntDef(CutToChar(Value, ';', True), Integer(SortAscending)));
  321. end;
  322. function TIEListViewColProperties.GetSortStr: string;
  323. begin
  324. Result := Format('%d;%d', [SortColumn, Integer(SortAscending)]);
  325. end;
  326. { TCustomIEListView }
  327. constructor TCustomIEListView.Create(AOwner: TComponent);
  328. begin
  329. inherited;
  330. ColProperties.OnChange := ColPropertiesChange;
  331. FShowColumnIcon := True;
  332. FSortColumn := 0;
  333. FSortAscending := True;
  334. SetDateTimeFormatString;
  335. end; {Create}
  336. procedure TCustomIEListView.SetSortColumn(Value: Integer);
  337. begin
  338. if Value <> SortColumn then
  339. begin
  340. FSortColumn := Value;
  341. FSortAscending := True;
  342. if Items.Count > 0 then
  343. SortItems;
  344. SetColumnImages;
  345. end;
  346. end; {SetSortColumn}
  347. procedure TCustomIEListView.SetViewStyle(Value: TViewStyle);
  348. begin
  349. if Value <> ViewStyle then
  350. begin
  351. inherited SetViewStyle(Value);
  352. if ViewStyle = vsReport then
  353. SetColumnImages;
  354. end;
  355. end; {SetViewStyle}
  356. procedure TCustomIEListView.SetSortAscending(Value: Boolean);
  357. begin
  358. if SortAscending <> Value then
  359. begin
  360. FSortAscending := Value;
  361. if Items.Count > 0 then
  362. SortItems;
  363. SetColumnImages;
  364. end;
  365. end; {SetSortAscending}
  366. procedure TCustomIEListView.SetColumnImages;
  367. var
  368. HdItem: THdItem;
  369. Index: Integer;
  370. SecondaryColumn: Integer;
  371. ShowImage: Boolean;
  372. NewFmt: Integer;
  373. begin
  374. if ShowColumnHeaders and HandleAllocated then
  375. begin
  376. for Index := 0 to Columns.Count-1 do
  377. begin
  378. HdItem.Mask := HDI_FORMAT;
  379. Header_GetItem(GetDlgItem(Self.Handle,0), Index, HdItem);
  380. SecondaryColumn := SecondaryColumnHeader(Index);
  381. ShowImage := False;
  382. if FShowColumnIcon then
  383. begin
  384. if (Index = SortColumn) or
  385. ((SecondaryColumn >= 0) and (SecondaryColumn = SortColumn)) then
  386. begin
  387. ShowImage := True;
  388. end;
  389. end;
  390. // for hidden columns, do not show the icon
  391. // as on some systems it is still drawn, but on neighboring columns
  392. if ShowImage and (Columns[Index].Width > 0) then
  393. begin
  394. if SortAscending then
  395. begin
  396. NewFmt := (Hditem.fmt or HDF_SORTUP) and (not HDF_SORTDOWN);
  397. end
  398. else
  399. begin
  400. NewFmt := (Hditem.fmt or HDF_SORTDOWN) and (not HDF_SORTUP);
  401. end;
  402. end
  403. else
  404. begin
  405. NewFmt := HdItem.fmt and (not (HDF_SORTUP or HDF_SORTDOWN));
  406. end;
  407. if NewFmt <> HdItem.fmt then
  408. begin
  409. HdItem.Mask := HDI_FORMAT;
  410. HdItem.fmt := NewFmt;
  411. Header_SetItem(GetDlgItem(Self.Handle, 0), Index, HDItem);
  412. end;
  413. end;
  414. end;
  415. end; {SetColumnImage}
  416. procedure TCustomIEListView.SetShowColumnIcon(Value: Boolean);
  417. begin
  418. if Value <> ShowColumnIcon then
  419. begin
  420. FShowColumnIcon := Value;
  421. SetColumnImages;
  422. end;
  423. end; {SetShowColumnIcon}
  424. function TCustomIEListView.SecondaryColumnHeader(Index: Integer): Integer;
  425. begin
  426. if Assigned(OnSecondaryColumnHeader) then
  427. begin
  428. OnSecondaryColumnHeader(Self, Index, Result);
  429. end
  430. else
  431. begin
  432. Result := -1;
  433. end;
  434. end;
  435. function TCustomIEListView.NewColProperties: TCustomListViewColProperties;
  436. begin
  437. Result := TIEListViewColProperties.Create(Self, 0);
  438. end;
  439. function TCustomIEListView.SortAscendingByDefault(Index: Integer): Boolean;
  440. begin
  441. Result := True;
  442. end;
  443. procedure TCustomIEListView.ColClick(Column: TListColumn);
  444. begin
  445. if Column.Index = SortColumn then FSortAscending := not FSortAscending
  446. else
  447. begin
  448. FSortColumn := Column.Index;
  449. FSortAscending := SortAscendingByDefault(Column.Index);
  450. end;
  451. if Items.Count > 0 then SortItems;
  452. SetColumnImages;
  453. inherited;
  454. end; {ColClick}
  455. procedure TCustomIEListView.WMNotify(var Msg: TWMNotify);
  456. begin
  457. if (FHeaderHandle <> 0) and (Msg.NMHdr^.hWndFrom = FHeaderHandle) then
  458. case Msg.NMHdr.code of
  459. HDN_BEGINDRAG:
  460. begin
  461. // We probably do not need to eat this message anymore,
  462. // we let's keep it in sync with HDN_ENDDRAG (see comment there)
  463. end;
  464. HDN_ENDDRAG:
  465. begin
  466. // Originally the code to eat this message was here to
  467. // workaround bug in D4 (until Update Pack 3).
  468. // But when we pass the message to VCL, it reorders
  469. // columns in Columns collection, what our code does not handle.
  470. // See also comment in TCustomListViewColProperties.UpdateListViewOrder
  471. HeaderEndDrag(Self);
  472. Invalidate;
  473. Exit;
  474. end;
  475. HDN_ENDTRACKA, HDN_ENDTRACKW:
  476. begin
  477. SetColumnImages;
  478. Invalidate;
  479. inherited;
  480. if Assigned(FOnHeaderEndTrack) then
  481. FOnHeaderEndTrack(Self);
  482. Exit;
  483. end;
  484. HDN_DIVIDERDBLCLICKA, HDN_DIVIDERDBLCLICKW:
  485. begin
  486. inherited;
  487. if Assigned(FOnHeaderEndTrack) then
  488. FOnHeaderEndTrack(Self);
  489. SetColumnImages;
  490. end;
  491. end;
  492. inherited;
  493. end; { TCustomIEListView.WMNotify }
  494. procedure TCustomIEListView.HeaderEndDrag(Sender : TObject);
  495. begin
  496. if Assigned(FOnHeaderEndDrag) then
  497. FOnHeaderEndDrag(Self);
  498. end; {HeaderEndDrag}
  499. procedure TCustomIEListView.ColPropertiesChange(Sender: TObject);
  500. begin
  501. SetColumnImages;
  502. end;
  503. procedure TCustomIEListView.CreateWnd;
  504. begin
  505. inherited;
  506. FParentForm := GetParentForm(Self);
  507. if not (csDesigning in ComponentState) then
  508. FDragImageList := TDragImageList.Create(Self);
  509. if not Assigned(GlobalDragImageList) then
  510. GlobalDragImageList := DragImageList;
  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.