Delphi Win Inet: How to make this code Delphi 7 code work in Delphi 2010

dirkil2
dirkil2 used Ask the Experts™
on
Hi there!

I have Delphi code that uses the WinInet library (see attachment) to download a file from a url. This used to work in Delphi 7. When I now compile it with Delphi 2010 it no longer works even when I exchange String with AnsiString and Char with AnsiChar.

There must something else be wrong. Can someone modify this code so that it works under Delphi 2010?

Any help is very much appreciated.

Regards,
Dirk

 
function THttpManager.GetHTML(AUrl: string): string;
var
  databuffer : array[0..4095] of char;
  ResStr : string;
  hSession, hfile: hInternet;
  dwindex,dwcodelen,dwread,dwNumber: cardinal;
  dwcode : array[1..20] of char;
  res    : pchar;
  Str    : pchar;
begin
  ResStr:='';
  if pos('http://',lowercase(AUrl))=0 then
     AUrl:='http://'+AUrl;
  hSession:=InternetOpen('InetURL:/1.0',
                         INTERNET_OPEN_TYPE_PRECONFIG,
                         nil,
                         nil,
                         0);
  if assigned(hsession) then
  begin    
    hfile:=InternetOpenUrl(
           hsession,
           pchar(AUrl),
           nil,
           0,
           INTERNET_FLAG_RELOAD,  // damit nicht aus dem Cache gelesen wird
           0);
    dwIndex  := 0;
    dwCodeLen := 10;
    HttpQueryInfo(hfile,
                  HTTP_QUERY_STATUS_CODE,
                  @dwcode,
                  dwcodeLen,
                  dwIndex);
    res := pchar(@dwcode);
    dwNumber := sizeof(databuffer)-1;
    if (res ='200') or (res ='302') then
    begin
      while (InternetReadfile(hfile,
                              @databuffer,
                              dwNumber,
                              DwRead)) do
      begin
        if dwRead =0 then
          break;
        databuffer[dwread]:=#0;
        Str := pchar(@databuffer);
        resStr := resStr + Str;
      end;
    end
    else
      ResStr := 'Status:'+res;
    if assigned(hfile) then
      InternetCloseHandle(hfile);
  end;
  InternetCloseHandle(hsession);
  Result := resStr;
end;

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Geert GOracle dba
Top Expert 2009

Commented:
change type string to AnsiString
Geert GOracle dba
Top Expert 2009

Commented:
and PChar to PAnsiChar

Commented:
What is the problem now? It doesn't work? You get corrupted files? You get empty files? You get an access violation? Please give some more details, thanks.

You could try to change the data buffer from Char (which is now 2 bytes) to Byte.

Author

Commented:
I wrote that I tried that already without success.

Author

Commented:
@ebob

The call to InternetReadfile fails.

Author

Commented:
Maybe someone could try to compile this code under Delphi 2010 and try to load a file. It's an easy test. I would really like to hear about the results.
Geert GOracle dba
Top Expert 2009

Commented:
ow, sorry, i missed the conversion bits

i tried it it and it fails here for me :
databuffer[dwread]:=#0;

still looking why
Commented:
You need to make a few changes. The function should return AnsiString, and inside the databuffer needs to be an array of AnsiChar as well.

Then ResStr needs to be AnsiString, and Str needs to be PAnsiChar;

Inside, you need to change a line of code:

    dwNumber := Length(databuffer)-1; // sizeof(databuffer)-1;

as well as

        Str := pAnsichar(@databuffer); // BS

And then it works for me.

Attached is a version of a stand-alone console application that returns the command-line parameter passed to it. Compiled with Delphi 2010, it works for me.
program GetURL;
{$APPTYPE CONSOLE}
uses
  SysUtils, Windows, WinINET;

function GetHTML(AUrl: string): Ansistring; // BS
var
  databuffer : array[0..4095] of AnsiChar; // BS
  ResStr : AnsiString; // BS
  hSession, hfile: hInternet;
  dwindex,dwcodelen,dwread,dwNumber: cardinal;
  dwcode : array[1..20] of Char;
  res    : pchar;
  Str    : pAnsichar; // BS
begin
  ResStr:='';
  if pos('http://',lowercase(AUrl))=0 then
     AUrl:='http://'+AUrl;
  hSession:=InternetOpen('InetURL:/1.0',
                         INTERNET_OPEN_TYPE_PRECONFIG,
                         nil,
                         nil,
                         0);
  if assigned(hsession) then
  begin    
    hfile:=InternetOpenUrl(
           hsession,
           pchar(AUrl),
           nil,
           0,
           INTERNET_FLAG_RELOAD,  // damit nicht aus dem Cache gelesen wird
           0);
    dwIndex  := 0;
    dwCodeLen := 10;
    HttpQueryInfo(hfile,
                  HTTP_QUERY_STATUS_CODE,
                  @dwcode,
                  dwcodeLen,
                  dwIndex);
    res := pchar(@dwcode); // BS
    dwNumber := Length(databuffer)-1; // sizeof(databuffer)-1;
    if (res ='200') or (res ='302') then
    begin
      while (InternetReadfile(hfile,
                              @databuffer,
                              dwNumber,
                              DwRead)) do
      begin
        if dwRead =0 then
          break;
        databuffer[dwread]:=#0;
        Str := pAnsichar(@databuffer); // BS
        resStr := resStr + Str;
      end;
    end
    else
      ResStr := 'Status:'+res;
    if assigned(hfile) then
      InternetCloseHandle(hfile);
  end;
  InternetCloseHandle(hsession);
  Result := resStr;
end;
 

begin
  writeln( GetHTML(ParamStr(1)) )
end.

Open in new window

Commented:
I can call the resulting GetURL.exe with http://www.drbob42.com/delphi/home.htm as argument for example.
Geert GOracle dba
Top Expert 2009
Commented:
this sample use byte, not char as a buffer ...
http://www.cryer.co.uk/brian/delphi/wininet/example_download_file_http.htm

and writes to file, you want this in memory ?
Geert GOracle dba
Top Expert 2009

Commented:
nice going bob,
i got 8192 as amount of bytes read from the internetReadfile

and was puzzled at first why the array was only half the size ...
but you pinned it

Commented:
I still use WinINet today, as well as Unicode strings and data buffers, so I knew where to look for ;-)

Author

Commented:
You guys are great! I plugged ebob's code into my program and it worked straight away.

ebob, I hope you don't mind if I award a few points to Geert as well.

Commented:
No, that's OK. And you can call me Bob or Dr.Bob (eBob42 is my company name) ;-)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial