Search code examples
delphinetwork-programmingippascal

How to get IP address in Pascal


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.

Solution

  • 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;