我正在开发一个最近从Delphi 2007升级到XE7的应用程序。有一种特殊情况,即TMemoryStream到PChar的转换失败。这是代码:
procedure TCReport.CopyToClipboard;
var
CTextStream: TMemoryStream;
PValue: PChar;
begin
CTextStream := TMemoryStream.Create;
//Assume that this code is saving a report column to CTextStream
//Verified that the value in CTextStream is correct
Self.SaveToTextStream(CTextStream);
//The value stored in PValue below is corrupt
PValue := StrAlloc(CTextStream.Size + 1);
CTextStream.Read(PValue^, CTextStream.Size + 1);
PValue[CTextStream.Size] := #0;
{ Copy text stream to clipboard }
Clipboard.Clear;
Clipboard.SetTextBuf(PValue);
CTextStream.Free;
StrDispose(PValue);
end;
添加SaveToTextStream的代码:
procedure TCReport.SaveToTextStream(CTextStream: TStream);
var
CBinaryMemoryStream: TMemoryStream;
CWriter: TWriter;
begin
CBinaryMemoryStream := TMemoryStream.Create;
CWriter := TWriter.Create(CBinaryMemoryStream, 24);
try
CWriter.Ancestor := nil;
CWriter.WriteRootComponent(Self);
CWriter.Free;
CBinaryMemoryStream.Position := 0;
{ Convert Binary 'WriteComponent' stream to text}
ObjectBinaryToText(CBinaryMemoryStream, CTextStream);
CTextStream.Position := 0;
finally
CBinaryMemoryStream.Free;
end;
end;
我观察到StrLen(PChar)的大小也是TMemoryStream的一半。但是在Delphi 2007中,它的出现与TMemoryStream的大小相同。
我知道上面的代码假设char的大小为1个字节,这可能是个问题。但我尝试了多种方法,没有任何作用。
你能建议一个更好的方法来进行这种转换吗?
答案 0 :(得分:8)
然而,这是Delphi 2009及以后使用Unicode文本的问题。在Delphi 2007及更早版本中:
Char
是AnsiChar
的别名。PChar
是PAnsiChar
的别名。string
是AnsiString
的别名。在Delphi 2009及更高版本中:
Char
是WideChar
的别名。PChar
是PWideChar
的别名。string
是UnicodeString
的别名。您的代码是在PChar
为PAnsiChar
的情况下编写的。因此你的问题。无论如何,您需要停止使用StrAlloc
。你在这里通过手动分配堆内存让自己变得艰难。让编译器完成工作。
您需要在字符串变量中获取文本,然后执行:
Clipboard.AsText := MyStrVariable;
获取字符串的最佳方式取决于TCReport
提供的功能。我希望它会直接产生一个字符串,在这种情况下你会写这样的东西:
procedure TCReport.CopyToClipboard;
begin
Clipboard.AsText := Self.ReportAsText;
end;
我猜测你的TCReport
提供的功能是什么,但我确定你知道。
答案 1 :(得分:0)
通过查看上面hvd和David Heffernan所写的内容,一种可能的方法是将Error C2065 'timezone': undeclared identifier pythoncore C:\Users\Ira\Downloads\Python-2.7.10\Modules\timemodule.c 713
上的<script src="telerik.kendoui.professional.2015.3.1111.trial/js/kendo.all.min.js"></script>
<script src="telerik.kendoui.professional.2015.3.1111.trial/js/jquery.min.js"></script>
<link href="telerik.kendoui.professional.2015.3.1111.trial/styles/kendo.default.min.css" rel="stylesheet" />
<link href="telerik.kendoui.professional.2015.3.1111.trial/styles/kendo.common.min.css" rel="stylesheet" />
</head>
<body>
<div id="example">
<label>First Name</label>
<input type="text" name="firstName" id="txtFname" value="" />
<script>
$(document).ready(function () {
$("txtFname").kendoMaskedTextbox({
});
});
</script>
</div>
</body>
</html>
更改为CTextStream
,如下所示:
CopyToClipboard
但您应确保 TStringStream
函数为procedure TCReport.CopyToClipboard;
var
CTextStream: TStringStream;
begin
CTextStream := TStringStream.Create;
try
//Assume no error with Self.SaveToTextStream
Self.SaveToTextStream(CTextStream);
{ Copy text stream to clipboard }
Clipboard.AsText := CTextStream.DataString;
finally
CTextStream.Free;
end;
end;
提供准确的编码文本数据。