Скопировать текст в буфер обмена

altСегодня столкнулся с одной нетривиальной задачей на Delphi XE. Нужно было скопировать текст в буфер обмена Windows, НО без использования модуля Clipbrd.

Почему именно без его использования? Всё просто! У меня было маленькое WinAPI-приложение (90кб), но если подключить Clipbrd, то это маленькое приложение становится толстым мутаном на 800Кб. Именно поэтому нужно было решить задачу без этого «толстого» модуля.

Итак, для решения нам понадобятся всего 3 WinAPI-функции:

OpenClipboard;
SetClipboardData;
CloseClipboard.
Заголовки функций приводить не буду т.к. их легко найти в MSDN.

Ну и, пожалуй, обойдёмся больше без прилюдий, ниже приведён исходный код:

Только кодкопировать в буфер обменапечать
{$IF DEFINED(CLR)}
procedure SetBuffer(Format: Word; Buffer: TBytes; Size: Integer);
var
DataPtr: IntPtr;
{$ELSE}
procedure SetBuffer(Format: Word; var Buffer; Size: Integer);
var
DataPtr: Pointer;
{$IFEND}
Data: THandle;
begin
OpenClipboard(0);
try
Data := GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, Size);
try
DataPtr := GlobalLock(Data);
try
{$IF DEFINED(CLR)}
Marshal.Copy(Buffer, 0, DataPtr, Size);
{$ELSE}
Move(Buffer, DataPtr^, Size);
{$IFEND}
if SetClipboardData(Format, Data) = 0 then
{$IF DEFINED(CLR)}
raise OutOfMemoryException.Create(SOutOfResources);
{$ELSE}
{$IFEND}
finally
GlobalUnlock(Data);
end;
except
GlobalFree(Data);
raise;
end;
finally
CloseClipboard;
end;
end;
procedure SetAsText(const Value: string);
{$IF NOT DEFINED(CLR)}
begin
SetBuffer(CF_UNICODETEXT, PChar(Value)^, ByteLength(Value) + SizeOf(Char));
{$ELSE}
var
Buffer: TBytes;
begin
Buffer := WideBytesOf(Value + #0);
SetBuffer(CTextFormat, Buffer, Length(Buffer))
{$IFEND}
end;
Выше приведены две функции, одна вызывает вторую. Пользоваться данным кодом просто:

Только кодкопировать в буфер обменапечать
SetAsText(‘Текст в буфер обмена’);
На этом всё. Надеюсь кому-то пригодится.


Понравилась статья? Поделиться с друзьями: