Mirror

Drag and Drop Thread (Views: 100)


Problem/Question/Abstract:

This demo shows how to perform a drag drop wich does not block the user interface during the copying of large files.

Answer:

{ Drag & Drop Thread
  Copyright (c) 2000, 2001 by E.J.Molendijk

  This class is a part of:
  "Drag and Drop Component Suite" (http://www.melander.dk).

  Explained:
  When you create the thread, it will copy the filenames of the specified
  DropFileSource. These filenames will be used by thread to perform a
  drag&drop operation. The calling thread continues uninterupted.

  Usage is very simple:
    TDragDropThread.Create(DropFileSource1);

  Drag&Drop Thread info Q139408:
    http://support.microsoft.com/support/kb/articles/Q139/4/08.asp
}

unit DragDropThread;

interface

uses
  Classes, DropSource, ActiveX, Windows;

type
  TDragDropThread = class(TThread)
  private
    { Private declarations }
    FFiles: string;
  protected
    procedure Execute; override;
  public
    constructor Create(DropFileSource: TDropFileSource);
  end;

implementation

{ TDragDropThread }

constructor TDragDropThread.Create(DropFileSource: TDropFileSource);
begin
  // Thread will start immediately after creation
  inherited Create(False);

  // Copy filenames from supplied DropFileSource
  FFiles := DropFileSource.Files.Text;

  // This thread disappeard when it finishes
  FreeOnTerminate := True;
end;

procedure TDragDropThread.Execute;
var
  DropFileSource: TDropFileSource;
  pt: TPoint;
  hwndAttach: HWND;
  dwAttachThreadID, dwCurrentThreadID: DWORD;

begin
  // Get handle of window under mouse-cursor
  GetCursorPos(pt);
  hwndAttach := WindowFromPoint(pt);
  Assert(hwndAttach <> 0, 'Unable to find window with drag-object');

  // Get thread ID's
  dwAttachThreadID := GetWindowThreadProcessId(hwndAttach, nil);
  dwCurrentThreadID := GetCurrentThreadId();

  // Attach input queues if necessary
  if (dwAttachThreadID <> dwCurrentThreadID) then
    AttachThreadInput(dwAttachThreadID, dwCurrentThreadID, True);

  // Initialize Ole for this thread
  OleInitialize(nil);
  try
    // create dropsource
    DropFileSource := TDropFileSource.Create(nil);
    try
      DropFileSource.Files.Text := FFiles;
      // start drag&drop
      DropFileSource.Execute;
    finally
      // cleanup dropsource
      DropFilesource.Free;
    end;
  finally
    // cleanup Ole
    OleUninitialize;
  end;
  // Restore input queues settings
  if (dwAttachThreadID <> dwCurrentThreadID) then
    AttachThreadInput(dwAttachThreadID, dwCurrentThreadID, False);
end;

end.

<< Back to main page