Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];

Вниз

Как передать содержимое файла в Clipboard   Найти похожие ветки 

 
kami ©   (2005-08-27 17:05) [0]

Не пойму, как в этом случае использовать CFSTR_FILECONTENTS и CFSTR_FILEDESCRIPTOR. В MSDN только упоминается, что это используется в StgMedium - структуре. Но вот Что и Как передавать в SetClipboardData?
Если кто сталкивался с подобным - подскажите, пожалуйста.


 
kami ©   (2005-08-27 17:18) [1]

По аналогии с Drag&Drop сперва должна передаваться структура TFileGroupDescriptor, а затем - содержимое каждого файла.
Попробовал на одном файле и, само собой, ничего не получил. Кажется, из-за того, что при передаче контента файла Clipboard не знает, в каком формате сохранен контент.
procedure TForm1.bbOkClick(Sender: TObject);
const
 FFileContentsCount=1;
var
 pFileGroup:pFileGroupDescriptor;
 i:integer;
 P:PChar;
begin
 CF_FILECONTENTS := RegisterClipboardFormat(CFSTR_FILECONTENTS);
 CF_FILEGROUPDESCRIPTOR := RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);

 if not OpenDialog.Execute then
   exit;
 s:=TMemoryStream.Create;
 s.LoadFromFile(OpenDialog.FileName);
 s.Position:=0;
 if not OpenClipboard(0) then
   exit;
 EmptyClipboard;
 hGl:=GlobalAlloc(GMEM_Share or GHND,SizeOf(TFileGroupDescriptor)+1);
 if hGl=0 then
   exit;
 pFileGroup:=GlobalLock(HGl);
 pFileGroup^.cItems:=FFileContentsCount;
 { Fill FileDescriptor}
 for i:=0 to FFileContentsCount-1 do
   FillFileDescriptor(i,pFileGroup^.fgd[i]);// процедура опробована  в Drag&Drop
 GlobalUnLock(HGl);
 SetClipboardData(CF_FILEGROUPDESCRIPTOR,HGl);
 //TStreamToIStream(s,Istm,true);
 Hgl:=GlobalAlloc(GMEM_Share or GHND,S.Size);
 p:=GlobalLock(hGl);
 CopyMemory(p,s.Memory,s.Size); // пробовал и через IStream
 GlobalUnlock(hGl);
 SetClipboardData(CF_FILECONTENTS,hGl);// вот здесь, скорее всего
 CloseClipboard;
end;


Вот и непонимаю, что именно нужно этому SetClipboardData?


 
alpet ©   (2005-08-27 17:26) [2]

Вот просмотрщик текстового буфера обмена:

uses Windows;

function streq (p1, p2: pchar): boolean;
var n: dword;
begin
n  := 0;
while (p1 [n] = p2 [n]) and
      (p1 [n] <> #0) do Inc (n);
result := p1 [n] = p2 [n];
end;

const maxbuff = 128 * 1024;
var hWnd, hgl: THandle;
    msg: tagMSG;
    ptxt: PChar;
    ptmp: PChar;
begin
ptmp := VirtualAlloc (nil, maxbuff, MEM_COMMIT,  PAGE_READWRITE);
// non standard technicus - creating Edit control as primary window
hWnd := CreateWindowEx (WS_EX_DLGMODALFRAME, "Edit", "",
                WS_VISIBLE or ES_READONLY or WS_SYSMENU or WS_THICKFRAME ,
                CW_USEDEFAULT, CW_USEDEFAULT, 200, 50,
                0, 0, hInstance, nil);
GetWindowText (hWnd, ptmp, maxbuff);
while IsWindow (hWnd) do
 begin
  if PeekMessage (msg, hWnd, 0, 0, PM_REMOVE) then
   begin
    TranslateMessage(msg);
    DispatchMessage (msg);
    GetWindowText (hWnd, ptmp, maxbuff);
   end;
  if OpenClipboard (hWnd) then
   begin
    hgl := GetClipboardData(CF_TEXT);
    if 0 <> hgl then
     begin
      ptxt := GlobalLock (hgl);
      if not streq (ptxt, ptmp) then
      if Assigned (ptxt) then SetWindowText (hWnd, ptxt);
      GlobalUnlock (hgl);
     end;
    CloseClipboard;
   end;
  sleep (10);
 end;
end.


 
alpet ©   (2005-08-27 17:32) [3]

Ек, совсем не в тему запостил. Тут оказывается shell механизм, по копированию файлов исследуется.


 
kami ©   (2005-08-27 17:36) [4]

2 [2] alpet ©

Да с CF_TEXT проблем-то нет, проблема в следующем (извините, что сначала неточно объяснил) : есть TMemoryStream, в нем - содержимое "почти" файла. Каким образом его можно отправить в буфер обмена, чтобы при Ctrl-V в проводнике появился файл.


 
kami ©   (2005-08-27 18:03) [5]

Попробовал скопировать через TSTGMEDIUM (GlobalAlloc этой структуры и в SetClipboardData) - та же история, просмотрщик буфера обмена пишет, что не может отобразить данные. :(

ЗЫ. Блин, не думал, что это будет сложнее, чем сделать Drag&Drop контента файлов.:((


 
alpet ©   (2005-08-27 18:10) [6]

А имя файла где копируется (CFSTR_FILENAME)?


 tagSTGMEDIUM = record
   tymed: Longint;
   case Integer of
     0: (hBitmap: HBitmap; unkForRelease: IUnknown);
     1: (hMetaFilePict: THandle);
     2: (hEnhMetaFile: THandle);
     3: (hGlobal: HGlobal);
     4: (lpszFileName: POleStr);
     5: (stm: IStream);
     6: (stg: IStorage);
 end;
 TStgMedium = tagSTGMEDIUM;

Про эту структуру речь идет?


 
kami ©   (2005-08-27 18:22) [7]

Именно про нее, имена файлов сохраняются в TFileGroupDescriptor, который идет в hGlobal. В [1] я сразу попробовал отправить TFileGroupDescriptor в буфер обмена.
var
 Medium:TSTGMEDIUM;
//==========================
 hGl:=GlobalAlloc(GMEM_Share or GHND,SizeOf(TStgMedium));
 pMedium:=GlobalLock(hGl);
 Medium:=pMedium^;// мне так удобнее

 Medium.tymed:=Tymed_HGlobal;
 Medium.hGlobal:=GlobalAlloc(GMEM_Share or GHND,SizeOf(TFileGroupDescriptor)+1);
  if Medium.hGlobal=0 then
   begin
     GlobalUnlock(hGl);
     GlobalFree(hGl);
     exit;
   end;
   pFileGroup:=GlobalLock(Medium.HGlobal);
   pFileGroup^.cItems:=FFileContentsCount;
   { Fill FileDescriptor}
   for i:=0 to FFileContentsCount-1 do
     FillFileDescriptor(i,pFileGroup^.fgd[i]);// именно здесь заполняются FileNames

   GlobalUnLock(Medium.HGlobal);
   GlobalUnlock(hGl);
   SetClipboardData(CF_FILEGROUPDESCRIPTOR,hGl);


 
alpet ©   (2005-08-27 18:30) [8]

Хм. Вот структура TFileGroupDescriptor

_FILEGROUPDESCRIPTORA = record
   cItems: UINT;
   fgd: array[0..0] of TFileDescriptor; // one item in array !!!
 end;


Небезопасно ее создавать динамически, для кол-ва файлов > 1.


 
alpet ©   (2005-08-27 18:34) [9]

У тебя строка:

Medium.hGlobal:=GlobalAlloc(GMEM_Share or GHND,SizeOf(TFileGroupDescriptor)+1);

выделяет структуру только для одного файла.

А в цикле:

for i:=0 to FFileContentsCount-1 do
   FillFileDescriptor(i,pFileGroup^.fgd[i]);

может записываться гораздо больше.


 
kami ©   (2005-08-27 18:38) [10]

Ну да, кажется, с Игорем Шевченко мы уже разбирали этот случай - описание структуры прямиком перекочевало из С, а там при таком объявлении можно указывать любой элемент. Все решается переобъявлением fgd на динамический массив. Пользуюсь уже долго, никаких нареканий.
Ну а для тестовой задачи можно пользоваться и таким :)


 
kami ©   (2005-08-27 18:40) [11]

2 [9] alpet ©
В самом начале -
const
FFileContentsCount=1;


Мне пока не нужно "много" файлов, хотя бы один "запуздырить":)


 
kami ©   (2005-08-27 18:44) [12]

Вообще, по крайней мере при Drag&Drop сперва отправляется StgMedium с TFileGroupDescriptor, а потом идут запросы CFSTR_FILECONTENTS на содержимое каждого файла в (опять-таки) StgMedium. Как именно они отправлены - указывается в StgMedium.Tymed
Вот именно так я и попробовал - сперва в буфер отправляю StgMedium с TFileGroupDescriptor, а потом StgMedium, в котором stm - содержимое моего файла.
Увы, Clipboard этого не понимает :(.


 
alpet ©   (2005-08-27 18:56) [13]

А статус выполнения/ошибки у всех функций хороший?


 
kami ©   (2005-08-27 19:07) [14]

[13] alpet ©
Вроде, да. Правда, если SetClipboardData возвращает не INVALID_HANDLE_VALUE, GlobalAlloc, CloseClipboard - тоже отрабатывает нормально.


 
kami ©   (2005-08-27 19:08) [15]

[14] kami ©
Убрать Правда, если


 
kami ©   (2005-08-27 21:32) [16]

УРААА !!!!!

Как всегда, всем спасибо, особенно себе, любимому :)

Проблема решена с помощью OleSetClipboard и IDataObject !!!!
Все работает просто вЕлИкОлЕпнО :)).



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

Форум: "WinAPI";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.037 c
14-1128932810
diwww
2005-10-10 12:26
2005.10.30
когда начали выдавать паспорта рф?


3-1126980946
WonderfulDay
2005-09-17 22:15
2005.10.30
Insufficient memory for this operation.


14-1128593205
syte_ser78
2005-10-06 14:06
2005.10.30
Прошу прощения ексли боян


1-1128406624
Svetiks
2005-10-04 10:17
2005.10.30
DBLookupComboBox


1-1128624589
Gall
2005-10-06 22:49
2005.10.30
Иконки приложения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский