Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Drag & Drop of a file into my application

244 views
Skip to first unread message

Patrick Schmidt - STEP Software GmbH, Germany

unread,
Nov 13, 2002, 12:26:30 PM11/13/02
to
I want to drag a file from a windows-explorer and and drag it
to my application in a TShellTreeView. How can I force my
application to accept the file and what kind of source is the
file-object from the explorer.
In Delphi-Help I only can find Drag&Drop within the same
application but no hint how to handle a source from "outside".

Thanks for help.
Patrick Schmidt
(Delphi 6)


George Wynne

unread,
Nov 19, 2002, 5:30:29 PM11/19/02
to
Amir,

I tried your code and it works great for any shortcuts on my desktop and
files in Windows Explorer. However, it does not seem to work for any
attachments in an email. The best I can do is to drag the attachment to the
desktop, and then drag the attachment to my app. So, I guess my OS
(Windows2000) is using a different API. I have not been able to figure out
what that API would be. Any insights?

Thanks,
George

"Amir Zolic" <am...@diginaut.com> wrote in message
news:3dd3...@newsgroups.borland.com...
> "Patrick Schmidt - STEP Software GmbH, Germany" <p...@step-gmbh.de> wrote in
> message news:3dd2...@newsgroups.borland.com...

> Use DragAcceptFiles() procedure to tell windows that your form or
> control wants to accept files dragged from Windows Exporer. After that you
> need to handle WM_DROPFILES message. If you want contol to accept files
you
> need to override control's WindowProc. Once you receive WM_DROPFILES
message
> call
>
> DragQueryFile( Message.WParam, $FFFFFFFF, nil, 0);
>
> to get number of files dragged, and after that call DragQueryFile()
> procedure to retreive each file (in fact you receive file names) that was
> dropped on your form/control. To end drag operation you should call
> DragFinish() procedure.
>
> Short example for form that should accept files.
>
> TMainForm = class(TForm)
> procedure WMDropFiles( var Msg: TMessage); message WM_DROPFILES;
> //...
> end
>
> procedure TMainForm.FormCreate(Sender: TObject);
> begin
> DragAcceptFiles( Handle, TRUE );
> end;
>
> procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
> begin
> DragAcceptFiles( Handle, FALSE );
> end;
>
> procedure TMainForm.WMDropFiles( var Msg: TMessage);
> var
> nCount : integer;
> nLength: integer;
> nIndex : integer;
> sFileName: String;
> bFound : Boolean;
> begin
> try
> nCount := DragQueryFile( Message.WParam, $FFFFFFFF, nil, 0);
> nIndex := 0;
> while ( nIndex < nCount ) do
> begin
> nLength := DragQueryFile( Message.WParam, nIndex, nil, 0);
> if nLength > 0 then
> begin
> Inc(nLength);
> SetLength( sFileName, nLength);
> DragQueryFile( Message.WParam, nIndex, PChar(sFileName), nLength);
> SetLength( sFileName, nLength);
> // sFileName contains name of the file/folder that was dropped
> // Do whatever you want with it
> Inc( nIndex );
> end;
> end;
> finally
> DragFinish( Message.WParam );
> end;
> end;
>
> Regards,
> Amir Zolic
> http://www.diginaut.com
> FolderWatch - http://www.diginaut.com/shareware/fw
>
>
>
>


Amir Zolic

unread,
Nov 21, 2002, 7:26:08 AM11/21/02
to

That is normal. WM_DROPFILES is used only for _file drag&drop_
operations. Since attachment is not a file it is logical it does not work.
In fact, as you can see from the example, only filename is 'dropped' not the
actual file. When you drag attachment to the desktop, Windows creates actual
file (that contains data attached to the email message) and after that you
can drag it to your appliaction.
If you would like to accept dragging from email software directly I
guess you should look at OLE and Data Transfer topic in MSDN
(Platform SDK->COM and ActiveX Object Services->COM->OLE and Data Transfer).
However, I have never used this directly so I can not help you with it.
I have seen and used before some components that automated this tasks. You
should search delphipages or torry's for components that allow OLE Drag&Drop
operations.
I hope this helps.

"George Wynne" <geo...@nssco.com> wrote in message
news:3dda...@newsgroups.borland.com...

Dieter Zimmermann

unread,
Nov 27, 2002, 4:03:15 AM11/27/02
to
Hi Patrick,

I don't know if you already got the solution for your problem.
If not may be this could give you some ideas for your project.

The code below is from a component I wrote after a long (struggling through)
internet session,
but for a listbox.
It uses the drag and drop possibilities as you mentioned.
I think you can easily adopt you TShellTreeView to this.

I wish you good luck
Dieter Zimmermann


unit DDListBox;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ShellAPI;

type
TDDListBox = class(TListBox)
private
{ Private-Deklarationen }
***********DragAndDrop******************************
procedure DropFiles(var aMsg : TWMDropFiles); message WM_DROPFILES;
***********DragAndDrop******************************
protected
{ Protected-Deklarationen }
procedure CreateWnd; override;
procedure DestroyWnd; override;
public
{ Public-Deklarationen }
published
{ Published-Deklarationen }
end;

procedure Register;

implementation

procedure TDDListBox.CreateWnd;
begin
inherited;
***********DragAndDrop******************************
DragAcceptFiles(handle, True);
***********DragAndDrop******************************
end;

procedure TDDListBox.DestroyWnd;
begin
inherited;
***********DragAndDrop******************************
DragAcceptFiles(handle, False);
***********DragAndDrop******************************
end;

procedure TDDListBox.DropFiles(var aMsg : TWMDropFiles);

var
DropCount : Integer;
BufferSize : Integer;
aFileName : PChar;
RetValue : Integer;
DropIndex : Integer;

begin

DropCount := DragQueryFile(aMsg.Drop, $FFFFFFFF, nil, 0)-1;

for DropIndex := 0 to DropCount do
begin

BufferSize := (DragQueryFile(aMsg.Drop, DropIndex, nil, 0)+1);

if (BufferSize < 255) then
begin

GetMem(aFileName,BufferSize);
RetValue := DragQueryFile(aMsg.Drop, DropIndex, aFileName,
BufferSize);

if (RetValue > 0) then
begin

Items.Add(StrPas(aFileName));

end;
FreeMem(aFileName,BufferSize);
end;

end;

DragFinish(aMsg.Drop);
inherited;

end;

procedure Register;
begin
RegisterComponents('Custom', [TDDListBox]);
end;

end.
"Patrick Schmidt - STEP Software GmbH, Germany" <p...@step-gmbh.de> schrieb im
Newsbeitrag news:3dd2...@newsgroups.borland.com...

0 new messages