?
Solved

Listview ondragover event problem

Posted on 2005-04-20
13
Medium Priority
?
354 Views
Last Modified: 2010-04-05
It's difficult for me to explain this problem, but i try:

I'm just making a little ftp program that use a listview to display files and directory. I'm using the vsIcon style.

When i drag a file over my ftp listview the item under the mouse pointer became droptarget (i can see this by querying the droptarget property in the listview) and this is ok.
But when the mouse leave an item and move in an empty area of the control, the last overflyed item remain drop target !!
I need that in this situation no droptarget is acquired, also during the drag operation.

Can anyone help me?  

Best regards



0
Comment
Question by:balrom
  • 6
  • 5
12 Comments
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 13828207
here's an example i wrote for you
use th eOnDragOver event to see if you are over an item.
If you are, mark it as selected (assuming multiselect false on destination)
if you are not over an item, set selected to nil.
Then oin the Drop event, check the selected property so you know whether to replace or add to the list

procedure TForm1.ListView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
    var
        LI: TListItem;
    begin
        Accept := Source is TListview;

        LI := (Sender as TListView).GetItemAt(X,Y);
        if LI = nil then
        begin
            (Sender as TListView).Selected := nil;
        end
        else
        begin
            LI.Selected := True;
        end;
        caption := format('x = %d, y = %d', [x, y]);
    end;

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    begin
        if (Sender is TListView) and (Source is TListView) then
        begin
            with Sender as TListView do
            begin
                if (sender as TListview).Selected = nil then
                  Showmessage('dropped on empty space')
                else
                  showmessage('dropped on item with caption: ' + (sender as TListview).Selected.Caption);
            end;
        end
        else
          showmessage('not dropped');
    end;
0
 

Author Comment

by:balrom
ID: 13831607
Ok, this is a workaround , i have done the same thing with droptarget property of the listview

The problem is that when the mouse leave the items, they are not redrawed correctly (seems to be partial selected).

have you any idea?
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 13837102
it behaves a bit better if you put
        (sender as TListView).Repaint;
at the bottom of the DragOver event

0
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!

 

Author Comment

by:balrom
ID: 13837246
Thank you for your help TheRealLoki,
Yes, it look a bit (just a bit) better, but now when the mouse moves over the listview is flickering.

is there a better solution?
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 13838528
with just this code
I'm not getting any problem. I had been seeing bad redraws like you described, until I realised I was developing in a virtual machine, so the display wasn't so clever :)
when I ran the app in my main pc (windows 2000 as opposed to nt4 VM) it redrew fine.
Could this be the same issue for you?

procedure TForm1.ListView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
    var
        LI: TListItem;
    begin
        Accept := Source = Listview2; //is TListview;
        LI := (Sender as TListView).GetItemAt(X,Y);

        if LI = nil then
          (Sender as TListView).Selected := nil;
        else
          LI.Selected := True;
    end;

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    begin
        if (Sender is TListView) and (Source is TListView) then
        begin
            with Sender as TListView do
            begin
                if (sender as TListview).Selected = nil then
                  Showmessage('dropped on empty space')
                else
                  showmessage('dropped on item with caption: ' + (sender as TListview).Selected.Caption);
            end;
        end
        else
          showmessage('not dropped');
    end;
0
 

Author Comment

by:balrom
ID: 13841072
I'm not using a virtual machine, i'm using a windows 2000 pro machine with delphi 7.0.
The only difference is that i use business skin form component (of almedia dev www.almediadev.com) that are skinned wrappers of delphi base components.

I've done the same thing with the vcl standard lisview component, and have the same problem (bad/partial redraws).

regards
0
 

Author Comment

by:balrom
ID: 13841088
this is a bit more complicated?
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 13861891
hmm, can you post your code snippet here so i can test.
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 13922466
a lot of these problems can be acused by the COMCTL32.DLL file.
make sure you have the correct one for your machine, a newer one which resolves issues like this may be available
0
 

Author Comment

by:balrom
ID: 14696923
Are there news?
0
 

Author Comment

by:balrom
ID: 14719596
Ok, After a lot of work, i've found the solution, adding an else in ComCtrls.TCustomListView.DoDragOver:

procedure TCustomListView.DoDragOver(Source: TDragObject; X, Y: Integer; CanDrop: Boolean);
var
  Item: TListItem;
  Target: TListItem;
begin
  { This is the original code
  Item := GetItemAt(X, Y);
  if Item <> nil then
  begin
    Target := DropTarget;
    if (Item <> Target) or (Item = FLastDropTarget) then
    begin
      FLastDropTarget := nil;
      TDragObject(Source).HideDragImage;
      Update;
      if Target <> nil then
        Target.DropTarget := False;
      Item.DropTarget := CanDrop;
      Update;
      TDragObject(Source).ShowDragImage;
    end;
  end;}

  Item := GetItemAt(X, Y);
  if Item <> nil then
  begin
    Target := DropTarget;
    if (Item <> Target) or (Item = FLastDropTarget) then
    begin
      FLastDropTarget := nil;
      TDragObject(Source).HideDragImage;
      Update;
      if Target <> nil then
        Target.DropTarget := False;
      Item.DropTarget := CanDrop;
      Update;
      TDragObject(Source).ShowDragImage;
    end;
  end
  else // This added by me
  begin
     Target := DropTarget;
     FLastDropTarget := nil;
     TDragObject(Source).HideDragImage;
     if Target <> nil then
       Target.DropTarget := False;
     Update;
     TDragObject(Source).ShowDragImage;
  end;

end;

Regards,
  Bart
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 14882597
Closed, 500 points refunded.

modulo
Community Support Moderator
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

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…
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…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month14 days, 12 hours left to enroll

839 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