Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Drag'n'Drop [D7, WinXP]


_aLF ©   (2004-09-09 13:16:00) 

Вопрос горит! Как заставить прилагу кидать файлы в другие проложения? То бишь, выбираю из списка, потом тащю, в фотошоп, например, а тот, че хошь, с ним, то и делает...


DVM   (2004-09-09 14:19:00) [1]


> _aLF ©   (09.09.04 14:12) [6]

В начале перетаскивания захвати мышь (SetCapture) и отслеживай ее координаты. По координатам получаешь hWnd того окна над которым мышь (WindowFromPoint) и в момент отпускания мыши посылаешь ему это сообщение со списком файлов.

> прилага говорит, что я не могу этого сделать (вид курсора).
>

И не будет. Хотя файлы проглотит нормально. Чтобы вид курсора менялся надо OLE использовать.
На сайте Подгорецкого есть книжка по Делфи (не помню название), и там в 4-5 главах об этом подробно рассказывается "Перетаскивание как это делается в OLE".
Вот.


_aLF   (2004-09-09 14:12:00) [2]

DVM, у тебя Wnd - дескриптор некоего окна, так вот, мне нужно получить именно то окно, на какое я тащу, а не как в примере. Согласен заренее, что это просто и я туплю, но время поджимает и думать некогда. И еще - когда я тащу что - либо во внешнюю прогу, прилага говорит, что я не могу этого сделать (вид курсора). Как мне это включить? На прилагу таскается нормально, DragAcceptFiles включил.


_aLF   (2004-09-09 13:43:00) [3]

DVM, Оперативность - на высшем уровне! Спасибо!


DVM   (2004-09-09 13:37:00) [4]


> У TMessage куча параметров, и что из них - что, быстро не
> сообразишь.

я думаю рановато это тебе пока, но да ладно вот пример:

uses
 ShellAPI;

function MakeDrop(const FileNames: array of string): THandle;
var
 I, Size: Integer;
 Data: PDragInfoA;
 P: PChar;
begin
 Size := SizeOf(TDragInfoA) + 1;
 for I := 0 to High(FileNames) do
   Inc(Size, Length(FileNames[I]) + 1);
 Result := GlobalAlloc(GHND or GMEM_SHARE, Size);
 if Result <> 0 then
 begin
   Data := GlobalLock(Result);
   if Data <> nil then
     try
       Data.uSize := SizeOf(TDragInfoA);
       P  := PChar(@Data.grfKeyState) + 4;
       Data.lpFileList := P;
       for I := 0 to High(FileNames) do
       begin
         Size := Length(FileNames[I]);
         Move(Pointer(FileNames[I])^, P^, Size);
         Inc(P, Size + 1);
       end;
     finally
       GlobalUnlock(Result);
     end
   else
   begin
     GlobalFree(Result);
     Result := 0;
   end;
 end;
end;

function MyEnum(Wnd: hWnd; Res: PInteger): Bool; stdcall;
var
 N: string;
begin
 SetLength(N, MAX_PATH);
 SetLength(N, GetClassName(Wnd, Pointer(N), Length(N)));
 Result := AnsiCompareText('TEditControl', N) <> 0;
 if not Result then Res^ := Wnd;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Wnd: HWnd;
 Drop: hDrop;
begin
 EnumChildWindows(FindWindow('TEditWindow', nil), @MyEnum, Integer(@Wnd));
 if IsWindow(Wnd) then
 begin
   Drop := MakeDrop(['c:\msdos.sys']);
   if Drop <> 0 then PostMessage(Wnd, wm_DropFiles, Drop, 0);
   GlobalFree(Drop);
 end;
end;


_aLF   (2004-09-09 13:33:00) [5]

У TMessage куча параметров, и что из них - что, быстро не сообразишь.


_aLF   (2004-09-09 13:31:00) [6]

Ага, а как это на практике реализовать, ен подскажешь (второй вариант). Принимать - то как я понял, а вот посылать...


DVM   (2004-09-09 13:19:00) [7]

Есть два пути:
Первый трудный - через OLE - реализовать интерфейсы IDataObject, IDataSource и иже с ними.
Второй попроще - послать самому WM_DROPFILES со списком файлов.


Наверх

Титульная страница Поиск, карта сайта Написать письмо