Solved

Select subItem in TListView

Posted on 2004-04-21
10
1,801 Views
Last Modified: 2010-05-18
I am using Delphi 5.  
I have a TListview with the ViewStyle as vsReport.  It has 8 columns and the number of rows varies.  I need some code to get the string that is located where the user double clicks on the TListView.  No mater what subitem they click on.  

Thanks

Rich
0
Comment
Question by:coondog091800
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
  • 2
10 Comments
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10883432

This will give you the first column

 ListView1.Selected.Caption

This will give you the additional columns:

 ListView1.Selected.Subitems[n]

WHere n is the column number

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10883443
IM sorry, that is assuming you have rowselect = true

SHane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10883503
procedure TForm1.ListView1DblClick(Sender: TObject);
var
 MP: TPoint;
 Pt: TSmallPoint;
 LI: TListItem;
begin
GetCursorPos(MP);
Pt := PointToSmallPoint(ListView1.ScreenToClient( MP ));
LI := ListView1.GetItemAt( pt.X, pt.Y );
if LI <> nil then
 ShowMessage(LI.SubItems[1]);
end;

Shane
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:shaneholmes
ID: 10883546
If you want to determine the Column of the item selected,  you need to get the item  like I show above, and prbably manually determine which column was clicked by comparinng to column widths.

Shane
0
 
LVL 17

Expert Comment

by:mokule
ID: 10884061
Try this

var
  SelTxt: string;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  l: TListItem;
  i: integer;
  w: integer;
begin
 l := ListView1.GetItemAt( 3, Y );
 SelTxt := '';
 if l <> nil then
   begin
   w := 0;
   for i := 0 to ListView1.Columns.Count-1 do
     begin
     w := w + ListView1.Column[i].Width;
     if w >= X then
       begin
       if i = 0 then
         SelTxt := l.Caption
       else
         SelTxt := l.SubItems[i-1];
       break;
       end;
     end;
   end;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
  // do something with SelTxt
end;
0
 
LVL 3

Expert Comment

by:MikProg
ID: 10886255
mokule: you miss partially scrolled listview so X is not position in list columns but position in list window. From now I can figure out how to find value of scroll offset.

BOOL ListView_GetItemRect(
    HWND hwnd,       
    int i,       
    RECT FAR *prc,       
    int code      
   );      
PRC.LEFT returns negative value of offset.

 l := ListView1.GetItemAt( 3, Y );
if not Assigned(l) then
  exit;
 SelTxt := '';
r.Left:=LVIR_BOUNDS;
 ListView_GetItemRect(Listview1.Handle,l.Index,r,LVIR_BOUNDS);
 w:=r.left;

0
 
LVL 17

Expert Comment

by:mokule
ID: 10886524

Yes. You are right. But You don't solve the problem :(
0
 
LVL 17

Accepted Solution

by:
mokule earned 125 total points
ID: 10887176
Thanks to MikProg hint I think that this time I solve the problem to the end.

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const
  LVM_FIRST = $1000;
  LVM_GETITEMRECT = (LVM_FIRST + 14);
  LVIR_BOUNDS = 0;
var
  l: TListItem;
  i: integer;
  w: integer;
  r: TRect;
begin
  l := nil;
  for i := 0 to ListView1.Items.Count-1 do
    begin
    r.Left := LVIR_BOUNDS;
    SendMessage(ListView1.Handle,LVM_GETITEMRECT,WPARAM(i),LPARAM(@r));
    if (Y > r.Top) and (Y < r.Bottom) then
      begin
      l := ListView1.Items[i];
      break;
      end;
    end;
 SelTxt := '';
 if l <> nil then
   begin
   w := r.Left;
   for i := 0 to ListView1.Columns.Count-1 do
     begin
     w := w + ListView1.Column[i].Width;
     if w >= X then
       begin
       if i = 0 then
         SelTxt := l.Caption
       else if l.SubItems.Count >= i then
         SelTxt := l.SubItems[i-1];
       break;
       end;
     end;
   end;
end;
0
 
LVL 3

Expert Comment

by:MikProg
ID: 10896210
mokule: We want to grab points fast. We are wrong. The Easiest Way To Get Display Rectangle of List Item Is to Call
   DisplayRect function of TListItem class :(
Althought both answers were right but we wrong. Therfore why you define LVM_ constants they definitions included in CommCtrl.pas (where you can find ListView_GetItemRect definition. My piece of code works well no need to send messages).
0
 
LVL 17

Expert Comment

by:mokule
ID: 10896953
MikProg
Thanks again.

CommCtrl isn't appended to the uses automatically and I've omitted it somehow.

If You've tested Your answer You would know that it didn't work. Though You may argue that the wrong line is from my code but something has had to be done with it.
To be concrete. After scrolling this doesn't work.
 l := ListView1.GetItemAt( 3, Y );
It was this what had to be changed.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question