英文:
Trying to complete the ShFileOpStruct in Delphi Sydney CE
问题
以下是翻译好的内容:
我正试图从Delphi 7迁移,并且这些pWide....。
下面的代码仅加载'123'
字符串。pFrom
是一个 PWideChar
,那么如何加载带有 #0
分隔符的文件名?并追加 #0#0
以满足要求?
procedure TForm13.Button1Click(Sender: TObject);
var
s: String;
sfo: TSHFileOpStruct;
begin
s := '123' + #0 + '456' + #0;
sfo.pfrom := pchar(s);
end;
我尝试了各种选项,使用 pWideString
或 pChar
如上所示,但都没有成功。尝试将 pFrom
与 #0
连接也会导致错误:
">" 操作符不适用于此操作数类型。
请帮助一个新手。
英文:
I am trying to move from Delphi 7 and these pWide....
The code below only loads the '123'
string. The pFrom
is a PWideChar
, so how do I load the file names with a separator of #0
? And append #0#0
to complete the requirement?
procedure TForm13.Button1Click(Sender: TObject);
var
s: String;
sfo: TSHFileOpStruct;
begin
s:='123'+#0+'456'+#0;
sfo.pfrom:=pchar(s);
end;
I have tried various options, using pWideString
or pChar
as above, but to no avail. Trying to concatenate the pFrom
with #0
also failed with an error:
> operator not applicable to this operand type
Please help a newbie.
答案1
得分: 1
简单地在构建字符串字面值时去掉`+`号,例如:
```delphi
procedure TForm13.Button1Click(Sender: TObject);
var
s: String;
sfo: TSHFileOpStruct;
begin
s := '123'#0'456'#0;
sfo.pfrom := PChar(s);
end;
在Delphi的文档中有描述:
> 控制字符串是一个或多个控制字符的序列,每个控制字符由#
符号后跟一个从0到65535(十进制)或从$0到$FFFF(十六进制)的无符号整数常量组成,以UTF-16编码表示,并表示与指定代码值对应的字符。每个整数在字符串中内部表示为2个字节。这对于表示控制字符和多字节字符很有用。控制字符串:
>
> #89#111#117
>
> 等效于带引号的字符串:
>
> 'You'
>
> 您可以将带引号的字符串与控制字符串结合在一起形成更大的字符字符串。 例如,您可以使用:
>
> 'Line 1'#13#10'Line 2'
>
> 在'Line 1'和'Line 2'之间放置一个回车换行。然而,您不能以这种方式连接两个带引号的字符串,因为一对连续的撇号被解释为一个单个字符。(要连接带引号的字符串,请使用+
运算符或将它们简单地组合成一个单独的带引号的字符串。)
这在Delphi 7中也应该可以工作。
另一方面,如果您想以更动态的方式进行(比如说,文件名来自变量),那么可以做类似于以下的操作:
procedure TForm13.Button1Click(Sender: TObject);
var
fileNames: array of string; // 或者您想要的任何容器
fileName, s: String;
len: Integer;
P: PChar;
sfo: TSHFileOpStruct;
begin
SetLength(fileNames, 2);
fileNames[0] := '123';
fileNames[1] := '456';
len := 0;
for fileName in fileNames do
Inc(len, Length(fileName)+1);
SetLength(s, len);
P := PChar(s);
for fileName in fileNames do
begin
len := Length(fileName);
Move(PChar(fileName)^, P^, len*SizeOf(Char));
Inc(P, len);
P^ := #0;
Inc(P);
end;
sfo.pfrom := PChar(s);
end;
或者:
procedure TForm13.Button1Click(Sender: TObject);
var
fileNames: TStringList;
s: String;
sfo: TSHFileOpStruct;
begin
fileNames := TStringList.Create;
try
fileNames.Add('123');
fileNames.Add('456');
fileNames.Delimiter := #0;
fileNames.QuoteChar := #0;
fileNames.StrictDelimiter := True;
s := fileNames.DelimitedText + #0;
finally
fileNames.Free;
end;
sfo.pfrom := PChar(s);
end;
<details>
<summary>英文:</summary>
Simply drop the `+` when building up your string literal, eg:
```delphi
procedure TForm13.Button1Click(Sender: TObject);
var
s: String;
sfo: TSHFileOpStruct;
begin
s := '123'#0'456'#0;
sfo.pfrom := PChar(s);
end;
This is described in Delphi's documentation:
Fundamental Syntactic Elements (Delphi): Character Strings
> A control string is a sequence of one or more control characters, each of which consists of the #
symbol followed by an unsigned integer constant from 0 to 65,535 (decimal) or from $0 to $FFFF (hexadecimal) in UTF-16 encoding, and denotes the character corresponding to a specified code value. Each integer is represented internally by 2 bytes in the string. This is useful for representing control characters and multibyte characters. The control string:
>
> #89#111#117
>
> Is equivalent to the quoted string:
>
> 'You'
>
> You can combine quoted strings with control strings to form larger character strings. For example, you could use:
>
> 'Line 1'#13#10'Line 2'
>
> To put a carriage-return line-feed between 'Line 1' and 'Line 2'. However, you cannot concatenate two quoted strings in this way, since a pair of sequential apostrophes is interpreted as a single character. (To concatenate quoted strings, use the +
operator or simply combine them into a single quoted string.)
This should work in Delphi 7, too.
On the other hand, if you want to do it more dynamically (say, the filenames are coming from variables), then you can do something more like this:
procedure TForm13.Button1Click(Sender: TObject);
var
fileNames: array of string; // or whatever container you want
fileName, s: String;
len: Integer;
P: PChar;
sfo: TSHFileOpStruct;
begin
SetLength(fileNames, 2);
fileNames[0] := '123';
fileNames[1] := '456';
len := 0;
for fileName in fileNames do
Inc(len, Length(fileName)+1);
SetLength(s, len);
P := PChar(s);
for fileName in fileNames do
begin
len := Length(fileName);
Move(PChar(fileName)^, P^, len*SizeOf(Char));
Inc(P, len);
P^ := #0;
Inc(P);
end;
sfo.pfrom := PChar(s);
end;
Alternatively:
procedure TForm13.Button1Click(Sender: TObject);
var
fileNames: TStringList;
s: String;
sfo: TSHFileOpStruct;
begin
fileNames := TStringList.Create;
try
fileNames.Add('123');
fileNames.Add('456');
fileNames.Delimiter := #0;
fileNames.QuoteChar := #0;
fileNames.StrictDelimiter := True;
s := fileNames.DelimitedText + #0;
finally
fileNames.Free;
end;
sfo.pfrom := PChar(s);
end;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论