balrom
asked on
Listview ondragover event problem
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
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
ASKER
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?
The problem is that when the mouse leave the items, they are not redrawed correctly (seems to be partial selected).
have you any idea?
it behaves a bit better if you put
(sender as TListView).Repaint;
at the bottom of the DragOver event
(sender as TListView).Repaint;
at the bottom of the DragOver event
ASKER
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?
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?
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(S ender, 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(S ender, 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.Captio n);
end;
end
else
showmessage('not dropped');
end;
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(S
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(S
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.Captio
end;
end
else
showmessage('not dropped');
end;
ASKER
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
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
ASKER
this is a bit more complicated?
hmm, can you post your code snippet here so i can test.
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
make sure you have the correct one for your machine, a newer one which resolves issues like this may be available
ASKER
Are there news?
ASKER
Ok, After a lot of work, i've found the solution, adding an else in ComCtrls.TCustomListView.D oDragOver:
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).HideDr agImage;
Update;
if Target <> nil then
Target.DropTarget := False;
Item.DropTarget := CanDrop;
Update;
TDragObject(Source).ShowDr agImage;
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).HideDr agImage;
Update;
if Target <> nil then
Target.DropTarget := False;
Item.DropTarget := CanDrop;
Update;
TDragObject(Source).ShowDr agImage;
end;
end
else // This added by me
begin
Target := DropTarget;
FLastDropTarget := nil;
TDragObject(Source).HideDr agImage;
if Target <> nil then
Target.DropTarget := False;
Update;
TDragObject(Source).ShowDr agImage;
end;
end;
Regards,
Bart
procedure TCustomListView.DoDragOver
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).HideDr
Update;
if Target <> nil then
Target.DropTarget := False;
Item.DropTarget := CanDrop;
Update;
TDragObject(Source).ShowDr
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).HideDr
Update;
if Target <> nil then
Target.DropTarget := False;
Item.DropTarget := CanDrop;
Update;
TDragObject(Source).ShowDr
end;
end
else // This added by me
begin
Target := DropTarget;
FLastDropTarget := nil;
TDragObject(Source).HideDr
if Target <> nil then
Target.DropTarget := False;
Update;
TDragObject(Source).ShowDr
end;
end;
Regards,
Bart
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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(S
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(S
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.Captio
end;
end
else
showmessage('not dropped');
end;