Как вставить данные буфера обмена нестандартного формата в TMemo?
Этот вопрос относится к этому наряду с принятым ответом, размещенным здесь на stackru.
Я не чувствую себя комфортно при программировании Windows API.
Исследуя, как EasyGPS от Topografix обрабатывает манипуляции с буфером обмена, я обнаружил, что он использует собственный формат буфера обмена с именем GPX
который на самом деле простой текст XML (точнее, GPX). Использование Clipboard.AsText исключено.
Я спотыкаюсь на этом этапе:
program ProbeClipboard;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
ClipBrd;
var
CF_GPX: Cardinal;
ClipboardData: THandle;
begin
CF_GPX:=RegisterClipboardFormat('GPX');
if ClipBoard.HasFormat(CF_GPX) then
begin
Writeln('GPX format available in clipboard');
//
OpenClipboard(0);
ClipboardData := GetClipboardData(CF_GPX);
if ClipboardData = 0 then
raise Exception.Create('Clipboard data Error');
/// How to use GlobalLock and GlobalUnLock
/// so that I can paste the Clipboard data
/// to a TMemo instance for example
CloseClipboard;
end;
end.
Пожалуйста, помогите мне исправить эту программу.
1 ответ
Я бы написал это так:
program ProbeClipboard;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
ClipBrd;
var
CF_GPX: Cardinal;
ClipboardData: Windows.HGLOBAL;
Ptr: Pointer;
Size: DWORD;
begin
CF_GPX := RegisterClipboardFormat('GPX');
Clipboard.Open;
try
if Clipboard.HasFormat(CF_GPX) then
begin
Writeln('GPX format available in clipboard');
ClipboardData := Clipboard.GetAsHandle(CF_GPX);
if ClipboardData=0 then
RaiseLastOSError;
Ptr := Windows.GlobalLock(ClipboardData);
if Ptr=nil then
RaiseLastOSError;
try
Size := Windows.GlobalSize(ClipboardData);
//Ptr now points to a memory block of Size bytes
//containing the clipboard data
finally
Windows.GlobalUnlock(ClipboardData);
end;
end;
finally
Clipboard.Close;
end;
end.
Обратите внимание, что я переместил буфер обмена Open
команда, которая блокирует буфер обмена за пределами теста для CF_GPX
формат. То есть, чтобы избежать состояния гонки, которое существует в вашем коде. В вашем коде буфер обмена может быть изменен между HasFormat
вызов и OpenClipboard
вызов.
Я также использовал Clipboard
класс исключительно. В этом классе есть все, что вам нужно, и вам не нужно использовать API-интерфейс буфера обмена Win32.
Я даже добавил проверку ошибок!