I am beginner of Delphi now I would like to learn this language but I have got error and I don`t know where is problem and how to fix it. This example I take it from book to delphi.

Error

[Pascal Error] Engine.pas(41): E2250 There is no overloaded version of 'ShellExecute' that can be called with these arguments

All code:

unit Engine;
interface
uses Windows, Classes, SysUtils;
type
  TTemplate = array of String;
  TEngine = class
private
  FFileName : String;
  FFileLines : TStringList;
protected
  procedure Execute(Path : String); virtual;
public
  Pattern : TTemplate;
  Replace : TTemplate;
  procedure Parse;
  constructor Create(FileName : String);
  destructor Destroy; override;
end;
implementation
{ TEngine }
uses ShellAPI; // włączenie modułu ShellAPI
constructor TEngine.Create(FileName : String);
begin
  FFileName := FileName; // przypisanie wartości parametru do
  FFileLines := TStringList.Create; // utworzenie typu TStringList
  FFileLines.LoadFromFile(FileName); // załadowanie zawartości
  inherited Create;
end;
destructor TEngine.Destroy;
begin
  FFileLines.Free; // zwolnienie typu
  { zwolnienie tablic }
  Pattern := nil;
  Replace := nil;
  DeleteFile('temporary.html'); // wykasowanie pliku tymczasowego
  inherited; // wywołanie destruktora klasy bazowej
end;
procedure TEngine.Execute(Path: String);
begin
  // otwarcie pliku w przeglądarce Internetowej
  ShellExecute(0, 'open', PChar(Path), nil, nil, SW_SHOW);
end;
procedure TEngine.Parse;
var
  i : Integer;
begin
  for I := Low(Pattern) to High(Pattern) do
  { zastąpienie określonych wartości w FFileLines }
  FFileLines.Text := StringReplace(FFileLines.Text, Pattern[i],
  Replace[i], [rfReplaceAll]);
  FFileLines.SaveToFile('temporary.html');
  Execute('temporary.html');
end;
end.

Place with error

ShellExecute(0, 'open', PChar(Path), nil, nil, SW_SHOW);

picture error enter image description here

Ctrl + click

[SuppressUnmanagedCodeSecurity, DllImport(shell32, CharSet = CharSet.Auto, SetLastError = True, EntryPoint = 'ShellExecute')]
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,
  Directory: string; ShowCmd: Integer): HINST; external;
[SuppressUnmanagedCodeSecurity, DllImport(shell32, CharSet = CharSet.Auto, SetLastError = True, EntryPoint = 'ShellExecute')]
有帮助吗?

解决方案

Looking at the declaration of ShellExecute in the .net implementation of ShellAPI, it is clear what to do. Stop casting to PChar and write your code like this:

ShellExecute(0, 'open', Path, '', '', SW_SHOW);

I had not appreciated this until now, but it seems that the Windows API calls you make from Delphi.net use the same DllImport attribute as other .net languages. I guess that makes sense and these are just normal p/invoke calls as would be found in C# interop code.

Interestingly, you report that attempts to pass nil to one of these string parameters leads to a compiler error. That means that there's no easy way to pass the null pointer to an API function that expects a C string. What you would have to do is to use an overloaded external declaration that received a Pointer for the parameter which you want to pass nil to.

As an aside, the Embarcadero developers made a mistake in their DllImport declaration. They set SetLastError = True which is incorrect for ShellExecute which does not set the thread last error value.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top