Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何将自定义格式剪贴板数据粘贴到TMemo中?_Delphi_Winapi_Clipboard_Gpx_Tmemo - Fatal编程技术网

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

Delphi 如何将自定义格式剪贴板数据粘贴到TMemo中?,delphi,winapi,clipboard,gpx,tmemo,Delphi,Winapi,Clipboard,Gpx,Tmemo,这个问题是指一个及其在stackoverflow上发布的问题 我对Windows API编程感到不舒服 在探索处理剪贴板操作的方法时,我发现它使用了一种名为GPX的自定义剪贴板格式,它实际上是纯XML文本(确切地说)。不包括使用Clipboard.AsText 我在这个阶段绊倒了: program ProbeClipboard; {$APPTYPE CONSOLE} uses SysUtils, Windows, ClipBrd; var CF_GPX: Cardinal;

这个问题是指一个及其在stackoverflow上发布的问题

我对Windows API编程感到不舒服

在探索处理剪贴板操作的方法时,我发现它使用了一种名为
GPX
的自定义剪贴板格式,它实际上是纯XML文本(确切地说)。不包括使用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.

请帮我修好那个程序。

我会这样写:

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\u GPX
格式的测试之外。这是为了避免代码中存在的竞争条件。在代码中,剪贴板可以在
HasFormat
调用和
OpenClipboard
调用之间进行修改

我还专门使用了
剪贴板
类。这个类包含了您所需要的一切,您不需要使用原始的Win32剪贴板API


我甚至把错误检查放进去了

FWIW您需要在此处最后一次尝试以保护
OpenClipboard
。您还需要检查调用
OpenClipboard
时的错误。感谢您告诉我,开箱即用的剪贴板singleton可以完成这项工作,尽管我的熟练程度很低,但我太专注于Windows API了。由于所谓的GPX自定义剪贴板格式实际上是纯文本,PChar会代替指针吗?具体如何提取字符串数据取决于它的编码方式。你知道吗?ANSI?UTF8?UTF16?尽管如此,我还是希望使用
SetString
过程来确保我没有溢出缓冲区。使用SetString(utf8str,PAnsiChar(Ptr),Size-1)你能帮我一个忙吗?如果您能指出我在stackoverflow/stackexchange站点上的何处可以找到您之前介绍给我的
整理过程中的大量资料,那就太好了。“我需要一些参考资料来说服别人,这样谁会觉得不合适呢?”门哈拉兹整理好了吗?这是从其他人的行为和版主对meta的评论中得到的。但这很明显。例如,如果您指出答案中的错误,然后对答案进行编辑以更正错误,则删除注释才是礼貌之举。