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

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

программно вырезать указанный файл в буфер обмена [D7, XP]


Страницы:   1 2

pest ©   (2009-06-15 16:47:00) 

привет всем.
есть путь к файлу. нужно программно вырезать этот файт в буфер обмена, чтобы вне программы пользователь мог просто нажать ctrl+v в какой-либо папке, и вырезанный файл вставился туда.
копировать в буфер умею, но вырезать не знаю как(
заранее благодарен за ответ


Gnomus   (2009-07-06 02:22:00) [1]

А как это перефразировать?


pest   (2009-06-17 11:07:00) [2]


> clickmaker


немного опоздал, но всеравно спасибо


pest   (2009-06-17 11:05:00) [3]

Общими усилиями мы добились результата. Не знаю как в D7, но в Delphı 2009 работает нормально.
Собственно, сабж:

uses ...
 ShlObj, ClipBrd, ActiveX;


procedure CopyFilesToClipboard(const AFiles: TStringList; MoveFiles: Boolean = false);
var
 DropFiles: PDropFiles;
 hGlobal: THandle;
 iLen: Integer;
 f: Cardinal;
 d: PCardinal;
 FileList: string;
begin
 Clipboard.Open;

 FileList := StringReplace(AFiles.Text, #13#10, #0, [rfReplaceAll]);
 FileList := trim(FileList) + #0#0;
 iLen := Length(FileList) * SizeOf(char);
 hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOf(TDropFiles) + iLen);
 Win32Check(hGlobal 0);
 DropFiles := GlobalLock(hGlobal);
 DropFiles^.pFiles := SizeOf(TDropFiles);

 {$IFDEF UNICODE}
  DropFiles^.fWide := true;
 {$ENDIF}

 Move(FileList[1], (PansiChar(DropFiles) + SizeOf(TDropFiles))^, iLen);
 SetClipboardData(CF_HDROP, hGlobal);
 GlobalUnlock(hGlobal);

 if MoveFiles then
   begin
     f := RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
     hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, sizeof(dword));
     d := PCardinal(GlobalLock(hGlobal));
     d^ := DROPEFFECT_MOVE;
     SetClipboardData(f, hGlobal);
     GlobalUnlock(hGlobal);
   end;

 Clipboard.Close;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
 List: TStringList;
begin
 List := TStringList.Create;
 List.Add(Edit1.Text);
 List.Add(Edit2.Text);
 CopyFilesToClipboard(List, true);
end;


Всем участникам спасибо за помощь


clickmaker   (2009-06-17 10:58:00) [4]

ну и iLen * 2


clickmaker   (2009-06-17 10:57:00) [5]

> надо теперь туда копать

DropFiles.fWide := 1;


pest   (2009-06-17 09:39:00) [6]


> Код , приведенный в [24], у меня успешно работает. Именно
> в D7.

ясно. значит дело всетаки в delphi 2009, скорее всего юникод. надо теперь туда копать


Сергей М.   (2009-06-17 08:15:00) [7]


> pest ©   (16.06.09 23:05) [33]
>
>


Код , приведенный в [24], у меня успешно работает. Именно в D7.


pest   (2009-06-16 23:05:00) [8]


> Сергей М. ©   (16.06.09 22:42) [32]


я нашел эту процедуту в инете ее очень много в неизменном виде. и сразу начал искать именно то, что мне нужно...а именно - вырезать.
потом начал тестить и отписался что код не работает. см pest   (16.06.09 11:47) [13]

и нигде не видел обсуждения этой процедуры, вроде как четко должна была работать..


Сергей М.   (2009-06-16 22:42:00) [9]


> нажимаю .. первую ..получаю ошибку на строке Clipboard.SetAsHandle(CF_HDROP, hGlobal)


Что-то я не понял .. Откуда она у тебя взялась, эта ошибка ?
Ты же сам сказал - "копировать в буфер умею".
Значит этот код как работал у тебя, так и должен работать, ибо никаких изменений он не претерпел ..


pest   (2009-06-16 19:01:00) [10]


> clickmaker ©   (16.06.09 18:26) [29]
> а как заполняется FileList?


берется из Edit1.Text.
там путь к картинке. довольно короткий и даже без русских символов


DVM   (2009-06-16 18:32:00) [11]

Ошибка скорее всего в том, как заполняется список файлов.


clickmaker   (2009-06-16 18:26:00) [12]

а как заполняется FileList?


clickmaker   (2009-06-16 18:25:00) [13]

в принципе, вот это лишнее - FileList := FileList + #0#0;
поскольку и так GMEM_ZEROINIT, а строку можно передавать как const, т.е. не создавать лишних копий.


pest   (2009-06-16 17:53:00) [14]


> clickmaker ©   (16.06.09 17:49) [26]


