Задача следующая:
Есть программа-архиватор. Надо из неё через буфер обмена извлекать файлы. Но файлы, ясное дело, должны физически извлекаться не в момент копирования (Ctrl+C) а во время встаки (Ctrl+V).
Дотнетовкий класс Clipboard такой функциональности судя по всему не предоставляет.
Нашёл в винде меседжи WM_RENDERALLFORMATS и WM_RENDERFORMAT и вроде для того чтоб получить его нужно просто вызвать функцию WinAPI SetClipboardData с нулевым указателем на данные, а потом, получив сообщение установить эти данные.
Т.е. по команде копирования я вызываю метод setEmptyFileToClipboard():
public const int CF_HDROP = 15;
[DllImport("user32.dll")]
extern public static IntPtr SetClipboardData(uint format, IntPtr data);
public static void setEmptyFileToClipboard() {
SetClipboardData(CF_HDROP, IntPtr.Zero);
}
И нифига, никакого сообщения я не получаю. Более того в Эксплорере Paste недоступен, т.е. он не видит в буфере понятных ему данных.
Вызов же стандартного для С# метода Clipboard.SetData() в таком виде
Clipboard.SetData(DataFormats.FileDrop, null);
вобще приводит к тому что эксплорер падает при нажатии правой мышки.
24.11.07 16:37: Перенесено модератором из '.NET' — AndrewVK
Здравствуйте, yura_net, Вы писали:
_>public const int CF_HDROP = 15;
_>[DllImport("user32.dll")]
_>extern public static IntPtr SetClipboardData(uint format, IntPtr data);
_>public static void setEmptyFileToClipboard() {
_> SetClipboardData(CF_HDROP, IntPtr.Zero);
_>}
_>И нифига, никакого сообщения я не получаю. Более того в Эксплорере Paste недоступен, т.е. он не видит в буфере понятных ему данных.
А Вы уверены, что функция SetClipboardData проходит? GetLаstError что говорит?
Можно поинтересоваться, а что вы питались добиться передвая null? Я всегда считал что InPtr — это указатель на область с данными, а вы педеаете пустоту эксполеру и пытаетесь получить правильно поведение. Передайте ему путь к файлу например, должно помочь

Смотрим пример:
http://www.developerfusion.co.uk/forums/p/44268/146767/
Всем спасибо, разобрался сам. Всего-то не сделал банальной вещи — открытия/закрытия буфера обменя.
Меняем функцию на вот такую:
[DllImport("user32.dll")]
public static extern int GetClipboardFormatName(uint format, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder formatName, int cchMaxCount);
[DllImport("user32.dll")]
public static extern bool OpenClipboard(IntPtr hwnd);
[DllImport("user32.dll")]
public static extern bool CloseClipboard();
[DllImport("user32.dll")]
public static extern bool EmptyClipboard();
public static void setEmptyFileToClipboard(Form form) {
OpenClipboard(form.Handle);
EmptyClipboard();
SetClipboardData(CF_HDROP, IntPtr.Zero);
CloseClipboard();
}
И дальше благополучно ловим сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS