Форум по Delphi программированию



Вернуться   Форум по Delphi программированию > Разное > Исходники и статьи
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 14.08.2012, 14:32
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию [ Исходник ] - TSimpleDragDrop: Drag & Drop файлов из программы в Проводник

Описание:
Невизуальный компонент TSimpleDragDrop. Реализует Drag & Drop файлов из программы в Проводник Windows.
Версия Delphi:
7
Свойства:
DropEffects: TDropEffects - определяет какие операции доступны: копирование, ссылка, перемещение
Методы:
function DragDrop(Directory: String; AFileName: String): Integer; overload;
function DragDrop(Directory: String; AFileList: TStrings): Integer; overload;
Первый работает с одним файлом, второй со списком.
Directory указывает на каталог в котором находятся файлы. AFileName и AFileList содержат имена файлов.
Возвращаемое значение:
Результат операции:
0 - отменено пользователем (нажал Esc) = DROPEFFECT_NONE
1 - файл скопирован = DROPEFFECT_COPY
2 - файл перемещен. Если поддерживает источник, то исходный файл будет удален = DROPEFFECT_MOVE
4 - создана ссылка на файл = DROPEFFECT_LINK
Пример:
В FileListBox отображаются *.jpg файлы, которые собственно и можно перетаскивать.
Вложения
Тип файла: rar SimpleDragDrop.rar (1.9 Кбайт, 131 просмотров)
Тип файла: rar SimpleDragDropTest.rar (1.3 Кбайт, 76 просмотров)
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 14.08.2012 в 14:34.
Ответить с цитированием
  #2  
Старый 14.08.2012, 14:47
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Это в ответ на это: http://www.delphisources.ru/forum/sh...ad.php?t=21864 ?
Ответить с цитированием
  #3  
Старый 14.10.2012, 15:58
Аватар для alexpac26
alexpac26 alexpac26 вне форума
Прохожий
 
Регистрация: 23.08.2011
Сообщения: 20
Репутация: 10
По умолчанию

Представляю класс который обеспечит перенос файлов в программу или вынос файлов из нее.

Код:
unit DropFileClass;

// procedure FromDropFiles(Sender: TObject);

interface

uses
  Windows, Messages, Classes, SysUtils, AppEvnts,
  Controls, ShellAPI, FileCtrl, ActiveX, ComObj, ShlObj;
type
  TDropEffect = (deNone, deCopy, deMove, deLink);

  TDropFile = class(TApplicationEvents, IDropSource)
    protected
      procedure ApplicationEventsMessage(var Msg: tagMSG; var Handled: Boolean); virtual;
      { IDropSource }
      function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: Longint): HResult; stdcall;
      function GiveFeedback(dwEffect: Longint): HResult; stdcall;
    public
      DropEffect: TDropEffect;
      Files: TStringList;
      OnDropFiles : TNotifyEvent;
      function DropOut(Directory: String; AFileName: String): Integer; overload;
      function DropOut(Directory: String; AFileList: TStrings): Integer; overload;
      function DropOut(AFileList: TStrings): Integer; overload;
      function DropOut(AFileName: String): Integer; overload;
      // методы для анализа
      function MouseMoveDrop(Sender: TObject; Shift: TShiftState; X, Y: Integer; offset: integer = 0):boolean;
      // конструктор
      constructor Create(AOwner: TWinControl);
      destructor Destroy; override;
  end;

// procedure DropFileEvent(Sender: TObject);

implementation

{ TDropFile }

procedure TDropFile.ApplicationEventsMessage(var Msg: tagMSG; var Handled: Boolean);
var nCount, nFile : UINT;
    sFileNm : string;
    dwChars : DWORD;
const QUERY_FILES_COUNT = UINT($FFFFFFFF);
begin
  if (Msg.message=WM_DROPFILES) and (Msg.hwnd = TWinControl(self.Owner).Handle) then begin
    if @self.OnDropFiles=nil then begin
      // защита от выполнения
      Handled:=true;
      exit;
    end;
    // Событие поймано.
    // отключаем пост обработку
    Handled:=true;
    // обрабатываем событие
    nCount := DragQueryFile( Msg.wParam, QUERY_FILES_COUNT, nil, 0);
    if nCount = 0 then Exit;
    // чистим лист
     Files.Clear;
    try
      for nFile := 0 to nCount-1 do begin
        // GrцЯe des Buffers bestimmen
        dwChars := DragQueryFile( Msg.wParam, nFile, nil,0);
        Inc( dwChars);  // Platz fьr Arnold
        SetLength( sFileNm, dwChars);
        // Dateinamen abrufen
        dwChars := DragQueryFile( Msg.wParam, nFile, PChar(sFileNm), dwChars);
        if dwChars > 0 then begin
          SetLength( sFileNm, dwChars);  // Arnold entsorgen
          Files.Add(sFileNm);
        end;
    end;
    // an der Abwurfstelle im Fenster eine anklickbare Markierung setzen
    finally
      if @self.OnDropFiles<>nil then OnDropFiles(self);
    end;
  end;  // end IF
