如何将自定义格式的剪贴板数据粘贴到 TMemo 中?

发布于 2024-12-24 20:34:07 字数 1232 浏览 7 评论 0 原文

这个问题指的是这个及其已接受的答案发布在 stackoverflow 上。

我对 Windows API 编程感到不舒服。

探索 EasyGPS by 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.

请帮我修复该程序。

This question refers to this one along with its accepted answer posted here on stackoverflow.

I don't feel comfortable at Windows API programming.

Exploring the way EasyGPS by Topografix handles clipboard manipulations, I discovered that it uses a custom clipboard format named GPX wich is actually plain XML text (GPX to be precise). Using Clipboard.AsText is excluded.

I stumble at this stage:

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.

Please, help me to fix that program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深巷少女 2024-12-31 20:34:07

我会这样写:

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 类。此类拥有您所需的一切,并且无需使用原始 Win32 剪贴板 API。

我什至加入了错误检查!

I'd write it like this:

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.

Note that I moved the clipboard Open command, which locks the clipboard to be outside the test for the CF_GPX format. That is to avoid a race condition which exists in your code. In your code the clipboard could be modified between the HasFormat call and the OpenClipboard call.

I also used the Clipboard class exclusively. This class has all you need and you don't need to use the raw Win32 clipboard API.

I even put error checking in!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文