You might be interested in the attached fragment, which I posted to the mailing list a while back. It simulates the windows file Drag and drop calls using gtk calls. I would supply a patch to put it in the LCL, only I am not sure where to put it.
Colin
type
  TMainForm = class(TForm)
    procedure WMDropFiles(var Message: TMessage); message WM_DROPFILES;
  end;

procedure TMainForm.WMDropFiles(var Message: TMessage);
var
  Strings: TStringList;
  i: Integer;
begin
  Strings := DroppedFiles(Message);
  try
    for i := 0 to Strings.Count-1 do
      LoadFile(Strings[i]);
  finally
    Strings.Free;
  end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Handle, True);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  if HandleAllocated then
    DragAcceptFiles(Handle, False);
end;

var
  Targets: array [0..2] of TGtkTargetEntry = ((target:'text/plain'; flags:0; info:0), (target:'text/uri-list'; flags:0; info:1), (target:'STRING'; flags:0; info:1));

function DropCallBack(widget: PGtkWidget; dc: PGdkDragContext; x, y: gint; selection: PGtkSelectionData; info, t: guint; data: gPointer): GBoolean; cdecl;
var
  list: PGList;
  Message: TMessage;
begin
  if (data <> nil) and (selection <> nil) and (selection^.length >= 0) then begin
    list := dc^.targets;
    while list <> nil do begin
      if (selection^.data <> nil) and (StrPos(PChar(selection^.data), 'file://') = PChar(selection^.data)) then begin
        Message.Msg := WM_DROPFILES;
        Message.lParam := LongInt(selection^.data);
        TWinControl(data).Dispatch(Message);
        Exit;
      end;
      list := list^.next;
    end;
  end;
end;

function DroppedFiles(var Message: TMessage):TStringList;
var
  i: Integer;
begin
  Result := TStringList.Create;
  try
    Result.Text := PChar(Message.lParam);
    for i := 0 to Result.Count-1 do
      if Pos('file://', Result[i]) = 1 then
        Result[i] := Copy(Result[i], 8, Length(Result[i]));
  except
    Result.Free;
    Raise;
  end;
end;

procedure DragAcceptFiles(Handle: THandle; Enabled: Boolean);
begin
  if Enabled then begin
    gtk_drag_dest_set(PGtkWidget(Handle), GTK_DEST_DEFAULT_ALL, @Targets[0], Length(Targets), GDK_ACTION_COPY);
    gtk_signal_connect(PGtkObject(Handle), 'drag_data_received', TGTKSignalFunc(@DropCallBack), gPointer(FindOwnerControl(Handle)));
  end else
    gtk_drag_dest_unset(PGtkWidget(Handle));
end;

Reply via email to