问题描述
代码:
var
WinHttpReq: OleVariant;
procedure TForm1.Button1Click(Sender: TObject);
begin
WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
WinHttpReq.Open('GET', 'http://stackoverflow.com', TRUE); // asynchronously
WinHttpReq.setRequestHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0');
WinHttpReq.Send();
// HOW to set a callback procedure here and get the response?
end;
注意:我不想导入mshttp.dll并使用TLB.我想通过后期绑定使用它.我也想处理异常(如果有).
Note: I do not want to import mshttp.dll and use TLB. I want to use it via late binding. I also would like to handle exceptions if any.
我接受TLama的回答,因为它为我最初提出的要求提供了一个很好的选择.加上它有一个很好的示例源.
I'm accepting TLama's answer becouse it gives me a good alternative to what I initially was asking. plus it has a good example source.
这是(附带源代码).
推荐答案
正如Stijn在他的回答中所说,为了防止程序滞后,请使用线程. IWinHttpRequest.Open
也具有异步配置功能,但是要捕获事件和 IWinHttpRequest.WaitForResponse
甚至会卡住您的程序.
As Stijn said in his answer, to prevent your program to lag, use the threads. IWinHttpRequest.Open
has the asynchronous configuration capability too but it would be very difficult to catch the events and IWinHttpRequest.WaitForResponse
would stuck your program even so.
这是如何将响应文本放入表单的备注框中的简单示例.请注意,以下示例使用同步模式,并且您还可以使用 IWinHttpRequest.SetTimeouts
.如果您想像问题一样使用异步模式,则必须等待 IWinHttpRequest.WaitForResponse
方法.
Here is the simple example of how to get the response text into the form's memo box.Please note that the following example uses the synchronous mode and that you can additionally modify the timeout values using IWinHttpRequest.SetTimeouts
. If you want to use the asynchronous mode as you have in your question then you'll have to wait for the result with IWinHttpRequest.WaitForResponse
method.
///////////////////////////////////////////////////////////////////////////////
///// WinHttpRequest threading demo unit //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
unit WinHttpRequestUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActiveX, ComObj, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
///////////////////////////////////////////////////////////////////////////////
///// THTTPRequest - TThread descendant for single request ////////////////
///////////////////////////////////////////////////////////////////////////////
type
THTTPRequest = class(TThread)
private
FRequestURL: string;
FResponseText: string;
procedure Execute; override;
procedure SynchronizeResult;
public
constructor Create(const RequestURL: string);
destructor Destroy; override;
end;
///////////////////////////////////////////////////////////////////////////////
///// THTTPRequest.Create - thread constructor ////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// RequestURL - the requested URL
constructor THTTPRequest.Create(const RequestURL: string);
begin
// create and start the thread after create
inherited Create(False);
// free the thread after THTTPRequest.Execute returns
FreeOnTerminate := True;
// store the passed parameter into the field for future use
FRequestURL := RequestURL;
end;
///////////////////////////////////////////////////////////////////////////////
///// THTTPRequest.Destroy - thread destructor ////////////////////////////
///////////////////////////////////////////////////////////////////////////////
destructor THTTPRequest.Destroy;
begin
inherited;
end;
///////////////////////////////////////////////////////////////////////////////
///// THTTPRequest.Execute - thread body //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
procedure THTTPRequest.Execute;
var
Request: OleVariant;
begin
// COM library initialization for the current thread
CoInitialize(nil);
try
// create the WinHttpRequest object instance
Request := CreateOleObject('WinHttp.WinHttpRequest.5.1');
// open HTTP connection with GET method in synchronous mode
Request.Open('GET', FRequestURL, False);
// set the User-Agent header value
Request.SetRequestHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0');
// sends the HTTP request to the server, the Send method does not return
// until WinHTTP completely receives the response (synchronous mode)
Request.Send;
// store the response into the field for synchronization
FResponseText := Request.ResponseText;
// execute the SynchronizeResult method within the main thread context
Synchronize(SynchronizeResult);
finally
// release the WinHttpRequest object instance
Request := Unassigned;
// uninitialize COM library with all resources
CoUninitialize;
end;
end;
///////////////////////////////////////////////////////////////////////////////
///// THTTPRequest.SynchronizeResult - synchronization method /////////////
///////////////////////////////////////////////////////////////////////////////
procedure THTTPRequest.SynchronizeResult;
begin
// because of calling this method through Synchronize it is safe to access
// the VCL controls from the main thread here, so let's fill the memo text
// with the HTTP response stored before
Form1.Memo1.Lines.Text := FResponseText;
end;
///////////////////////////////////////////////////////////////////////////////
///// TForm1.Button1Click - button click event ////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Sender - object which invoked the event
procedure TForm1.Button1Click(Sender: TObject);
begin
// because the thread will be destroyed immediately after the Execute method
// finishes (it's because FreeOnTerminate is set to True) and because we are
// not reading any values from the thread (it fills the memo box with the
// response for us in SynchronizeResult method) we don't need to store its
// object instance anywhere as well as we don't need to care about freeing it
THTTPRequest.Create('http://stackoverflow.com');
end;
end.
这篇关于如何使用"WinHttp.WinHttpRequest.5.1";异步地?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!