Solved

Select subItem in TListView

Posted on 2004-04-21
10
1,684 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
  • 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi 10 Seattle Dataset Actions 5 79
URL for downloading Google Chrome for Win XP 2 126
Create a path if not exists 7 69
Delphi and Access based Enumeration 9 48
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

863 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now