Bonjour,
Je désire pouvoir faire un glisser d'une application contenant un composant TListViewFile vers une autre de mes applications Delphi.
Le programme émetteur avec TListViewFile dépose bien dans le presse-papiers une information de type CF_HDROP avec le nom du fichier.
Par contre le programme récepteur ne récupère rien ( il ne rentre même pas dans ListBox1DragDrop) . Le curseur interdit le déposer. Pourquoi ?
D'avance merci.

Dans le programme émetteur qui contient le composant TListViewFile j'ai :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// ******************************************
procedure CopyFilesToClipboard(Filenames: TStrings);
// Trouvé sur internet 
var
  i, len: Integer; 
  hMem: THandle; 
  ptr: PByte; 
  dropfiles: PDropFiles; 
begin 
  // On commence par récupérer la longueur totale de la "liste" de chaînes 
  len:= 0; 
  for i:= 0 to Filenames.Count - 1 do 
    Inc(len, Length(Filenames[i]) + 1); 
  if len <> 0 then 
  begin 
    Inc(len); // Ajout d'un octet pour le zéro terminal 
    // Allocation d'un buffer pour la structure _DROPFILES + la chaîne complète 
    hMem:= GlobalAlloc(GMEM_MOVEABLE, SizeOf(_DROPFILES) + len); 
    dropFiles:= GlobalLock(hMem); 
    dropFiles.pFiles:= SizeOf(_DROPFILES); 
    dropFiles.pt:= Point(0, 0); 
    dropFiles.fNC:= false; 
    dropFiles.fWide:= false; 
    // On positionne un pointeur juste après la structure 
    ptr:= Pointer(Integer(dropFiles) + SizeOf(_DROPFILES)); 
    // Et on copie les chemins en les séparant par des zéros 
    for i:= 0 to Filenames.Count - 1 do 
    begin 
      Move(Filenames[i][1], ptr^, Length(Filenames[i])); 
      Inc(Integer(ptr), Length(Filenames[i])); 
      ptr^:= 0; 
      Inc(Integer(ptr)); 
    end; 
    // La "liste" de chaînes doit être terminée par un autre zéro 
    ptr^:= 0; 
    // On a donc : StructureChemin1#0Chemin2#0#0 
    // Ne pas oublier de dévérouiller la zone mémoire 
    GlobalUnlock(hMem); 
    // Il ne reste plus qu'à injecter ça dans le presse-papier 
    with ClipBoard do 
    begin 
      Open; 
      Clear; 
      SetAsHandle(CF_HDROP, hMem); 
      Close 
    end;
  end; 
End;
// ******************************************
procedure TForm1.ListViewFile1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
var
  LISTE : TSTRINGLIST;
  INFO : String;
I : INTEGER;
begin
   LISTE:= TSTRINGLIST.CREATE; { Contruire l'objet}
  try
// Multisélection :
  FOR I:=1 TO ListViewFile1.Items.Count DO
  Begin
  IF ListViewFile1.Items[I-1].Selected Then
  Begin
  INFO:=ListViewFile1.Directory+'\'+ListViewFile1.Items[I-1].caption;
  LISTE.ADD(INFO);
  End;
  End;
 
  // récupérer le chemin et le nom du fichier pointé dans ListViewFile1
//  INFO:=ListViewFile1.Directory+'\'+ListViewFile1.Items[ListViewFile1.ItemIndex].caption;
//  LISTE.ADD(INFO); 
 
  CopyFilesToClipboard(LISTE);
  finally
     LISTE.FREE; { détruit l'objet }
  end;
end;
// *****************************************
// *****************************************
Le programme récepteur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
ListBox1.DrapMode est à dmAutomatic
// ***********************************************
procedure TForm1.FormCreate(Sender: TObject);
  begin
    //la fenêtre accepte le glissement d'objets
    DragAcceptFiles(Handle, True);
  ...........................
End;
// *************************************
// *************************************
// copies filenames from the clipboard to "Filenames" if there
// are any. the clipboard can contain file- and directory names.
procedure PasteFilenamesFromClipboard;
// Trouvé sur internet
var
  hDropHandle: HDROP;
  szBuffer: PChar;
  iCount, iIndex: Integer;
  iLength: Integer;
begin
  // lock clipboard
  Clipboard.Open;
  try
  // does clipboard contain filenames?
  if (Clipboard.HasFormat(CF_HDROP)) then
  begin
    // get drop handle from the clipboard
    hDropHandle := Clipboard.GetAsHandle(CF_HDROP);
    // enumerate filenames
    iCount := DragQueryFile(hDropHandle, $FFFFFFFF, nil, 0);
    for iIndex := 0 to iCount - 1 do
    begin
      // get length of filename
      iLength := DragQueryFile(hDropHandle, iIndex, nil, 0);
      // allocate the memory, the #0 is not included in "iLength"
      szBuffer := StrAlloc(iLength + 1);
      try
      // get filename
      DragQueryFile(hDropHandle, iIndex, szBuffer, iLength + 1);
      Form1.ListBox1.ITEMS.Add(szBuffer);
      finally // free the memory
        StrDispose(szBuffer);
      end;
    end;
  end;
  finally
    // unlock clipboard
    Clipboard.Close;
  end;
end;
// *************************************
procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := True;
end;
// *************************************
procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
   PasteFilenamesFromClipboard;
end;
// *************************************