Check which subitem of a TListView's ListItem was clicked (Views: 708)
Problem/Question/Abstract: I have a listview that is displayed using the vsReport view style. It contains a number of columns, and subsequently, the listitems have corresponding subitems. I want to give the user the ability to edit the text in any of the subitems by just clicking on the subitem. How does one do this? I can't seem to figure out a straight forward way to capture the subitem index when a listitem is clicked. Answer: The following is copied and pasted from 2 different units in an old D3 project. The version of ListView_SubItemHitTest in D3 didn't allow for subitems to be "hit-tested" I think because it wasn't available in the version of ComCtl32.DLL at the time. uses CommCtrl, ComCtrls; type { Updated version of TLVHitTestInfo (has also been updated in D5) } PLVHitTestInfoNew = ^TLVHitTestInfoNew; TLVHitTestInfoNew = record Pt: TPoint; Flags: Integer; iItem: Integer; iSubItem: Integer; end; {Updated version of CommCtrl function} function ListView_SubItemHitTest(hwndLV: HWND; var lvhti: TLVHitTestInfoNew): Integer; begin Result := SendMessage(hwndLV, LVM_SUBITEMHITTEST, 0, Longint(@lvhti)); end; function ListViewSubItemHitTest(Handle: HWND; X: Integer; Y: Integer): Integer; var HitTest: TLVHitTestInfoNew; begin HitTest.pt.X := X; HitTest.pt.Y := Y; {Calls ListView_SubItemHitTest from *this* unit, not from CommCtrl.pas} ListView_SubItemHitTest(Handle, HitTest); Result := HitTest.iSubItem; end; procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Item: TListItem; iSubItem: Integer; begin Item := ListView1.GetItemAt(X, Y); if Assigned(Item) then begin iSubItem := ListViewSubItemHitTest(ListView1.Handle, X, Y); {etc.} end; end; |