end;

constructor TDropFile.Create(AOwner: TWinControl);
begin
  TApplicationEvents(self).Create(AOwner);
  self.OnMessage:=self.ApplicationEventsMessage;
  Files:=TStringList.Create;
  DropEffect:=deCopy;
  DragAcceptFiles(TWinControl(Owner).Handle, TRUE);
end;

destructor TDropFile.Destroy;
begin
  Files.free;
  if Assigned(Owner) then DragAcceptFiles(TWinControl(Owner).Handle, FALSE);
  inherited;
end;

function TDropFile.DropOut(AFileList: TStrings): Integer;
var s1:string; i:integer;
begin
  if AFileList.Count=0 then exit;
  Files.Clear;
  s1:=ExtractFilePath(AFileList[0]);
  i:=0;
  repeat
    if (s1<>ExtractFilePath(AFileList[i])) then break;
    Files.Add(ExtractFileName(AFileList[i]));
    inc(i);
  until (i=AFileList.Count);
  DropOut(s1,Files);
  Files.Clear;
end;

// базовый обработчик
function TDropFile.DropOut(Directory: String; AFileList: TStrings): Integer;
var
  dataObj: IDataObject;
  Root: IShellFolder;
  pchEaten: ULONG;
  DirectoryItemIDList: PItemIDList;
  dwAttributes: ULONG;
  Folder: IShellFolder;
  i: Integer;
  ItemIDLists: array of PItemIDList;
  dwOKEffects: Longint;
begin
  OleCheck(SHGetDesktopFolder(Root));

  OleCheck(Root.ParseDisplayName(0, nil, PWideChar(WideString(Directory)),
    pchEaten, DirectoryItemIDList, dwAttributes));

  try
    OleCheck(Root.BindToObject(DirectoryItemIDList, nil, IShellFolder, Folder));

    SetLength(ItemIDLists, AFileList.Count);

    for i:=0 to AFileList.Count-1 do OleCheck(Folder.ParseDisplayName(0, nil,
      PWideChar(WideString(AFileList[i])),
      pchEaten, ItemIDLists[i], dwAttributes));

    try
      OleCheck(Folder.GetUIObjectOf(0, AFileList.Count, ItemIDLists[0],
        IDataObject, nil, dataObj));
    finally
      for i:=0 to AFileList.Count-1 do CoTaskMemFree(ItemIDLists[i]);
    end;

    dwOKEffects:=0;
    if deNone = DropEffect then dwOKEffects:=dwOKEffects or DROPEFFECT_NONE;
    if deCopy = DropEffect then dwOKEffects:=dwOKEffects or DROPEFFECT_COPY;
    if deMove = DropEffect then dwOKEffects:=dwOKEffects or DROPEFFECT_MOVE;
    if deLink = DropEffect then dwOKEffects:=dwOKEffects or DROPEFFECT_LINK;

    DoDragDrop(dataObj, Self, dwOKEffects, Result);
  finally
    CoTaskMemFree(DirectoryItemIDList);
  end;
end;

function TDropFile.DropOut(Directory, AFileName: String): Integer;
begin
  Files.Clear;
  try
    Files.Add(AFileName);
    Result:=DropOut(Directory, Files);
  finally
    Files.Clear;
  end;
end;

function TDropFile.DropOut(AFileName: String): Integer;
begin
  Files.Clear;
  try
    Files.Add(ExtractFileName(AFileName));
    Result:=DropOut(ExtractFilePath(AFileName), Files);
  finally
    Files.Clear;
  end;
end;

function TDropFile.GiveFeedback(dwEffect: Integer): HResult;
begin
  Result:=DRAGDROP_S_USEDEFAULTCURSORS;
end;

function TDropFile.MouseMoveDrop(Sender: TObject; Shift: TShiftState; X, Y, offset: Integer): boolean;
begin
  result:=false;
  if not (Sender is TControl) then exit;
  if (ssLeft in Shift) and
  ((x<=offset)or(x>=TControl(Sender).Width-5-offset) or
  (y<=offset)or(y>=TControl(Sender).Height-5-offset)) then result:=true;
end;

function TDropFile.QueryContinueDrag(fEscapePressed: BOOL;
  grfKeyState: Integer): HResult;
