尝试完成在Delphi Sydney CE中的ShFileOpStruct。

huangapple go评论53阅读模式
英文:

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;

我尝试了各种选项,使用 pWideStringpChar 如上所示,但都没有成功。尝试将 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的文档中有描述:

基本语法元素(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 := &#39;123&#39;#0&#39;456&#39;#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:
>
> &#39;You&#39;
>
> You can combine quoted strings with control strings to form larger character strings. For example, you could use:
>
> &#39;Line 1&#39;#13#10&#39;Line 2&#39;
>
> 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] := &#39;123&#39;;
  fileNames[1] := &#39;456&#39;;

  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(&#39;123&#39;);
    fileNames.Add(&#39;456&#39;);

    fileNames.Delimiter := #0;
    fileNames.QuoteChar := #0;
    fileNames.StrictDelimiter := True;

    s := fileNames.DelimitedText + #0;
  finally
    fileNames.Free;
  end;

  sfo.pfrom := PChar(s);
end;

huangapple
  • 本文由 发表于 2023年5月11日 05:12:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76222592.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定