[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Select subItem in TListView

Posted on 2004-04-21
10
Medium Priority
?
1,935 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
Independent Software Vendors: 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 500 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

650 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