home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sibdemo3.zip / SOURCE.DAT / SOURCE / SPCC / LISTVIEW.PAS < prev    next >
Pascal/Delphi Source File  |  1998-04-28  |  36KB  |  1,232 lines

  1.  
  2. {╔══════════════════════════════════════════════════════════════════════════╗
  3.  ║                                                                          ║
  4.  ║     Sibyl Portable Component Classes                                     ║
  5.  ║                                                                          ║
  6.  ║     Copyright (C) 1995,97 SpeedSoft Germany,   All rights reserved.      ║
  7.  ║                                                                          ║
  8.  ╚══════════════════════════════════════════════════════════════════════════╝}
  9.  
  10. Unit ListView;
  11.  
  12.  
  13. Interface
  14.  
  15. {$IFDEF OS2}
  16. Uses Os2Def,PmWin,PmStdDlg;
  17. {$ENDIF}
  18.  
  19. {$IFDEF Win95}
  20. Uses WinDef,WinUser,WinGDI,CommCtrl;
  21. {$ENDIF}
  22.  
  23. Uses Messages,SysUtils,Classes,Forms,Graphics,OutLine;
  24.  
  25. Type
  26.     EListViewError=Class(Exception);
  27.  
  28. Type
  29.     TListViewNode=Class;
  30.     TListView=Class;
  31.  
  32.     PListViewRecord=^TListViewRecord;
  33.     TListViewRecord=Record
  34.          {$IFDEF OS2}
  35.          RecordCore:RecordCore;
  36.          {$ENDIF}
  37.          {$IFDEF Win95}
  38.          RecordCore:LV_ITEM;
  39.          {$ENDIF}
  40.          Node:TListViewNode;  {Extra Data}
  41.     End;
  42.  
  43.     TListViewNode=Class
  44.       Private
  45.          FTreeRec:PListViewRecord;
  46.          FCaption:PChar;
  47.          FData:Pointer;
  48.          FIndex:LongInt;
  49.          FListView:TListView;
  50.          FBitmap:TBitmap;
  51.       Private
  52.          Function GetCaption:String;
  53.          Procedure SetCaption(NewCaption:String);
  54.          Function GetBitmap:TBitmap;
  55.          Procedure SetBitmap(NewBitmap:TBitmap);
  56.          Function GetItemRect:TRect;
  57.       Public
  58.          Constructor Create(Owner:TListView);
  59.          Destructor Destroy;Override;
  60.       Public
  61.          Property Data:Pointer Read FData Write FData;
  62.          Property Text:String Read GetCaption Write SetCaption;
  63.          Property Bitmap:TBitmap Read GetBitmap Write SetBitmap;
  64.          Property Index:LongInt Read FIndex;
  65.          Property ItemRect:TRect read GetItemRect;
  66.     End;
  67.     TListViewNodeClass=Class Of TListViewNode;
  68.  
  69.     {$M+}
  70.     TListViewItemSelectEvent=Procedure(Sender:TObject;Index:LongInt) Of Object;
  71.     {$M-}
  72.  
  73.     TListView=Class(TControl)
  74.       Private
  75.          FBitmapSize:TSize;
  76.          FShowDragRects:Boolean;
  77.          FDragRectValid:Boolean;
  78.          FDragRect:TRect;
  79.          FDragSelected:TListViewNode;
  80.          FInitNodes:TList;
  81.          FNodes:TList;
  82.          FNodeClass:TListViewNodeClass;
  83.          FPictureList:TBitmapList;
  84.          FMultipleSel:Boolean;
  85.          FBorderStyle:TBorderStyle;
  86.          FPopupPos:TPoint;
  87.          {$IFDEF Win95}
  88.          FHim:HIMAGELIST;
  89.          {$ENDIF}
  90.          FOnItemSelect:TListViewItemSelectEvent;
  91.          FUpdateCount:LongInt;
  92.          FSorted:Boolean;
  93.       Private
  94.          {$IFDEF OS2}
  95.          Procedure WMPaint(Var Msg:TMessage);Message WM_PAINT;
  96.          {$ENDIF}
  97.          Procedure SetCnrInfo;
  98.          Procedure SetupImageList;
  99.          Procedure SetupList;
  100.          Function AddPicture(NewBitmap:TBitmap):TBitmap;
  101.          Function Get(Index:LongInt):TListViewNode;
  102.          Function GetItemCount:LongInt;
  103.          Procedure UpdateNode(Node:TListViewNode);
  104.          Procedure SetBorderStyle(NewBorder:TBorderStyle);
  105.          Function GetItemIndex:LongInt;
  106.          Procedure SetItemIndex(NewValue:LongInt);
  107.          Function GetSelect(Index:LongInt):Boolean;
  108.          Procedure SetSelect(Index:LongInt;NewValue:Boolean);
  109.          Procedure SetSorted(NewValue:Boolean);
  110.          Procedure DrawDragRect;
  111.       Protected
  112.          Procedure SetupComponent;Override;
  113.          {$IFDEF OS2}
  114.          Procedure SetupShow;Override;
  115.          {$ENDIF}
  116.          Procedure GetClassData(Var ClassData:TClassData);Override;
  117.          Procedure CreateParams(Var Params:TCreateParams);Override;
  118.          Procedure CreateWnd;Override;
  119.          Procedure DestroyWnd;Override;
  120.          Procedure ParentNotification(Var Msg:TMessage);Override;
  121.          Procedure ItemSelect(Index:LongInt);Virtual;
  122.          Procedure ScanEvent(Var KeyCode:TKeyCode;RepeatCount:Byte);Override;
  123.          Procedure MouseClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
  124.          {$IFDEF WIN32}
  125.          Procedure MouseDblClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LonGInT);Override;
  126.          {$ENDIF}
  127.          Procedure DragOver(Source:TObject;X,Y:LongInt;State:TDragState;Var Accept:Boolean);Override;
  128.          Procedure DragDrop(Source:TObject;X,Y:LongInt);Override;
  129.       Public
  130.          Destructor Destroy;Override;
  131.          Function Add(Const Text:String;Data:Pointer;Bitmap:TBitmap):TListViewNode;
  132.          Function NodeFromPoint(pt:TPoint):TListViewNode;
  133.          Procedure Clear;
  134.          Procedure BeginUpdate;
  135.          Procedure EndUpdate;
  136.       Public
  137.          Property NodeClass:TListViewNodeClass Read FNodeClass Write FNodeClass;
  138.          Property Nodes:TList Read FNodes;
  139.          Property Items[Index:LongInt]:TListViewNode Read Get;Default;
  140.          Property ItemCount:LongInt Read GetItemCount;
  141.          Property ItemIndex:LongInt Read GetItemIndex Write SetItemIndex;
  142.          Property Selected[Index:LongInt]:Boolean Read GetSelect Write SetSelect;
  143.          Property XAlign;
  144.          Property XStretch;
  145.          Property YAlign;
  146.          Property YStretch;
  147.       Published
  148.          Property Align;
  149.          Property Color;
  150.          Property BitmapSize:TSize Read FBitmapSize Write FBitmapSize;
  151.          Property BorderStyle:TBorderStyle Read FBorderStyle Write SetBorderStyle;
  152.          Property PenColor;
  153.          Property DragCursor;
  154.          Property DragMode;
  155.          Property Enabled;
  156.          Property Font;
  157.          Property MultipleSel:Boolean Read FMultipleSel Write FMultipleSel;
  158.          Property ParentColor;
  159.          Property ParentPenColor;
  160.          Property ParentFont;
  161.          Property ParentShowHint;
  162.          Property PopupMenu;
  163.          Property ShowDragRects:Boolean Read FShowDragRects Write FShowDragRects;
  164.          Property ShowHint;
  165.          Property Sorted:Boolean read FSorted write SetSorted;
  166.          Property TabOrder;
  167.          Property TabStop;
  168.          Property Visible;
  169.          Property ZOrder;
  170.  
  171.          Property OnCanDrag;
  172.          Property OnDblClick;
  173.          Property OnDragDrop;
  174.          Property OnDragOver;
  175.          Property OnEndDrag;
  176.          Property OnEnter;
  177.          Property OnExit;
  178.          Property OnFontChange;
  179.          Property OnItemSelect:TListViewItemSelectEvent Read FOnItemSelect Write FOnItemSelect;
  180.          Property OnMouseClick;
  181.          Property OnMouseDblClick;
  182.          Property OnMouseDown;
  183.          Property OnMouseMove;
  184.          Property OnMouseUp;
  185.          Property OnSetupShow;
  186.          Property OnStartDrag;
  187.     End;
  188.  
  189.  
  190. Function InsertListView(parent:TControl;Left,Bottom,Width,Height:LongInt;Hint:String):TListView;
  191.  
  192.  
  193. Implementation
  194.  
  195.  
  196. Function InsertListView(parent:TControl;Left,Bottom,Width,Height:LongInt;Hint:String):TListView;
  197. Begin
  198.      Result.Create(parent);
  199.      Result.SetWindowPos(Left,Bottom,Width,Height);
  200.      Result.TabStop := True;
  201.      Result.Hint := Hint;
  202.      Result.parent := parent;
  203. End;
  204.  
  205.  
  206. {$IFDEF Win95}
  207. Const
  208.     CMA_FIRST:LongWord=0;
  209. {$ENDIF}
  210.  
  211.  
  212. Procedure RemoveRecord(Node:TListViewNode; Update:Boolean);
  213. Var  Flags:LongWord;
  214.      ListHandle:LongWord;
  215. Begin
  216.      If Node = Nil Then Exit;
  217.      If Node.FTreeRec = Nil Then Exit;
  218.  
  219.      ListHandle := Node.FListView.Handle;
  220.      If ListHandle <> 0 Then
  221.      Begin
  222.           {$IFDEF OS2}
  223.           Flags := CMA_FREE;
  224.           If Update Then Flags := Flags Or CMA_INVALIDATE;
  225.           WinSendMsg(ListHandle,CM_REMOVERECORD,LongWord(@Node.FTreeRec),
  226.                      MPFROM2SHORT(1,Flags));
  227.           {$ENDIF}
  228.           {$IFDEF Win95}
  229.           SendMessage(ListHandle,LVM_DELETEITEM,
  230.                       LongWord(Node.FTreeRec^.RecordCore.iItem),0);
  231.           {$ENDIF}
  232.      End;
  233.  
  234.      {$IFDEF Win95}
  235.      Dispose(Node.FTreeRec);
  236.      {$ENDIF}
  237.      Node.FTreeRec := Nil;
  238. End;
  239.  
  240.  
  241. Procedure InsertRecord(NewNode:TListViewNode; AParentRecord:PListViewRecord;
  242.                        RecordOrder:Pointer);
  243. Var  ListHandle:LongWord;
  244.      List:TListView;
  245.      {$IFDEF OS2}
  246.      aRecordInsert:RECORDINSERT;
  247.      {$ENDIF}
  248. Begin
  249.      NewNode.FTreeRec^.Node := NewNode;
  250.      {specify where To Insert}
  251.      List := NewNode.FListView;
  252.      ListHandle := List.Handle;
  253.  
  254.      {$IFDEF OS2}
  255.      aRecordInsert.cb := SizeOf(RECORDINSERT);
  256.      aRecordInsert.pRecordOrder := RecordOrder;
  257.      aRecordInsert.ZOrder := CMA_TOP;
  258.      aRecordInsert.cRecordsInsert := 1;     //Number Of records
  259.      aRecordInsert.fInvalidateRecord := 1;  //Invalidate records
  260.      aRecordInsert.pRecordParent := Pointer(AParentRecord);
  261.  
  262.      {Insert Record}
  263.      WinSendMsg(ListHandle,CM_INSERTRECORD,
  264.                 LongWord(NewNode.FTreeRec),LongWord(@aRecordInsert));
  265.      {$ENDIF}
  266.  
  267.      {$IFDEF Win95}
  268.      SendMessage(ListHandle,LVM_INSERTITEM,0,LongWord(@NewNode.FTreeRec^.RecordCore));
  269.      {$ENDIF}
  270. End;
  271.  
  272.  
  273. Procedure AllocateRecord(Handle:LongWord;Var porec:PListViewRecord);
  274. Begin
  275.      //allocate Memory
  276.      {$IFDEF OS2}
  277.      porec:=Pointer(WinSendMsg(Handle,
  278.                                CM_ALLOCRECORD,
  279.                                {additional Info For ListViewRecord}
  280.                                SizeOf(TListViewRecord)-SizeOf(RecordCore),
  281.                                1));          {allocate one Record}
  282.      {$ENDIF}
  283.      {$IFDEF Win95}
  284.      New(porec);
  285.      {$ENDIF}
  286. End;
  287.  
  288. {
  289. ╔═══════════════════════════════════════════════════════════════════════════╗
  290. ║                                                                           ║
  291. ║ Speed-Pascal/2 Version 2.0                                                ║
  292. ║                                                                           ║
  293. ║ Speed-Pascal Component Classes (SPCC)                                     ║
  294. ║                                                                           ║
  295. ║ This section: TListViewBitmap Class Implementation                        ║
  296. ║                                                                           ║
  297. ║ (C) 1995,97 SpeedSoft. All rights reserved. Disclosure probibited !       ║
  298. ║                                                                           ║
  299. ╚═══════════════════════════════════════════════════════════════════════════╝
  300. }
  301.  
  302. Type
  303.     TListViewBitmap=Class(TBitmap)
  304.       {$IFDEF Win95}
  305.       Private
  306.          FHimlIndex:LongInt;
  307.       Private
  308.          Function CreateBitmapFromClass(CX,CY:LongWord):LongWord;
  309.       {$ENDIF}
  310.     End;
  311.  
  312.  
  313. {$IFDEF Win95}
  314. Function TListViewBitmap.CreateBitmapFromClass(CX,CY:LongWord):LongWord;
  315. Var ps:HDC;
  316.     iinfo:ICONINFO;
  317.     HBITMAP,OldBmp:LongWord;
  318. Begin
  319.      HBITMAP:=CopyImage(Handle,IMAGE_BITMAP,CX,CY,0);
  320.      iinfo.FIcon:=True;
  321.      iinfo.hbmMask:=CreateBitmap(CX,CY,1,1,Nil);
  322.      ps:=CreateCompatibleDC(0);
  323.      OldBmp:=SelectObject(ps,iinfo.hbmMask);
  324.      WinGDI.BitBlt(ps,0,0,CX-1,CY-1,0,0,0,BLACKNESS);
  325.      iinfo.hbmColor:=HBITMAP;
  326.      Result:=CreateIconIndirect(iinfo);
  327.  
  328.      SelectObject(ps,OldBmp);
  329.      If Not DeleteDC(ps) Then ErrorBox2('CreateBitmapFromClass: Cannot destroy BitmapPS');;
  330.      If Not DeleteObject(iinfo.hbmMask) Then ErrorBox2('CreateBitmapFromClass: Cannot destroy Mask BitmapHandle');
  331.      If Not DeleteObject(HBITMAP) Then ErrorBox2('CreateBitmapFromClass: Cannot destroy BitmapHandle');
  332. End;
  333. {$ENDIF}
  334.  
  335. {
  336. ╔═══════════════════════════════════════════════════════════════════════════╗
  337. ║                                                                           ║
  338. ║ Speed-Pascal/2 Version 2.0                                                ║
  339. ║                                                                           ║
  340. ║ Speed-Pascal Component Classes (SPCC)                                     ║
  341. ║                                                                           ║
  342. ║ This section: TListViewNode Class Implementation                          ║
  343. ║                                                                           ║
  344. ║ (C) 1995,97 SpeedSoft. All rights reserved. Disclosure probibited !       ║
  345. ║                                                                           ║
  346. ╚═══════════════════════════════════════════════════════════════════════════╝
  347. }
  348.  
  349.  
  350. Function TListViewNode.GetCaption:String;
  351. Begin
  352.      If FCaption=Nil Then Result:=''
  353.      Else Result:=FCaption^;
  354. End;
  355.  
  356.  
  357. Procedure TListViewNode.SetCaption(NewCaption:String);
  358. Begin
  359.      If NewCaption = Text Then Exit;
  360.  
  361.      If FCaption<>Nil Then FreeMem(FCaption,Length(FCaption^)+1);
  362.      FCaption:=Nil;
  363.      If NewCaption<>'' Then
  364.      Begin
  365.           GetMem(FCaption,Length(NewCaption)+1);
  366.           FCaption^:=NewCaption;
  367.      End;
  368.  
  369.      {$IFDEF OS2}
  370.      If FTreeRec<>Nil Then FTreeRec^.RecordCore.pszIcon:=FCaption;
  371.      {$ENDIF}
  372.      {$IFDEF Win95}
  373.      If FTreeRec<>Nil Then
  374.      Begin
  375.           FTreeRec^.RecordCore.pszText:=FCaption;
  376.           If FCaption<>Nil Then
  377.              FTreeRec^.RecordCore.cchTextMax:=Length(FCaption^)+1
  378.           Else FTreeRec^.RecordCore.cchTextMax:=0;
  379.      End;
  380.      {$ENDIF}
  381.  
  382.      FListView.UpdateNode(Self);
  383. End;
  384.  
  385.  
  386. Procedure TListViewNode.SetBitmap(NewBitmap:TBitmap);
  387. Begin
  388.      FBitmap:=FListView.AddPicture(NewBitmap);
  389.  
  390.      {$IFDEF OS2}
  391.      If FTreeRec<>Nil Then
  392.      Begin
  393.         If FBitmap<>Nil Then
  394.            FTreeRec^.RecordCore.hbmBitmap:=FBitmap.Handle
  395.         Else
  396.            FTreeRec^.RecordCore.hbmBitmap:=0;
  397.      End;
  398.      {$ENDIF}
  399.      {$IFDEF Win95}
  400.      If FTreeRec<>Nil Then
  401.      Begin
  402.         If FBitmap<>Nil Then
  403.            FTreeRec^.RecordCore.iImage := TListViewBitmap(FBitmap).FHimlIndex
  404.         Else
  405.            FTreeRec^.RecordCore.iImage:=0;
  406.      End;
  407.      {$ENDIF}
  408.  
  409.      FListView.UpdateNode(Self);
  410. End;
  411.  
  412.  
  413. Function TListViewNode.GetBitmap:TBitmap;
  414. Begin
  415.      If FBitmap = Nil Then
  416.      Begin
  417.           FBitmap.Create;
  418.           Include(FBitmap.ComponentState, csDetail);
  419.      End;
  420.      Result := FBitmap;
  421. End;
  422.  
  423.  
  424. Constructor TListViewNode.Create(Owner:TListView);
  425. Begin
  426.      Inherited Create;
  427.  
  428.      If Owner Is TListView Then
  429.      Begin
  430.           FListView := TListView(Owner)
  431.      End
  432.      Else Raise EListViewError.Create('Invalid listview item owner');
  433. End;
  434.  
  435. Destructor TListViewNode.Destroy;
  436. Begin
  437.      RemoveRecord(Self,True);
  438.  
  439.      If FCaption <> Nil Then
  440.      Begin
  441.           FreeMem(FCaption,Length(FCaption^)+1);
  442.           FCaption := Nil;
  443.      End;
  444.  
  445.      Inherited Destroy;
  446. End;
  447.  
  448. Function TListViewNode.GetItemRect:TRect;
  449. {$IFDEF OS2}
  450. Var RecRect:QUERYRECORDRECT;
  451. {$ENDIF}
  452. Begin
  453.      FillChar(result,sizeof(TRect),0);
  454.      {$IFDEF OS2}
  455.      RecRect.cb:=sizeof(QUERYRECORDRECT);
  456.      RecRect.pRecord:=@FTreeRec^.RecordCore;
  457.      RecRect.fRightSplitWindow:=0;
  458.      RecRect.fsExtent:=CMA_ICON OR CMA_TEXT;
  459.      WinSendMsg(FListView.Handle,CM_QUERYRECORDRECT,LongWord(@Result),LongWord(@RecRect));
  460.      {$ENDIF}
  461. End;
  462.  
  463. {
  464. ╔═══════════════════════════════════════════════════════════════════════════╗
  465. ║                                                                           ║
  466. ║ Speed-Pascal/2 Version 2.0                                                ║
  467. ║                                                                           ║
  468. ║ Speed-Pascal Component Classes (SPCC)                                     ║
  469. ║                                                                           ║
  470. ║ This section: TListView Class Implementation                              ║
  471. ║                                                                           ║
  472. ║ (C) 1995,97 SpeedSoft. All rights reserved. Disclosure probibited !       ║
  473. ║                                                                           ║
  474. ╚═══════════════════════════════════════════════════════════════════════════╝
  475. }
  476.  
  477.  
  478. Procedure TListView.UpdateNode(Node:TListViewNode);
  479. Begin
  480.      If Handle=0 Then Exit;
  481.      {$IFDEF OS2}
  482.      WinSendMsg(Handle,CM_INVALIDATERECORD,LongWord(@Node.FTreeRec),
  483.                 MPFROM2SHORT(1,0));
  484.      {$ENDIF}
  485.      {$IFDEF Win95}
  486.      SendMessage(Handle,LVM_SETITEM,0,LongWord(@Node.FTreeRec^.RecordCore));
  487.      {$ENDIF}
  488. End;
  489.  
  490. Procedure TListView.SetCnrInfo;
  491. {$IFDEF OS2}
  492. Var acnrInfo:CNRINFO;
  493.     Flags:LongWord;
  494. {$ENDIF}
  495. {$IFDEF Win95}
  496. Var WinStyle:LongWord;
  497. {$ENDIF}
  498. Begin
  499.      If Handle=0 Then Exit;
  500.  
  501.      {$IFDEF OS2}
  502.      FillChar(acnrInfo,SizeOf(CNRINFO),0);
  503.      Flags:=CMA_FLWINDOWATTR;
  504.  
  505.      With acnrInfo Do
  506.      Begin
  507.           cb:=SizeOf(CNRINFO);
  508.           flWindowAttr:=CV_ICON;
  509.           slBitmapOrIcon.CX:=FBitmapSize.CX;
  510.           slBitmapOrIcon.CY:=FBitmapSize.CY;
  511.           Flags:=Flags Or CMA_SLBITMAPORICON;
  512.           flWindowAttr:=flWindowAttr Or CA_DRAWBITMAP;
  513.      End;
  514.      WinSendMsg(Handle,CM_SETCNRINFO,LongWord(@acnrInfo),Flags);
  515.      {$ENDIF}
  516.      {$IFDEF Win95}
  517.      WinStyle:=GetWindowLong(Handle,GWL_STYLE);
  518.      If Not FMultipleSel Then WinStyle:=WinStyle Or LVS_SINGLESEL;
  519.      SetWindowLong(Handle,GWL_STYLE,WinStyle);
  520.      Invalidate;
  521.      {$ENDIF}
  522. End;
  523.  
  524.  
  525. Procedure TListView.GetClassData(Var ClassData:TClassData);
  526. Begin
  527.      Inherited GetClassData(ClassData);
  528.  
  529.      {$IFDEF OS2}
  530.      ClassData.ClassULong := WC_CONTAINER;
  531.      {$ENDIF}
  532.      {$IFDEF Win95}
  533.      CreateSubClass(ClassData,WC_LISTVIEW);
  534.      {$ENDIF}
  535. End;
  536.  
  537. Procedure TListView.CreateParams(Var Params:TCreateParams);
  538. Begin
  539.      Inherited CreateParams(Params);
  540.  
  541.      {$IFDEF OS2}
  542.      Params.Style := Params.Style Or CCS_AUTOPOSITION;
  543.      If FMultipleSel Then Params.Style := Params.Style Or CCS_MULTIPLESEL
  544.      Else Params.Style := Params.Style Or CCS_SINGLESEL;
  545.      {$ENDIF}
  546.      {$IFDEF Win95}
  547.      Params.Style := Params.Style Or LVS_AUTOARRANGE;
  548.      Params.Style := Params.Style Or WS_CHILD Or LVS_ICON;
  549.      If Not FMultipleSel Then Params.Style:=Params.Style Or LVS_SINGLESEL;
  550.  
  551.      If FBorderStyle = bsSingle Then
  552.      Begin
  553.           Params.Style := Params.Style Or WS_BORDER;             {Single}
  554.           Params.ExStyle := Params.ExStyle Or WS_EX_CLIENTEDGE;  {Double}
  555.      End;
  556.      {$ENDIF}
  557. End;
  558.  
  559. Procedure TListView.SetupImageList;
  560. {$IFDEF Win95}
  561. Var  Count:LongInt;
  562.      T:LongInt;
  563.      Bitmap:TListViewBitmap;
  564.      BitHandle:LongWord;
  565. {$ENDIF}
  566. Begin
  567.      {$IFDEF Win95}
  568.      If Handle=0 Then Exit;
  569.      If FPictureList=Nil Then Exit;
  570.  
  571.      Count:=FPictureList.Count;
  572.  
  573.      If Count=0 Then Exit;
  574.  
  575.      If FHim<>Nil Then ImageList_Destroy(FHim);
  576.  
  577.      FHim:=ImageList_Create(FBitmapSize.CX,
  578.                             FBitmapSize.CY,
  579.                             ILC_COLOR4,Count,0);
  580.  
  581.      For T:=0 To FPictureList.Count-1 Do
  582.      Begin
  583.           Bitmap:=TListViewBitmap(FPictureList.Bitmaps[T]);
  584.           BitHandle:=Bitmap.CreateBitmapFromClass(FBitmapSize.CX,FBitmapSize.CY);
  585.           Bitmap.FHimlIndex:=ImageList_AddIcon(FHim,BitHandle);
  586.           DeleteObject(BitHandle);
  587.      End;
  588.  
  589.      SendMessage(Handle,LVM_SETIMAGELIST,LVSIL_NORMAL,LongWord(FHim));
  590.      {$ENDIF}
  591. End;
  592.  
  593. Procedure SetupNode(Node:TListViewNode);
  594. Begin
  595.      {$IFDEF OS2}
  596.      Node.FTreeRec^.RecordCore.pszIcon := Node.FCaption;
  597.      If Node.FBitmap<>Nil Then
  598.        Node.FTreeRec^.RecordCore.hbmBitmap:=Node.FBitmap.Handle
  599.      Else
  600.        Node.FTreeRec^.RecordCore.hbmBitmap:=0;
  601.      //Node.FTreeRec^.RecordCore.ptlIcon.X:=20;
  602.      //Node.FTreeRec^.RecordCore.ptlIcon.Y:=20;
  603.      {$ENDIF}
  604.      {$IFDEF Win95}
  605.      Node.FTreeRec^.RecordCore.Mask:=LVIF_TEXT Or LVIF_IMAGE Or LVIF_PARAM;
  606.      Node.FTreeRec^.RecordCore.iItem:=Node.Index;
  607.      Node.FTreeRec^.RecordCore.iSubItem:=0;
  608.      Node.FTreeRec^.RecordCore.State:=0;
  609.      Node.FTreeRec^.RecordCore.StateMask:=0;
  610.      Node.FTreeRec^.RecordCore.pszText:=Node.FCaption;
  611.      Node.FTreeRec^.RecordCore.cchTextMax:=Length(Node.FCaption^)+1;
  612.      If Node.FBitmap<>Nil Then
  613.        Node.FTreeRec^.RecordCore.iImage:=TListViewBitmap(Node.FBitmap).FHimlIndex
  614.      Else
  615.        Node.FTreeRec^.RecordCore.iImage:=0;
  616.      Node.FTreeRec^.RecordCore.LParam:=LongWord(Node);
  617.      {$ENDIF}
  618. End;
  619.  
  620.  
  621.  
  622. Procedure TListView.SetupList;
  623. Var T:LongInt;
  624.     Node,PrevNode:TListViewNode;
  625.     P:Pointer;
  626. Begin
  627.      If Handle=0 Then Exit;
  628.      If FInitNodes=Nil Then Exit;
  629.      {Create All main Nodes}
  630.      PrevNode:=Nil;
  631.      For T:=0 To FNodes.Count-1 Do
  632.      Begin
  633.           Node:=FNodes.Items[T];
  634.           If Node.FTreeRec=Nil Then
  635.           Begin
  636.                AllocateRecord(Handle,Node.FTreeRec);
  637.                SetupNode(Node);
  638.           End;
  639.  
  640.           If PrevNode=Nil
  641.           Then
  642.           Begin
  643.               LongWord(P):=CMA_FIRST;
  644.               InsertRecord(Node,Nil,P);
  645.           End
  646.           Else InsertRecord(Node,Nil,Pointer(PrevNode.FTreeRec));
  647.           PrevNode:=Node;
  648.      End;
  649.      FInitNodes:=Nil;
  650. End;
  651.  
  652.  
  653. Procedure TListView.CreateWnd;
  654. Begin
  655.      Inherited CreateWnd;
  656.  
  657.      If Handle=0 Then Exit;
  658.      {Set Options}
  659.      SetCnrInfo;
  660.      SetupImageList;
  661.      SetupList;
  662. End;
  663.  
  664. Procedure TListView.SetupComponent;
  665. Begin
  666.      Inherited SetupComponent;
  667.  
  668.      FBitmapSize.CX:=0;
  669.      FBitmapSize.CY:=0;
  670.  
  671.      FNodeClass := TListViewNode;
  672.      Ownerdraw := False;
  673.      Name:='ListView';
  674.      Height:=150;
  675.      Width:=150;
  676.      color:=clWindow;
  677.      ParentPenColor:=False;
  678.      ParentColor:=False;
  679.      FBorderStyle:=bsSingle;
  680. End;
  681.  
  682.  
  683. {$IFDEF OS2}
  684. Procedure TListView.SetupShow;
  685. Begin
  686.      Inherited SetupShow;
  687.      CreateCanvas;
  688. End;
  689.  
  690.  
  691. Procedure TListView.WMPaint(Var Msg:TMessage);
  692. Var  rc1,rcupdate:TRect;
  693. Begin
  694.      If FBorderStyle = bsSingle Then
  695.      Begin {Exclude border from Redraw area}
  696.           rc1 := ClientRect;
  697.           {????????+-1}
  698.           Inc(rc1.Right);
  699.           Inc(rc1.Top);
  700.           InflateRect(rc1,-2,-2);
  701.  
  702.           WinQueryUpdateRect(Handle,RECTL(rcupdate));
  703.           WinValidateRect(Handle,RECTL(rcupdate),False);
  704.           rcupdate := IntersectRect(rcupdate,rc1);
  705.           WinInvalidateRect(Handle,RECTL(rcupdate),False);
  706.      End;
  707.  
  708.      DefaultHandler(Msg);       {Do Default Action}
  709.  
  710.      If FBorderStyle = bsSingle Then
  711.      Begin
  712.           rc1 := ClientRect;
  713.           DrawSystemBorder(Self,rc1,FBorderStyle); {overpaint Text ON the border}
  714.      End;
  715. End;
  716. {$ENDIF}
  717.  
  718.  
  719. Procedure TListView.SetBorderStyle(NewBorder:TBorderStyle);
  720. Begin
  721.      FBorderStyle := NewBorder;
  722.      {$IFDEF OS2}
  723.      Invalidate;
  724.      {$ENDIF}
  725.      {$IFDEF Win95}
  726.      RecreateWnd;
  727.      {$ENDIF}
  728. End;
  729.  
  730. Procedure TListView.Clear;
  731. Var  T:LongInt;
  732.      Node:TListViewNode;
  733. Begin
  734.     {Store Tree Items -> Linear List}
  735.     If FNodes<>Nil Then
  736.     Begin
  737.          For t:=FNodes.Count-1 Downto 0 Do
  738.          Begin
  739.              Node:=FNodes[t];
  740.              Node.Destroy;
  741.          End;
  742.          FNodes.Destroy;
  743.          FNodes:=Nil;
  744.     End;
  745. End;
  746.  
  747. Procedure TListView.BeginUpdate;
  748. Begin
  749.      If FUpdateCount = 0 Then
  750.      Begin
  751.           If Handle <> 0 Then
  752.           {$IFDEF OS2}
  753.           WinEnableWindowUpdate(Handle,False);
  754.           {$ENDIF}
  755.           {$IFDEF Win95}
  756.           SendMessage(Handle,WM_SETREDRAW, 0, 0);
  757.           {$ENDIF}
  758.      End;
  759.      Inc(FUpdateCount);
  760. End;
  761.  
  762.  
  763. Procedure TListView.EndUpdate;
  764. Begin
  765.      Dec(FUpdateCount);
  766.      If FUpdateCount = 0 Then
  767.      Begin
  768.           If Handle <> 0 Then
  769.           {$IFDEF OS2}
  770.           WinEnableWindowUpdate(Handle,True);
  771.           {$ENDIF}
  772.           {$IFDEF Win95}
  773.           SendMessage(Handle,WM_SETREDRAW, 1, 0);
  774.           {$ENDIF}
  775.           Invalidate;
  776.      End;
  777. End;
  778.  
  779. Procedure TListView.DestroyWnd;
  780. Begin
  781.      Clear;
  782.  
  783.      Inherited DestroyWnd;
  784. End;
  785.  
  786.  
  787. Destructor TListView.Destroy;
  788. Begin
  789.      If FPictureList <> Nil Then
  790.      Begin
  791.           FPictureList.Destroy;  {Destroy local Bitmaps}
  792.           FPictureList := Nil;
  793.      End;
  794.  
  795.      {$IFDEF Win95}
  796.      If FHim <> Nil Then ImageList_Destroy(FHim);
  797.      FHim := Nil;
  798.      {$ENDIF}
  799.  
  800.      Inherited Destroy;
  801. End;
  802.  
  803. Function TListView.AddPicture(NewBitmap:TBitmap):TBitmap;
  804. Var  idx:LongInt;
  805. Begin
  806.      If NewBitmap = Nil Then
  807.      Begin
  808.           Result := Nil;
  809.           Exit;
  810.      End;
  811.  
  812.      If FPictureList = Nil Then
  813.      Begin
  814.           FPictureList.Create;
  815.           FPictureList.BitmapClass := TListViewBitmap;
  816.           FPictureList.Duplicates := False;
  817.      End;
  818.  
  819.      idx := FPictureList.IndexOfOrigin(NewBitmap);
  820.  
  821.      If idx < 0 Then                                     {Not found}
  822.      Begin
  823.           idx := FPictureList.Add(NewBitmap);  {Create local Bitmap}
  824.           SetupImageList;
  825.      End;
  826.      Result := FPictureList.Bitmaps[idx];
  827. End;
  828.  
  829. Procedure TListView.SetSorted(NewValue:Boolean);
  830. Var Nodes:TList;
  831.     t:Longint;
  832.     Node:TListViewNode;
  833. Begin
  834.     If NewValue=FSorted Then exit;
  835.  
  836.     FSorted:=NewValue;
  837.  
  838.     If Sorted Then //resort
  839.       If FNodes<>Nil Then
  840.     Begin
  841.        BeginUpdate;
  842.  
  843.        Nodes:=FNodes;
  844.  
  845.        FNodes:=Nil;
  846.        For t:=Nodes.Count-1 Downto 0 Do
  847.        Begin
  848.            Node:=Nodes[t];
  849.            Add(Node.Text,Node.Data,Node.FBitmap);
  850.            Node.Destroy;
  851.        End;
  852.        Nodes.Destroy;
  853.  
  854.        EndUpdate;
  855.     End;
  856. End;
  857.  
  858. Function TListView.Add(Const Text:String;Data:Pointer;Bitmap:TBitmap):TListViewNode;
  859. Var  NewNode,PrevNode,Node:TListViewNode;
  860.      P:Pointer;
  861.      t,t1:LongInt;
  862. Begin
  863.      NewNode := FNodeClass.Create(Self);
  864.      NewNode.Data := Data;
  865.      NewNode.Text := Text;
  866.      NewNode.FBitmap:=AddPicture(Bitmap);
  867.      If Bitmap<>Nil Then
  868.      Begin
  869.         If FBitmapSize.CX=0 Then FBitmapSize.CX:=Bitmap.Width;
  870.         If FBitmapSize.CY=0 Then FBitmapSize.CY:=Bitmap.Width;
  871.      End;
  872.  
  873.      If FNodes=Nil Then FNodes.Create;
  874.      If Sorted Then
  875.      Begin
  876.         NewNode.FIndex:=FNodes.Count;
  877.         For t:=0 To FNodes.Count-1 Do
  878.         Begin
  879.             Node:=FNodes[t];
  880.             If Node.Text>Text Then
  881.             Begin
  882.                 NewNode.FIndex:=Node.FIndex;
  883.                 For t1:=t To FNodes.Count-1 Do
  884.                 Begin
  885.                     Node:=TListViewNode(FNodes[t1]);
  886.                     inc(Node.FIndex);
  887.                 End;
  888.                 break;
  889.             End;
  890.         End;
  891.  
  892.         FNodes.Insert(NewNode.FIndex,NewNode);
  893.      End
  894.      Else
  895.      Begin
  896.         NewNode.FIndex:=FNodes.Count;
  897.         FNodes.Add(NewNode);
  898.      End;
  899.  
  900.      If Handle=0 Then FInitNodes:=FNodes
  901.      Else
  902.      Begin
  903.           If FNodes.Count=1 Then PrevNode:=Nil
  904.           Else PrevNode:=FNodes.Items[NewNode.FIndex-1];
  905.  
  906.           If NewNode.FTreeRec=Nil Then
  907.           Begin
  908.                AllocateRecord(Handle,NewNode.FTreeRec);
  909.                SetupNode(NewNode);
  910.           End;
  911.  
  912.           If PrevNode=Nil
  913.           Then
  914.           Begin
  915.               LongWord(P):=CMA_FIRST;
  916.               InsertRecord(NewNode,Nil,P);
  917.           End
  918.           Else InsertRecord(NewNode,Nil,Pointer(PrevNode.FTreeRec));
  919.      End;
  920.      Result := NewNode;
  921. End;
  922.  
  923. Function TListView.Get(Index:LongInt):TListViewNode;
  924. Begin
  925.      Result:=FNodes.Items[Index];
  926. End;
  927.  
  928. Function TListView.GetItemCount:LongInt;
  929. Begin
  930.      If FNodes=Nil Then Result:=0
  931.      Else Result:=FNodes.Count;
  932. End;
  933.  
  934. {$HINTS OFF}
  935. Procedure TListView.ItemSelect(Index:LongInt);
  936. Begin
  937. End;
  938. {$HINTS ON}
  939.  
  940.  
  941. Procedure TListView.ScanEvent(Var KeyCode:TKeyCode;RepeatCount:Byte);
  942. Begin
  943.      Case KeyCode Of
  944.        kbCUp,kbCDown,kbCLeft,kbCRight: ; {!}
  945.        Else Inherited ScanEvent(KeyCode,RepeatCount);
  946.      End;
  947. End;
  948.  
  949. Procedure TListView.ParentNotification(Var Msg:TMessage);
  950. {$IFDEF OS2}
  951. Var  Node:TListViewNode;
  952.      RecordCore:PListViewRecord;
  953.      RecEnter:PNOTIFYRECORDENTER;
  954. {$ENDIF}
  955. Begin
  956.      {$IFDEF OS2}
  957.      Case Msg.Param1Hi Of
  958.        CN_SCROLL:
  959.        Begin
  960.             Inherited ParentNotification(Msg);
  961.  
  962.             {!! Update BitBlt area Of the Ownerdraw Frame}
  963.             If FBorderStyle = bsSingle Then Invalidate;
  964.        End;
  965.        CN_ENTER:      {Enter & DoubleClick}
  966.        Begin
  967.             If Designed Then Exit;
  968.             Inherited ParentNotification(Msg);
  969.  
  970.             RecEnter := Pointer(Msg.Param2);
  971.             If RecEnter = Nil Then Exit;
  972.             RecordCore := Pointer(RecEnter^.pRecord);
  973.             If RecordCore = Nil Then Exit;
  974.             Node := RecordCore^.Node;
  975.  
  976.             If Node Is TListViewNode Then
  977.             Begin
  978.                  ItemSelect(Node.Index);
  979.                  If OnItemSelect <> Nil Then OnItemSelect(Self,Node.Index);
  980.             End;
  981.        End;
  982.        CN_CONTEXTMENU:
  983.        Begin
  984.             If Designed Then Exit;
  985.             CheckMenuPopup(FPopupPos);
  986.        End;
  987.        Else Inherited ParentNotification(Msg);
  988.      End;
  989.      {$ENDIF}
  990.  
  991.      {$IFDEF Win95}
  992.      Inherited ParentNotification(Msg);
  993.      {$ENDIF}
  994. End;
  995.  
  996. Function TListView.GetItemIndex:LongInt;
  997. {$IFDEF OS2}
  998. Var RecordCore:PListViewRecord;
  999. {$ENDIF}
  1000. {$IFDEF WIN32}
  1001. Var t:LongInt;
  1002. {$ENDIF}
  1003. Begin
  1004.      Result:=-1;
  1005.      If Handle=0 Then Exit;
  1006.      {$IFDEF OS2}
  1007.      RecordCore:=Pointer(WinSendMsg(Handle,CM_QUERYRECORDEMPHASIS,
  1008.                          CMA_FIRST,CRA_SELECTED));
  1009.      If RecordCore<>Nil Then Result:=RecordCore^.Node.Index;
  1010.      {$ENDIF}
  1011.      {$IFDEF WIN32}
  1012.      For t:=0 To ItemCount-1 Do
  1013.      Begin
  1014.            If SendMessage(Handle,LVM_GETITEMSTATE,t,LVIS_SELECTED OR LVIS_FOCUSED)<>0 Then
  1015.            Begin
  1016.                 Result:=t;
  1017.                 exit;
  1018.            End;
  1019.      End;
  1020.      {$ENDIF}
  1021. End;
  1022.  
  1023. Procedure TListView.SetItemIndex(NewValue:LongInt);
  1024. {$IFDEF WIN32}
  1025. Var Item:LV_ITEM;
  1026. {$ENDIF}
  1027. Begin
  1028.      If Handle=0 Then Exit;
  1029.      If ((NewValue<0)Or(NewValue>FNodes.Count-1)) Then Exit;
  1030.  
  1031.      {$IFDEF OS2}
  1032.      WinSendMsg(Handle,CM_SETRECORDEMPHASIS,LongWord(Items[NewValue].FTreeRec),
  1033.                 MPFROM2SHORT(1,CRA_SELECTED));
  1034.      {$ENDIF}
  1035.      {$IFDEF WIN32}
  1036.      Item.StateMask:=LVIS_SELECTED;
  1037.      Item.State:=LVIS_SELECTED;
  1038.      SendMessage(Handle,LVM_SETITEMSTATE,NewValue,LongWord(@Item));
  1039.      {$ENDIF}
  1040. End;
  1041.  
  1042. Function TListView.NodeFromPoint(pt:TPoint):TListViewNode;
  1043. Var t:LongInt;
  1044.     rec:TRect;
  1045. Begin
  1046.     For t:=0 To ItemCount-1 Do
  1047.     Begin
  1048.         result:=Items[t];
  1049.         rec:=result.ItemRect;
  1050.         If ((pt.X>=rec.Left)And(pt.X<=rec.Right)) Then
  1051.           If ((pt.Y>=rec.Bottom)And(pt.Y<=rec.Top)) Then exit;
  1052.     End;
  1053.     result:=Nil;
  1054. End;
  1055.  
  1056. Procedure TListView.DrawDragRect;
  1057. Begin
  1058.      If Canvas = Nil Then Exit;
  1059.      Canvas.Pen.Mode:=pmNot;
  1060.      Canvas.Pen.color:=clBlack;
  1061.      Canvas.Pen.Style:=psDot;
  1062.      Canvas.Rectangle(FDragRect);
  1063.      Canvas.Pen.Mode:=pmCopy;
  1064. End;
  1065.  
  1066. Procedure TListView.DragOver(Source:TObject;X,Y:LongInt;State:TDragState;Var Accept:Boolean);
  1067. Var Node:TListViewNode;
  1068. Label invalid;
  1069. Begin
  1070.      Node:=Nil;
  1071.      Inherited DragOver(Source,X,Y,State,Accept);
  1072.      If FShowDragRects Then
  1073.      Begin
  1074.           If Accept Then
  1075.           Begin
  1076.                Node:=NodeFromPoint(Point(X,Y));
  1077.                If Node<>Nil Then
  1078.                Begin
  1079.                     Case State Of
  1080.                        dsDragEnter:
  1081.                        Begin
  1082.                             CreateDragCanvas;
  1083.                             If FDragRectValid Then DrawDragRect; //Delete old
  1084.                             FDragRect := Node.ItemRect;
  1085.                             FDragRectValid:=True;
  1086.                             DrawDragRect;  //Draw New
  1087.                             DeleteDragCanvas;
  1088.                        End;
  1089.                        dsDragMove:
  1090.                        If Node<>FDragSelected Then
  1091.                        Begin
  1092.                             CreateDragCanvas;
  1093.                             If FDragRectValid Then DrawDragRect; //Delete old
  1094.                             FDragRect := Node.ItemRect;
  1095.                             FDragRectValid:=True;
  1096.                             DrawDragRect; //Draw New
  1097.                             DeleteDragCanvas;
  1098.                        End;
  1099.                        dsDragLeave:
  1100.                        Begin
  1101.                             If FDragRectValid Then
  1102.                             Begin
  1103.                                  FDragRectValid:=False;
  1104.                                  CreateDragCanvas;
  1105.                                  DrawDragRect; //Delete old
  1106.                                  DeleteDragCanvas;
  1107.                             End;
  1108.                        End;
  1109.                     End; //Case
  1110.                End
  1111.                Else Goto invalid;
  1112.           End
  1113.           Else
  1114.           Begin
  1115. invalid:
  1116.                If FDragRectValid Then
  1117.                Begin
  1118.                     FDragRectValid:=False;
  1119.                     CreateDragCanvas;
  1120.                     DrawDragRect; //Delete old
  1121.                     DeleteDragCanvas;
  1122.                End;
  1123.           End;
  1124.           FDragSelected:=Node;
  1125.      End;
  1126. End;
  1127.  
  1128. Procedure TListView.DragDrop(Source:TObject;X,Y:LongInt);
  1129. Begin
  1130.      If FDragRectValid Then
  1131.      Begin
  1132.           CreateDragCanvas;
  1133.           DrawDragRect; //Delete old
  1134.           DeleteDragCanvas;
  1135.           FDragRectValid:=False;
  1136.      End;
  1137.      Inherited DragDrop(Source,X,Y);
  1138. End;
  1139.  
  1140. Function TListView.GetSelect(Index:LongInt):Boolean;
  1141. {$IFDEF OS2}
  1142. Var RecordCore:PListViewRecord;
  1143.     Start:LongWord;
  1144. {$ENDIF}
  1145. {$IFDEF WIN32}
  1146. Var Start,Index1:LongInt;
  1147. {$ENDIF}
  1148. Begin
  1149.      Result:=False;
  1150.      If Handle=0 Then Exit;
  1151.      If ((Index<0)Or(Index>FNodes.Count-1)) Then Exit;
  1152.  
  1153.  
  1154.      {$IFDEF OS2}
  1155.      If Index=0 Then Start:=CMA_FIRST
  1156.      Else Start:=LongWord(Items[Index-1].FTreeRec);
  1157.  
  1158.      RecordCore:=Pointer(WinSendMsg(Handle,CM_QUERYRECORDEMPHASIS,
  1159.                          Start,CRA_SELECTED));
  1160.      If RecordCore<>Nil Then
  1161.      Begin
  1162.          If Start=CMA_FIRST Then
  1163.          Begin
  1164.               If RecordCore^.Node=Items[0].FTreeRec^.Node Then Result:=True;
  1165.          End
  1166.          Else
  1167.          Begin
  1168.               If RecordCore^.Node=Items[Index].FTreeRec^.Node Then Result:=True;
  1169.          End;
  1170.      End;
  1171.      {$ENDIF}
  1172.      {$IFDEF WIN32}
  1173.      If Index=0 Then Start:=-1
  1174.      Else Start:=Index;
  1175.  
  1176.      Index1:=SendMessage(Handle,LVM_GETNEXTITEM,Start,MakeLParam(LVNI_ALL Or LVNI_SELECTED,0));
  1177.      If Index1=Index Then Result:=True;
  1178.      {$ENDIF}
  1179. End;
  1180.  
  1181. Procedure TListView.SetSelect(Index:LongInt;NewValue:Boolean);
  1182. Var Value:LongInt;
  1183. Begin
  1184.      If Handle=0 Then Exit;
  1185.      If ((Index<0)Or(Index>FNodes.Count-1)) Then Exit;
  1186.  
  1187.      If NewValue Then Value:=1
  1188.      Else Value:=0;
  1189.  
  1190.      {$IFDEF OS2}
  1191.      WinSendMsg(Handle,CM_SETRECORDEMPHASIS,LongWord(Items[Index].FTreeRec),
  1192.                 MPFROM2SHORT(Value,CRA_SELECTED));
  1193.      {$ENDIF}
  1194. End;
  1195.  
  1196.  
  1197. Procedure TListView.MouseClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
  1198. Begin
  1199.      If OnMouseClick <> Nil Then OnMouseClick(Self,Button,ShiftState,X,Y);
  1200.      {no Inherited because Of CN_CONTEXTMENU, but Store the mouse Pos}
  1201.      FPopupPos := Point(X,Y);
  1202. End;
  1203.  
  1204. {$IFDEF WIN32}
  1205. Procedure TListView.MouseDblClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
  1206. Var Index:LongInt;
  1207.     HitTest:LV_HITTESTINFO;
  1208.     pt:TPoint;
  1209. Begin
  1210.      Inherited MouseDblClick(Button,ShiftState,X,Y);
  1211.      LastMsg.CallDefaultHandler;
  1212.      If Button=mbLeft Then
  1213.      Begin
  1214.           pt:=Point(X,Y);
  1215.           TransformClientPoint(pt,Self,Nil);
  1216.           HitTest.pt:=pt;
  1217.           HitTest.Flags:=LVHT_ONITEMICON;
  1218.           Index:=SendMessage(Handle,LVM_HITTEST,0,LongWord(@HitTest));
  1219.           If Index<>-1 Then
  1220.           Begin
  1221.                ItemSelect(Index);
  1222.                If OnItemSelect <> Nil Then OnItemSelect(Self,Index);
  1223.           End;
  1224.      End;
  1225. End;
  1226. {$ENDIF}
  1227.  
  1228. Begin
  1229. End.
  1230.  
  1231.  
  1232.