Recent

Author Topic: [SOLVED] Drag multiple items from TShellListView  (Read 405 times)

valter.home

  • Jr. Member
  • **
  • Posts: 75
[SOLVED] Drag multiple items from TShellListView
« on: April 21, 2021, 01:43:39 pm »
I have a TShellListView with the multiselect property set to True.
Below it I have a TFlowPanel which I use to create a preview of the images I drag into it from the TShellListView.
The code is simple:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.FlowPanelDragDrop(Sender, Source: TObject; X, Y: Integer);
  2. var
  3.   s: string;
  4. begin
  5.   if Source = ShellListView1 then
  6.   begin
  7.     for i := 0 to ShellListView1.Items.Count -1 do
  8.     begin
  9.       if ShellListView1.Items[i].Selected then
  10.       begin
  11.         s := ShellListView1.GetPathFromItem(ShellListView1.Items[i]);
  12.         memo1.Lines.Add(s);  // actually I do something else
  13.       end;
  14.     end;
  15.   end;    
  16. end;

Everything works fine by dragging one item at a time.
But I'd like it to be possible to drag multiple items at once.
The problem is that once you have selected several elements in the TShellListView, clicking on one of them to drag the whole group into the TFlowPanel obviously all the items are deselected apart from the one you just clicked.
So, what is multiselect for if it is not possible to use it as in windows explorer?
« Last Edit: April 23, 2021, 01:32:54 pm by valter.home »

jamie

  • Hero Member
  • *****
  • Posts: 4587
Re: Drag multiple items from TShellListView
« Reply #1 on: April 22, 2021, 12:34:51 am »
Well it seems to work with the trunk, Could also work with the last release too I am not sure there.

btw.
 the way you are doing it, it will only work if the selected items start from the top.

 so for each unselected item before the first selected item you will lose one count.

the for loop, you can do something like this..
Code: Pascal  [Select][+][-]
  1. XX := ShellListview.Selected.Index;
  2.  For I := XX to XX+ShellListView.SelCount-1 do
  3.     Memo.Lines.Add(ShellListView.Items[I].Caption);
  4.  
The only true wisdom is knowing you know nothing

valter.home

  • Jr. Member
  • **
  • Posts: 75
Re: Drag multiple items from TShellListView
« Reply #2 on: April 22, 2021, 11:26:56 am »
Hi jamie,
it could be that I have not explained well.

Quote
Well it seems to work with the trunk
when you say that it seems to work, you mean that after selecting (with multiselect = true) for example item 2, 4 and 7, when clicking on one of them, for example 4, to drag the group towards another window, items 2 and 7 do not deselect?
I have seen that the only way for them to remain all selected is to keep the shift or ctrl key pressed on the last selection and start dragging everything without releasing the key.
This behavior is very inconvenient for the user who is used with Windows to select what he wants and then click on any element to drag them all together.

Quote
the way you are doing it, it will only work if the selected items start from the top
it is not clear to me what you mean.
Currently the only way to copy the selected items from the TShellListView to the TFlowPanel is to use a TButton with the code I posted that sends them without using drag (but I don't like it). The TMemo shows exactly the selected items.
Your code seems to me that it takes elements one after the other starting from the first one selected but if the user used ctrl to skip some of them it would not work.
Am I doing something wrong?


valter.home

  • Jr. Member
  • **
  • Posts: 75
Re: Drag multiple items from TShellListView
« Reply #3 on: April 23, 2021, 01:29:12 pm »
Ok guys, I think I've solved it.
The code is not the best but it seems to work well.
With the property multiselect = true you can select one or more items from TShellListView using the cursor with either the CTRL key or the SHIFT key pressed and also select items in succession directly with the mouse.
The problem is that once you have selected the items and released the mouse button, a subsequent click on one of the selected items to carry out the drag as you normally do in Windows results in the deselection of all the other items.

With this code, the whole group of items remains selected and you can drag one to drag them all.

I used a global variable but it can be optimized with a class.
If anyone wants to try it and suggest any corrections, just drag a TShellListView, a TMemo and a TButton onto the form, setting the Multiselect and DragMode values.


Code: Pascal  [Select][+][-]
  1. var
  2.   Form1: TForm1;
  3.   ItemsGroup: TStringList;
  4.  
  5. { TForm1 }
  6.  
  7. function GetKeyPressed(const VKeyCode: Integer): Boolean;
  8. begin
  9.   Result := GetKeyState(VKeyCode) and $80 <> 0;
  10. end;
  11.  
  12. procedure TForm1.FormCreate(Sender: TObject);
  13. begin
  14.   ItemsGroup:=TStringList.Create;
  15. end;
  16.  
  17. procedure TForm1.ShellListView1MouseDown(Sender: TObject; Button: TMouseButton;
  18.   Shift: TShiftState; X, Y: Integer);
  19. var
  20.   i: integer;
  21. begin
  22.   if ShellListView1.SelCount>0 then
  23.   begin
  24.     if not ((GetKeyPressed(VK_CONTROL)) or (GetKeyPressed(VK_SHIFT))) then
  25.     begin
  26.       if ItemsGroup.IndexOf(ShellListView1.Selected.Index.ToString) <> -1 then
  27.       begin
  28.         for i:=0 to ItemsGroup.Count-1 do
  29.           ShellListView1.Items[ItemsGroup[i].ToInteger].Selected:=true;
  30.       end
  31.       else
  32.       begin
  33.         ItemsGroup.Clear;
  34.         ItemsGroup.Add(ShellListView1.Selected.Index.ToString);
  35.       end;
  36.     end
  37.     else
  38.     begin
  39.       ItemsGroup.Clear;
  40.       for i := 0 to ShellListView1.Items.Count -1 do
  41.         if ShellListView1.Items[i].Selected then
  42.           ItemsGroup.Add(i.ToString);
  43.     end;
  44.   end
  45.   else
  46.     ItemsGroup.Clear;
  47. end;
  48.  
  49. procedure TForm1.ShellListView1MouseUp(Sender: TObject; Button: TMouseButton;
  50.   Shift: TShiftState; X, Y: Integer);
  51. var
  52.   i: integer;
  53. begin
  54.   if ItemsGroup.Count=1 then
  55.   begin
  56.     ItemsGroup.Clear;
  57.     for i := 0 to ShellListView1.Items.Count -1 do
  58.       if ShellListView1.Items[i].Selected then
  59.         ItemsGroup.Add(i.ToString);
  60.   end;
  61. end;
  62.  
  63. procedure TForm1.Button1Click(Sender: TObject);
  64. var
  65.   i: integer;
  66. begin
  67.   Memo1.Clear;
  68.   for i:=0 to ItemsGroup.Count-1 do
  69.      Memo1.Lines.Add(ItemsGroup[i]);
  70. end;
  71.  
  72. procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);
  73. var
  74.   i: integer;
  75.   path: string;
  76. begin
  77.     Memo1.Clear;
  78.     for i:=0 to ItemsGroup.Count-1 do
  79.     begin
  80.       path:= ShellListView1.GetPathFromItem(ShellListView1.Items[ItemsGroup[i].ToInteger]);
  81.       Memo1.Lines.Add('Index: '+ItemsGroup[i]+'  Path: '+ path);
  82.     end;
  83.     for i := 0 to ShellListView1.Items.Count -1 do
  84.       ShellListView1.Items[i].Selected:=false;
  85.     ItemsGroup.Clear;
  86. end;
  87.  
  88. procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;
  89.   State: TDragState; var Accept: Boolean);
  90. begin
  91.   Accept:=true;
  92. end;


 

TinyPortal © 2005-2018