Форум: "WinAPI";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Вниз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 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.038 c