i am getting these two Errors trying to view IP address and show in a messagebox
Error looks like this
[dcc32 Error] Unit1.pas(38): E2010 Incompatible types: 'PAnsiChar' and 'PWideChar' => Error1
and
[dcc32 Error] Unit1.pas(40): E2010 Incompatible types: 'string' and 'array[1..1024] of Byte' => Error2
I could do this in C/C but i wanted to try something new in Delphi
My source code Looks like this
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Wininet, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
hInet: HINTERNET;
hFile: HINTERNET;
buffer: array[1..1024] of byte;
bytesRead: DWORD;
url : String;
begin
url := 'https://icanhazip.com';
hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
hFile := InternetOpenUrlA(hInet, PChar(url), nil, 0, 0, 0); //Error 1
InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead); // Error 2
showmessage(buffer);
end;
end.
Please what am I doing wrongly?
Edit
Okay, InternetOpenUrl
Worked,however , it still gives me error on the showmessage(buffer)
Code looks like this now
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Wininet, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
hInet: HINTERNET;
hFile: HINTERNET;
buffer: array[1..1024] of byte;
bytesRead: DWORD;
url : String;
begin
url := 'https://icanhazip.com';
hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
hFile := InternetOpenUrl(hInet, PChar(url), nil, 0, 0, 0);
InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);
showmessage(buffer);
end;
end.
Edit2
My code Looks like this now
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Wininet, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
hInet: HINTERNET;
hFile: HINTERNET;
buffer: String;
bytesRead: DWORD;
url : String;
szMessage : String;
i : integer;
begin
//url := 'https://icanhazip.com';
hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
hFile := InternetOpenUrl(hInet, PChar('https://icanhazip.com'), nil, 0, 0, 0);
InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);
//showmessage(buffer);
Label1.Caption := buffer;
end;
end.
CodePudding user response:
The first error happens because you call the AnsiChar version of the function.
Use InternetOpenUrl
instead of InternetOpenUrlA
.
The second happens in the line below you expect it. ShowMessage expects a string
and not an array of byte
.
Edit: To get a string out of your array of bytes to be passed to ShowMessage, you need to know in what encoding the bytes are sent. Assuming that is UTF-8, the conversion can simply be done with:
ShowMessage(TEncoding.UTF8.GetString(Slice(buffer, bytesRead)))
Edit 2: OK, for XE8 you have to do a bit more work.
procedure TForm1.Button1Click(Sender: TObject);
var
hInet: HINTERNET;
hFile: HINTERNET;
buffer: TBytes;
bytesRead: DWORD;
url : String;
begin
url := 'https://icanhazip.com';
hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
hFile := InternetOpenUrl(hInet, PChar(url), nil, 0, 0, 0);
SetLength(buffer, 1024);
InternetReadFile(hFile,@buffer[0],Length(buffer),bytesRead);
showmessage(TEncoding.UTF8.GetString(buffer, 0, bytesRead));
end;
CodePudding user response:
In C/C you typically use a NUL terminated string -and allocate the storage to hold that string yourself. This is what you have done in your code with the BYTE array.
In Delphi a string
is a native type, not just a pointer to NUL terminated character data.
From the Error message you provided the error happens on the call to ShowMessage, not on the call to InternetReadFile.
You need to pass a string variable to ShowMessage.
You could try this:
var
szMessage: String;
i: Integer;
SetLength(szMessage, bytesread);
for i =1 to bytesread do
szMessage[i]:=buffer[i-1];
ShowMessage(szMessage);
There are ways you can do this more compactly, but as someone who has moved from C to mainly using Delphi these days I think looking at the operation this way helps to understand the differences between the two languages.