![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
программно вырезать указанный файл в буфер обмена [D7, XP]
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]