Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.25;
Скачать: CL | DM;

Вниз

drag n drop API   Найти похожие ветки 

 
Alex44   (2004-06-07 12:21) [0]

Я использую IDropSource и IDropTarget для продвинутого drag"n"drop"а (чтобы таскать вещи в/из своей программы). Вопрос: кто-нибудь знает, как реализовать операции с "виртуальными" файлами? Например, бросается файл из WinZip или WinRar: IDataObject возвращает имя файла, но файла еще нет. Что нужно послат" (запросить у IDataObject), чтобы WinZip создал обещаный файл? Аналогичный вопрос про мою программу: в какой момент я должен создать файл? Спасибо заранее :)


 
Alex44   (2004-06-08 00:43) [1]

Удалено модератором


 
nikkie ©   (2004-06-08 02:17) [2]

прежде всего надо посмотреть, в каких форматах предоставляет данные IDataObject. перечислить форматы можно с помощью IDataObject.EnumFormatEtc.

в MSVS среди tools есть программка DataObject Viewer, которая подобное и делает. для того, что тащится из WinRAR она показывает единственный формат "Unknown Clipformat", а из WinZIP она вообще отказывается принимать drag-drop. поэтому мне становится непонятна фраза
>IDataObject возвращает имя файла
будь добр, приведи код.

хотя, наверное, я догадываюсь в чем дело - IDataObject.EnumFormatEtc вполне может оказаться не реализованным, но к данным тем не менее добраться можно с помощью методов GetData/GetDataHere. судя по MSDN нужный формат CF_HDROP:
A handle to type HDROP that identifies a list of files. An application can retrieve information about the files by passing the handle to the DragQueryFile functions.  

если тебе надо таскать только файлы, то можно обойтись и без IDataObject. можно создавать окно со стилем WS_EX_ACCEPTFILES и обрабатывать сообщение WM_DROPFILES.


 
Alex44   (2004-06-08 08:39) [3]


> IDataObject.EnumFormatEtc


Ето я все пробовал (правда, из своей программы). Действительно, не реализовано (в WinZip), но CF_HDROP получить можно, со ссылкой на временный файл, которого еще нет! При етом, explorer (как и реализация WS_EX_ACCEPTFILES) умудряются получить етот файл, видимо, через GetData или SetData с каким-то форматом. Вопрос, с каким? (Кажется, у WinZip SetData тоже не реализована.)
Я пробовал различные CF_...DROPEFFECT (как описано в MSDN), но ничего не работает. Какие-нибудь еще идеи?


> если тебе надо таскать только файлы


Я хочу таскать ВСЕ (вкючая файлы из программы и объекты внутри программы) и при етом менять курсор/хинт в зависимости от того, куда ето попадает. (Например, возможность дропнуть файл и логическая операция зависят от места в окне, куда он попадет).
WS_EX_ACCEPTFILES не дает такого контроля.


 
nikkie ©   (2004-06-08 14:04) [4]

думаю, статья "Handling Shell Data Transfer Scenarios" в MSDN тебе поможет. кусочек из нее:

CFSTR_FILECONTENTS
This format identifier is used with the CFSTR_FILEDESCRIPTOR format to transfer data as if it were a file, regardless of how it is actually stored. The data consists of an STGMEDIUM structure that represents the contents of one file. The file is normally represented as a stream object, which avoids having to place the contents of the file in memory. In that case, the tymed member of the STGMEDIUM structure is set to TYMED_ISTREAM, and the file is represented by an IStream interface. The file can also be a storage or global memory object (TYMED_ISTORAGE or TYMED_HGLOBAL). The associated CFSTR_FILEDESCRIPTOR format contains a FILEDESCRIPTOR structure for each file that specifies the file"s name and attributes.

The target treats the data associated with a CFSTR_FILECONTENTS format as if it were a file. When the target calls IDataObject::GetData to extract the data, it specifies a particular file by setting the lindex member of the FORMATETC structure to the zero-based index of the file"s FILEDESCRIPTOR structure in the accompanying CFSTR_FILEDESCRIPTOR format. The target then uses the returned interface pointer or global memory handle to extract the data.