аналогично (
запускаю через exe выдает ошибку.
запускаю через делфи, выкидывает в дебагер


clickmaker   (2009-06-16 17:49:00) [15]

а так?

Move(FileList[1], (PChar(DropFiles) + SizeOf(TDropFiles))^, iLen);
SetClipboardData(CF_HDROP, hGlobal);
GlobalUnlock(hGlobal);


pest   (2009-06-16 17:41:00) [16]

моя возня:

procedure CopyFilesToClipboard(FileList: ansistring);
var
 DropFiles: PDropFiles;
 hGlobal: THandle;
 iLen: Integer;
begin
 iLen := Length(FileList) + 2;
 FileList := FileList + #0#0;
 hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT,
   SizeOf(TDropFiles) + iLen);
 if (hGlobal = 0) then raise Exception.Create('Could not allocate memory.');
 begin
   DropFiles := GlobalLock(hGlobal);
   DropFiles^.pFiles := SizeOf(TDropFiles);
   Move(FileList[1], (PChar(DropFiles) + SizeOf(TDropFiles))^, iLen);

   GlobalUnlock(hGlobal);
   Clipboard.SetAsHandle(CF_HDROP, hGlobal);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//  CopyFilesToClipboard('C:\boot.ini'#0'C:\AutoExec.Bat');
 CopyFilesToClipboard(Edit1.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 hGlobal: THandle;
 f: Cardinal;
 d: PCardinal;
begin
 f := RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
 hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, sizeof(dword));
 d := PCardinal(GlobalLock(hGlobal));
 d^ := DROPEFFECT_MOVE;
 GlobalUnlock(hGlobal);
 SetClipboardData(f, hGlobal);
end;


нажимаю по очереди первую и вторую кнопки.

но получаю ошибку на строке Clipboard.SetAsHandle(CF_HDROP, hGlobal);которая выглядит так:
Инструкция по адресу "0x7c911f6c" обратилась к памяти по адресу "0x00000002". Память не может быть "read".

эта же ошибка возникает на той же строке в коде, приведенном Сергеем:

procedure CopyFilesToClipboard(FileList: string);
var
DropFiles: PDropFiles;
hGlobal: THandle;
iLen: Integer;
f: Cardinal;
d: PCardinal;
begin
Clipboard.Open;

// это твой код один-в-один

iLen := Length(FileList) + 2;
FileList := FileList + #0#0;
hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOf(TDropFiles) + iLen);
Win32Check(hGlobal <> 0);
DropFiles := GlobalLock(hGlobal);
DropFiles^.pFiles := SizeOf(TDropFiles);
Move(FileList[1], (PChar(DropFiles) + SizeOf(TDropFiles))^, iLen);
GlobalUnlock(hGlobal);
Clipboard.SetAsHandle(CF_HDROP, hGlobal);

// а это те самые дополнительные телодвижения, см. [15], [17]

f := RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, sizeof(dword));
d := PCardinal(GlobalLock(hGlobal));
d^ := DROPEFFECT_MOVE;
SetClipboardData(f, hGlobal);
GlobalUnlock(hGlobal);

Clipboard.Close;
end;


Сергей М.   (2009-06-16 17:09:00) [17]


> pest   (16.06.09 16:41) [22]


procedure CopyFilesToClipboard(FileList: string);
var
 DropFiles: PDropFiles;
 hGlobal: THandle;
 iLen: Integer;
 f: Cardinal;
 d: PCardinal;
begin
 Clipboard.Open;

// это твой код один-в-один

 iLen := Length(FileList) + 2;
 FileList := FileList + #0#0;
 hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOf(TDropFiles) + iLen);
 Win32Check(hGlobal <> 0);
 DropFiles := GlobalLock(hGlobal);
 DropFiles^.pFiles := SizeOf(TDropFiles);
 Move(FileList[1], (PChar(DropFiles) + SizeOf(TDropFiles))^, iLen);
 GlobalUnlock(hGlobal);
 Clipboard.SetAsHandle(CF_HDROP, hGlobal);

// а это те самые дополнительные телодвижения, см. [15], [17]

 f := RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
 hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, sizeof(dword));
 d := PCardinal(GlobalLock(hGlobal));
 d^ := DROPEFFECT_MOVE;
 SetClipboardData(f, hGlobal);
 GlobalUnlock(hGlobal);

 Clipboard.Close;
end;


Сложно , да ?)


clickmaker   (2009-06-16 16:54:00) [18]

> [22] pest   (16.06.09 16:41)
> возился долго, но результата так и не

так опубликуй, что получилось


pest   (2009-06-16 16:41:00) [19]

возился долго, но результата так и не достиг(.
так методом тыка у меня ничего не получится, я же не гигантские алгоритмы прошу, а всего-лишь доработку имеющейся небольшой процедуры копирования, которая не работает почемуто. для опытных это пара минут, а мне головняк уже несколько дней в форумах


Сергей М.   (2009-06-16 14:55:00) [20]


> pest   (16.06.09 13:43) [18]
>
>


> где я указываю имя файла?


В строке


> Clipboard.SetAsHandle(CF_HDROP, hGlobal);



> мне надо вырезать файл


Вот для этого и надо проделать дополнительныетелодвижения, проиллюстрированные в [17]


Страницы:   1 2

Наверх

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