【问题标题】:It's some kind of magic... or bug? [closed]这是某种魔法……还是虫子? [关闭]
【发布时间】:2015-10-13 23:43:57
【问题描述】:

我将我的程序添加到了 SendTo。我向它发送了两个文件。 它们是:

C:\ThisIsMySuperTestHelloWorld\ThisBookIsRedMyPenIsWhite\test.jpg
C:\ThisIsMySuperTestHelloWorld\ThisBookIsRedMyPenIsWhite\hello.jpg

下面的代码显示C:\ThisIsMySuperTestHelloWorld\ThisBookIsRedMyPenIsWhite\test.jpg@C:\ThisIsMySuperTestHelloWorld\ThisBookIsRedMyPenIsWhite\test.jpg

procedure TForm1.FormCreate(Sender: TObject);
var Files: array of PAnsiChar;
    i: Integer;
begin
  SetLength(Files, 2);

  for i:=0 to 1 do begin
   Files[i] := PAnsiChar(ParamStr(2+i));
  end;

  ShowMessage( Files[0] +'@' + Files[1] );
end;

我在 Windows7 上使用 Delphi 6。 在 Delphi Xe3(仍然是 Win7)下,我将(两者)PAnsiChar 更改为 PWideChar,效果相同。

我的 SendTo 链接链接到:

"C:\<PATH_HERE>\Project1.exe" c

并放置在这里:

C:\Users\<USER>\AppData\Roaming\Microsoft\Windows\SendTo

【问题讨论】:

  • 你可以使用PChar而不是PAnsiChar/PWideChar来添加更多的魔法,现在不管你用Delphi 6还是Delphi XE3编译都没有关系
  • 在编程方面,没有魔法这回事。这实际上是当今的问题 - 太多人认为软件背后存在某种巫术。
  • 请阅读this article about using PChar and strings。正如其他人已经注意到的那样,在这里使用 PChars 并不是一个好主意。

标签: windows delphi


【解决方案1】:

使用字符串怎么样?例如:

procedure HandleParams;
var Files: array of string;
    i: Integer;
begin
  SetLength(Files, ParamCount);
  for i := 1 to ParamCount do
        Files[i-1] := ParamStr(i);

  if ParamCount >= 2 then
        ShowMessage( Files[0] +'@' + Files[1] );
end;

您的代码不起作用,因为 PAnsiChar 只是一个指针,不存储实际的字符串数据。当您分配从 ParamStr 函数返回的字符串时,仅存储指向(临时)函数结果的指针。实际数据将被下一个函数调用覆盖。这甚至会在进一步使用时使您的程序崩溃。

顺便说一句,您的 ParamStr 索引迭代了 2 和 3,并引用了第二个和第三个参数;也许这不是预期的,因为参数从索引 1 开始(索引 0 是程序调用本身)?

要解决这个问题,必须存储字符串数据,这使得指针有点没用,但无论如何,这是你示例的固定版本:

procedure HandleParamsPAnsi;
var Files: array of PAnsiChar;
    FilesData: array of AnsiString;
    i: Integer;
begin
  SetLength(Files, 2);
  SetLength(FilesData, 2);

  for i:=0 to 1 do begin
      FilesData[i] := AnsiString(ParamStr(1+i));
      Files[i] := PAnsiChar(FilesData[i]);
  end;

  ShowMessage( Files[0] + '@' + Files[1] );
end;

【讨论】:

  • 我只会使用TStringList。循环通过ParamCount() 存储列表中的每个ParamStr() 值,然后将其Delimiter 属性设置为@ 并读取其DelimitedText 属性。
  • ...您的 ParamStr 索引迭代了 2 和 3,... 也许您没有注意到 SendTo 链接中已经有一个参数 c
  • 非常感谢。我不知道 PChars 只是指针,因为我可以做到:var C: PChar; begin C := 'Hello World'; 并且内存被分配。你为我澄清了事情。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 2014-03-24
  • 2013-02-04
  • 2014-01-03
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多