begin
  if fEscapePressed then Result:=DRAGDROP_S_CANCEL
  else if (grfKeyState and MK_LBUTTON)=0 then Result:=DRAGDROP_S_DROP
  else Result:=S_OK;
end;

initialization
  OleInitialize(nil);

finalization
  OleUninitialize;

end.



Методы

DropEffect: TDropEffect;

Тип операции

deNone (0) - нет
deCopy (1) - копирование
deMove (2) - перемещение
deLink (3) - ярлык

Files: TStringList;

Список файлов или папок после события OnDropFiles
Список перемещенных файлов в программу

Constructor Create(Aowner: TWinControl);
От того что передается в качестве родителя компонента TDropFile зависит реакция обработчика
OnDropFiles
То есть если передана форма
Код:
df:=TDropFile.Create(Form1);
То значит форма будет реагировать на перетаскивание
Если, например, панель
Код:
df:=TDropFile.Create(Panel1);
То значит панель будет реагировать на перетаскивание, а форма НЕТ
и тп

OnDropFiles : TNotifyEvent;
Ссылка на событие перетаскивания файлов
Задается вручную

Код:
type
  TForm2 = class(TForm)
    Label1: TLabel;
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    df: TDropFile; // экземляр класса TDropFile
    procedure FromDropFiles(Sender: TObject); // событие обработчик OnDropFiles
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
  df:=TDropFile.Create(self); // создаем объект
  df.OnDropFiles:=self.FromDropFiles; // задаем обработчик
end;

procedure TForm2.FromDropFiles(Sender: TObject);
begin
  // обрабатываем событие перетаскивания файлов в программу
  ListBox1.Clear;
  ListBox1.Items.AddStrings(df.Files);
  // в df.Files лежит список файлов или папок которые были перенесены в программу
end;

function DropOut(Directory: String; AFileName: String): Integer; overload;
function DropOut(Directory: String; AFileList: TStrings): Integer; overload;
function DropOut(AFileList: TStrings): Integer; overload;
function DropOut(AFileName: String): Integer; overload;


1) работает с одним файлом
2) второй со списком.
3) Третий работает со списком абсолютных путей
4) Червертый работает с одним абсолютным адресом файла

Directory указывает на каталог в котором находятся файлы. AFileName и AFileList содержат имена файлов.


Результат операции:
0 - отменено пользователем (нажал Esc) = DROPEFFECT_NONE
1 - файл скопирован = DROPEFFECT_COPY
2 - файл перемещен. Если поддерживает источник, то исходный файл будет удален = DROPEFFECT_MOVE
4 - создана ссылка на файл = DROPEFFECT_LINK

function MouseMoveDrop(Sender: TObject; Shift: TShiftState; X, Y: Integer; offset: integer = 0):boolean;

Функция проверяет что можно запускать DropOut
Вызывается внутри MouseMove события компонента

offset - отступ от рамки внутрь. Рекомендуется 10 пикселей.
Проще говоря задает отступ от рамки при котором разрешен DropOut

Код:
procedure TForm1.FileListBox1MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if df.MouseMoveDrop(Sender,Shift,X,Y,10) then // проверяем что запуск разрешен
    df.DropOut(FileListBox1.Directory,FileListBox1.Items); // запускаем перетаскивание
end;

Можно написать любой свой обработчик

Последний раз редактировалось alexpac26, 10.02.2013 в 19:34.
Ответить с цитированием
  #4  
Старый 10.02.2013, 19:33
Аватар для alexpac26
alexpac26 alexpac26 вне форума
Прохожий
 
Регистрация: 23.08.2011
Сообщения: 20
Репутация: 10
По умолчанию март 2013

независимая от narod.ru ссылка

DropFiles.zip
Ответить с цитированием
  #5  
Старый 06.05.2013, 16:56
Oreon Oreon вне форума
Прохожий
 
Регистрация: 27.03.2012
Сообщения: 36
Репутация: 10
По умолчанию

Реализовал в программе через Drag&Drop нечто типа с левой панельки перетащил файл в правую (дерево каталогов). Все работает (через события Делфи StartDrag, DragOver, DragDrop). Теперь хочу перетащить файл условно на "Проводник". Попробовал реализовать как тут приведено - тоже все работает, но внутренний Drag&Drop работать перестал, начиная со смены иконки драга и заканчивая отсутствием реакции на DragOver.
Можно как-то это совместить? (таскание по программе и на внешние приложения)
ЗЫ, дроп на програму с проводника работает.
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:44.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2021

ВКонтакте   Facebook   Twitter   Ссылка на Telegram