WinInet functions were used in windows to help developers develop network application more conveniently, but there is no Delphi code example on the internet, so I give some code here, help it useful for you.
Please first look at the following code:
type
TNTDownLoadProgressCallBack = reference to procedure(Current,
Total: Cardinal);
TNTDownLoadFinishedCallBack = reference to procedure(Status: NativeInt);
TNTShouldExit=reference to function():Boolean;
procedure DownLoadToFile(
const URL, SavePath: string;
ProgressCallBack: TNTDownLoadProgressCallBack;
FinishCallBack: TNTDownLoadFinishedCallBack;
CanExit:TNTShouldExit
);
const
USER_EXIT_DOWNLOAD_PROCESS=$666666;
implementation
uses
{$IFDEF VER230}
Winapi.Windows, System.SysUtils, Winapi.WinInet
{$ELSE}
Windows, SysUtils,WinInet
{$ENDIF};
var
Header: String = // 'GET %s HTTP/1.1'+sLineBreak+
'Host: %s' + sLineBreak +
'Connection: keep-alive' + sLineBreak +
'User-Agent: NeuglsWorkStudio-Auto-updater' + sLineBreak +
'Accept: text/html,application/xhtml+xml,application/*;q=0.9,*/*;q=0.8' +sLineBreak +
'Accept-Encoding: gzip,deflate,sdch' + sLineBreak +
'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3' + sLineBreak +
'Accept-Language: *' + sLineBreak + 'Referer: http://neuglsworkstudio.com/';
var
RequestHandle: HINTERNET;
ConnetHandle: HINTERNET;
ConnectEvent: THandle;
RequestOpendEvent:THandle;
RequestCompleteEvent: THandle;
ShouldExit:Boolean;
TheExitCode:Cardinal;
procedure InternetStatusCallback(hInt: HINTERNET; dwContext: DWORD_PTR;
dwInternetStatus: DWORD; lpvStatusInformation: LPVOID;
dwStatusInformationLength: DWORD); stdcall;
var
InternetAsyncResult: TInternetAsyncResult;
begin
case dwContext of
1: if (dwInternetStatus = INTERNET_STATUS_HANDLE_CREATED) then
begin
InternetAsyncResult:=TInternetAsyncResult(lpvStatusInformation^);
ConnetHandle:=Pointer(InternetAsyncResult.dwResult);
SetEvent(ConnectEvent);
end;
2: case dwInternetStatus of
INTERNET_STATUS_HANDLE_CREATED:
begin
InternetAsyncResult:=TInternetAsyncResult(lpvStatusInformation^);
RequestHandle:=Pointer(InternetAsyncResult.dwResult);
SetEvent(RequestOpendEvent);
end;
INTERNET_STATUS_REQUEST_COMPLETE:
begin
SetEvent(RequestCompleteEvent);
end;
end;
end;
end;
procedure DownLoadToFile(const URL, SavePath: string;
ProgressCallBack: TNTDownLoadProgressCallBack;
FinishCallBack: TNTDownLoadFinishedCallBack;
CanExit:TNTShouldExit);
{$IFDEF MSWINDOWS}
const
BufferSize = 1024*4;
var
Session: HINTERNET;
FHeader: AnsiString;
dwReceived: Cardinal;
Reservered: Cardinal;
Buffer: PAnsiChar;
dwBufferLength: Cardinal;
BOK: Boolean;
FileStream: TFileStream;
InternetBuffer: TInternetBuffersA;
CallBackPointer: PFNInternetStatusCallback;
dwFileSize: Cardinal;
dwSize,: Cardinal;
I:Cardinal;
label
ToExit;
function GetHost(TheURL: string): String;
var
FURL: String;
begin
FURL := TheURL + '555';
if pos(UpperCase('http://'), UpperCase(FURL)) > 0 then
begin
Delete(FURL, 1, Length('http://'));
end;
Result := Copy(FURL, 1, pos('/', FURL) - 1);
end;
function GetURI():string;
var
s:String;
begin
S:=GetHost(URL) ;
Result := Copy(URL, pos(s, URL) + Length(s) + 1, MaxInt);
end;
begin
{Init the event}
ConnectEvent:=CreateEvent(nil,false,false,'ConnectEvent');
RequestCompleteEvent:=CreateEvent(nil,false,false,'RequestCompleteEvent');
RequestOpendEvent:= CreateEvent(nil,false,false,'requestOpen');
Session := InternetOpenA(PAnsiChar(AnsiString('NWSDownloader')),
INTERNET_OPEN_TYPE_PRECONFIG, niL, niL, INTERNET_FLAG_ASYNC);
if not Assigned(Session) then
goto ToExit;
CallBackPointer := @InternetStatusCallback;
CallBackPointer := InternetSetStatusCallback(Session, CallBackPointer);
if NativeInt(CallBackPointer) = INTERNET_INVALID_STATUS_CALLBACK then
raise Exception.Create('callback function is not valid');
ConnetHandle:=InternetConnectA(
Session,
PAnsiChar(AnsiString(GetHost(URL))),
INTERNET_DEFAULT_HTTP_PORT,
nil,
nil,
INTERNET_SERVICE_HTTP,
0,
1);
if not Assigned(ConnetHandle) then
begin
if GetLastError=ERROR_IO_PENDING then
WaitForSingleObject(ConnectEvent,INFINITE) //wait connection complete.
else
goto ToExit;
end;
RequestHandle:=HttpOpenRequestA(ConnetHandle,
PAnsiChar('GET'),
PAnsiChar(AnsiString(GetURI())),
nil,
nil,
nil,
INTERNET_FLAG_RELOAD or INTERNET_FLAG_NO_CACHE_WRITE,
2);
if not Assigned(RequestHandle) then
begin
if GetLastError=ERROR_IO_PENDING then
WaitForSingleObject(RequestOpendEvent,INFINITE) //wait connection complete.
else
goto ToExit;
end;
FHeader := AnsiString(Format(Header, [GetHost(URL)]));
if not HttpSendRequestA(RequestHandle,
PAnsiChar(FHeader),
SizeOf(AnsiChar)*Length(FHeader),
nil,
0)
then
if GetLastError<>ERROR_IO_PENDING then
Goto ToExit;
WaitForSingleObject(RequestCompleteEvent,INFINITE); //wait request complete.
//get Content-Length
dwFileSize:=0;
dwSize:= Sizeof(dwFileSize);
Reservered:=0;
HttpQueryInfoA(
RequestHandle,
HTTP_QUERY_CONTENT_LENGTH or HTTP_QUERY_FLAG_NUMBER,
@dwFileSize,
dwSize,Reservered
);
GetMem(Buffer, BufferSize);
ZeroMemory(@InternetBuffer,SizeOf(InternetBuffer));
FileStream := TFileStream.Create(SavePath, fmCreate);
dwReceived := 0;
I:=0;
TheExitCode:=0;
ShouldExit:=False;
try
while (True) do
begin
ZeroMemory(@InternetBuffer,SizeOf(InternetBuffer));
InternetBuffer.dwStructSize := SizeOf(InternetBuffer);
InternetBuffer.lpvBuffer := Buffer;
InternetBuffer.dwBufferLength := BufferSize;
ResetEvent(RequestCompleteEvent);
Reservered:=1;
BOK := InternetReadFileExA(RequestHandle, @InternetBuffer, IRF_NO_WAIT,
Reservered);
if BOK then
begin
Inc(I);
FileStream.Write(Buffer^, InternetBuffer.dwBufferLength);
ZeroMemory(Buffer, BufferSize);
dwReceived := dwReceived + InternetBuffer.dwBufferLength;
if I mod 3=0 then
ProgressCallBack(dwReceived, dwFileSize);
end
else
begin
if GetLastError=ERROR_IO_PENDING then
WaitForSingleObject(RequestCompleteEvent,INFINITE); //wait request complete.
end;
if (InternetBuffer.dwBufferLength=0) and(dwReceived=dwFileSize) then
Break;
if ShouldExit then
Break;
if CanExit then
begin
TheExitCode:=USER_EXIT_DOWNLOAD_PROCESS;
Break;
end;
end;
finally
FreeMem(Buffer);
FileStream.Free;
end;
InternetCloseHandle(RequestHandle);
InternetCloseHandle(ConnetHandle);
InternetSetStatusCallback(Session, nil);
InternetCloseHandle(Session);
FinishCallBack(TheExitCode);
Exit;
ToExit:
FinishCallBack(GetLastError);
Exit;
{$ENDIF}
end;