如何在Windows XP系统中获取Unicode CSV剪贴板数据?

3

我正在为一个大型项目编写测试应用程序,但似乎无法从Windows剪贴板中检索Unicode CSV数据。我成功地检索了CF_UNICODETEXT,使用内置的GetClipboardData API调用,但是当我在MSExcel中将Unicode CSV放入剪贴板并尝试以CSV格式检索时,我得到了错误的数据。以下是一些代码:

procedure TForm1.Button7Click(Sender: TObject);
var
   hMem     : THandle;
   dwLen    : DWord;
   ps1, ps2 : pChar;
begin
   OpenClipboard( form1.Handle );
   RichEdit1.Lines.Clear;
   try
      if Clipboard.HasFormat( CF_UNICODETEXT ) then
      begin
         hMem := GetClipboardData( CF_UNICODETEXT );
         ps1 := GlobalLock( hMem );
         dwLen := GlobalSize( hMem );
         ps2 := StrAlloc( 1 + dwLen );
         StrLCopy( ps2, ps1, dwLen );
         GlobalUnlock( hMem );
         RichEdit1.Lines.Add( ps2 );
      end
      else
         ShowMessage( 'No CF_UNICODETEXT on Clipboard!' );
   finally
      CloseClipboard;
   end;
end;

现在这段代码应该适用于CSV,但是当我更改剪贴板格式为我所需的格式时,应用程序无法获取正确的数据。需要注意的是,我可以很好地获得制表符Unicode,只是我所需的CSV格式不行。
2个回答

5
Excel使用的CSV剪贴板格式是ANSI编码,而不是Unicode。
从转储Excel 2007剪贴板中可以看出,启用Unicode的有:
  • CF_UNICODETEXT
  • "HTML格式"
  • "Rich Text Format"
  • "XML电子表格"
"XML电子表格"和"HTML格式"都有明确定义的表/行,因此从中提取数据不应该太难。

但是,从剪贴板获取数据应该自动转换CF_TEXT和CF_UNICODETEXT之间的格式。请参见:http://msdn.microsoft.com/en-us/library/ms649013(VS.85).aspx中的“合成剪贴板格式”。但可能会发生的情况是CF_UNICODETEXT从剪贴板中拉取UTF-8而不是UTF-16LE?虽然很奇怪,因为Windows本地支持UTF-16LE。 - Marjan Venema
@Marjan:CF_UNICODE 可以使用,但是它是制表符分隔,而不是逗号分隔的。Excel 在剪贴板上包括第二个格式,即 ANSI 编码的 CSV,这正是 wfoster 所问的。他的问题实际上是:“此代码可以正常工作,但如果我用 RegisterClipboardFormat('CSV') 替换 CF_UNICODETEXT,它就会失败”。 - Zoë Peterson
非常感谢您的帮助。我可能会使用选项卡格式。我还偶然发现了这篇文章http://blogs.msdn.com/b/michkap/archive/2005/09/17/470413.aspx,似乎Excel应该将Unicode CSV作为它可以将任何语言保存到CSV文件中,但我想我不能得到所有东西。 - wfoster

1

你需要请求CF_CSV格式。在以CF_CSV的形式获取数据之后,你可以将其作为AnsiString处理,然后根据需要转换为UnicodeString。

下面是一个屏幕截图,显示了从Excel2007复制的6个单元格。我将其作为CF_CSV捕获到ClipMate中,然后用ClipMate的十六进制查看器显示出来。你会看到字段之间由逗号(十六进制2C)分隔,以CRLF(十六进制0D0A)结尾。下面显示的是一个带注释的组合图,展示了Excel、复制的区域以及ClipMate将CF_CSV呈现为十六进制字节的方式。 alt text
(来源:thornsoft.com)

此外,这个相关主题也值得一读: Get CSV Data from Clipboard (pasted from Excel) that contains accented characters


标准剪贴板格式列在http://msdn.microsoft.com/en-us/library/ff729168%28VS.85%29.aspx中,CSV不是其中之一,因此,是的,您需要使用RegisterClipboardFormat。由于问题特别涉及剪贴板上的Unicode数据,所以说他可以从ANSI转换并不是很有帮助。 - Zoë Peterson
@wfoster,@Craig - 哎呀!对此感到抱歉。CF_CSV确实需要注册。但它就是它,不会成为Unicode。因此,您可以将其视为Ansi,或者可以从UnicodeText构建自己的CSV,并猜测列应该在哪里断开。 - Chris Thornton
那是个可怕的想法 - 将 ANSI 字符串转换为 Unicode 不会帮助您恢复由于 ANSI 编码而丢失的任何信息。如果您想要启用 Unicode 的表格数据,则正确的方法似乎是 XML 电子表格或 HTML,如 Craig 的答案中所述。 - EFraim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接