CFSTR_FILEDESCRIPTOR
This format identifier is used with the CFSTR_FILECONTENTS format to transfer data as a group of files. These two formats are the preferred way to transfer shell objects that are not stored as file-system files. For example, these formats can be used to transfer a group of e-mail messages as individual files, even though each e-mail is actually stored as a block of data in a database. The data consists of an STGMEDIUM structure that contains a global memory object. The structure"s hGlobal member points to a FILEGROUPDESCRIPTOR structure that is followed by an array containing one FILEDESCRIPTOR structure for each file in the group. For each FILEDESCRIPTOR structure, there is a separate CFSTR_FILECONTENTS format that contains the contents of the file. To identify a particular file"s CFSTR_FILECONTENTS format, set the lIndex value of the FORMATETC structure to the zero-based index of the file"s FILEDESCRIPTOR structure.

The CFSTR_FILEDESCRIPTOR format is commonly used to transfer data as if it were a group of files, regardless of how it is actually stored. From the target"s perspective, each CFSTR_FILECONTENTS format represents a single file and is treated accordingly. However, the source can store the data in any way it chooses. While a CSFTR_FILECONTENTS format might correspond to a single file, it could also, for example, represent data extracted by the source from a database or text document.


 
Alex44   (2004-06-08 15:03) [5]

Я весь MSDN на ету тему прочитал. (Sorry, не помню, где у меня другое "е" и есть ли вообще :) Пробовал и CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS, как раз по етой страничке; WinZip их не поддерживает. Прямо хоть автору пиши, так он ведь вряд ли скажет...


 
nikkie ©   (2004-06-08 15:12) [6]

TYMED правильный указывал?


 
Alex44   (2004-06-08 15:54) [7]

Честно говоря, сейчас уж я плохо помню. Кажется, он вырубается на CFSTR_FILEDESCRIPTOR (где TYMED еще стандартная global memory), а как без CFSTR_FILEDESCRIPTOR использовать CFSTR_FILECONTENTS, непонятно (неясно даже, сколько файлов). Впрочем, попробую на досуге. Или напишу таки авторам. Если что узнаю, выложу. Но любые идеи still welcome :)


 
Alex44   (2004-06-10 12:41) [8]

Wow! Кажется, разобрался. Вместо того, чтобы самому parse"ить DROPFILES, нужно вызвать на нее DragQueryFile. Кому интересно, вот кусок кода:


FillChar(Medium, SizeOf(Medium), 0);
Format := HDropFormatEtc;
Res := Target.DataObject.GetData(Format, Medium);
if Res = S_OK then begin
 HDROP := Medium.hGlobal;
 Count := DragQueryFile(HDROP, $FFFFFFFF, nil, 0);
 for I := 0 to Count - 1 do begin
   Sb := DragQueryFile(HDROP, I, nil, 0) + 1;
   GetMem(P, Sb);
   DragQueryFile(HDROP, I, P, Sb);
// Do something with the file here
   FreeMem(P);
 end;
end;
ReleaseStgMedium(Medium);


Теперь бы еще понять, что же DragQueryFile делает, чтобы я тоже мог на нее правильно реагировать и создавать файл. Есть идеи?


 
suhar   (2004-06-14 19:32) [9]

Могу послать пример. С книжки списал :).



Страницы: 1 вся ветка

Текущий архив: 2004.07.25;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.031 c
14-1089108766
cherrex
2004-07-06 14:12
2004.07.25
Запуск програм при старте Windows


14-1088944223
}|{yk
2004-07-04 16:30
2004.07.25
Как заставить Excel переносить длинные строки


14-1089166782
Aldor_
2004-07-07 06:19
2004.07.25
Восстановление стертой информации (NTFS)


3-1088409404
Users
2004-06-28 11:56
2004.07.25
Получение спика поставщиков данных


14-1089013165
Александр Иванов
2004-07-05 11:39
2004.07.25
Свершилось :).