Drag and Drop from the Explorer


The ability to accept items dragged from the Windows Explorer is something that users today expect. The main reason is that the user is able to open a file much faster by dragging it from the Explorer than by using the common Open dialog box.

The first thing that we have to do in order to accept items from the Windows Explorer is register the window that should accept the dropped items. To do this, we have to call the DragAcceptFiles API function. The DragAcceptFiles function accepts two parameters: the handle of the window that should accept dropped items and a Boolean parameter that specifies whether or not the window should accept dropped items.

procedure DragAcceptFiles(Wnd: HWND; Accept: BOOL);

We actually have to call the DragAcceptFiles function twice. First, we have to call it in the OnCreate event handler to register the main form as the drop target, and then in the OnDestroy or OnClose event handlers to discontinue accepting dropped items. In order to use the DragAcceptFiles function, you have to add the ShellAPI unit to the uses list (see Listing 20-21).

Listing 20-21: Registering the main form as the drop target

image from book
unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics,   Controls, Forms, Dialogs, ShellAPI; type   TForm1 = class(TForm)     procedure FormDestroy(Sender: TObject);     procedure FormCreate(Sender: TObject);   private     { Private declarations }   public     { Public declarations }   end; procedure TForm1.FormCreate(Sender: TObject); begin   DragAcceptFiles(Handle, True); end; procedure TForm1.FormDestroy(Sender: TObject); begin   DragAcceptFiles(Handle, False); end; end.
image from book

Once a window has been registered with the DragAcceptFiles function, it is able to process the WM_DROPFILES message. To accept the files dropped from the Explorer, we have to handle the WM_DROPFILES message.

type   TForm1 = class(TForm)   public     procedure WMDropFiles(var Message: TWMDropFiles);       message WM_DROPFILES;   end; procedure TForm1.WMDropFiles(var Message: TWMDropFiles); begin end;

Inside the WM_DROPFILES message handler, we have to do the following:

  1. Determine how many files were dropped to the form.

  2. Retrieve the file names of all dropped files.

  3. Finish the drag and drop process by calling DragFinish.

To determine the number of dropped files, we have to call the DragQueryFile function:

function DragQueryFile(Drop: HDROP;   FileIndex: UINT; FileName: PChar; cb: UINT): UINT;

The Drop parameter identifies the structure that contains the names of files dropped to the form. The value of the Drop parameter is always specified in the Drop field of the WM_DROPFILES message. The FileIndex parameter specifies the index of the file to query for the file name. If the value of the FileIndex parameter is between 0 and the number of dropped files, the DragQueryFile function writes the file name to the buffer specified in the File- Name parameter. If the value of the FileIndex parameter is $FFFFFFFF (or 0xFFFFFFFF in C++), the DragQueryFile function returns the total number of dropped files. When determining the number of dropped files, you can pass nil as the FileName buffer, as shown in Listing 20-22.

Listing 20-22: Determining the number of dropped files

image from book
procedure TForm1.WMDropFiles(var Message: TWMDropFiles); var   dropCount: Integer; begin   dropCount := DragQueryFile(Message.Drop, $FFFFFFFF, nil, 0);   try   finally     DragFinish(Message.Drop);   end; end;
image from book

After we determine the number of dropped files, we have to write a loop that will read the file names of all dropped files and create a buffer large enough to hold long file names. The easiest way to create a file name buffer is to declare an array of characters. Since Windows XP with SP2 allows file names up to 2,048 characters long, you should declare an array that accepts that many characters plus one for the terminating null character.

Listing 20-23 shows the entire WM_DROPFILES message handler that adds the dropped file names to a TListBox component.

Listing 20-23: Working with items dropped from the Windows Explorer

image from book
procedure TForm1.WMDropFiles(var Message: TWMDropFiles); var   dropCount: Integer;   nameBuffer: array[0..2048] of Char;   i: Integer; begin   dropCount := DragQueryFile(Message.Drop, $FFFFFFFF, nil, 0);   try     for i := 0 to Pred(dropCount) do     begin       { process each file name }       DragQueryFile(Message.Drop, i, nameBuffer, SizeOf(nameBuffer));       ListBox1.Items.Add(string(nameBuffer));     end;         // for   finally     DragFinish(Message.Drop);   end;          // try..finally end; 
image from book

image from book
Figure 20-8: Dragging and dropping from the Windows Explorer



Inside Delphi 2006
Inside Delphi 2006 (Wordware Delphi Developers Library)
ISBN: 1598220039
EAN: 2147483647
Year: 2004
Pages: 212
Authors: Ivan Hladni

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net