procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin if (pDisp = CurDispatch) then begin Beep; {the document is loaded, not just a frame } CurDispatch := nil; {clear the global variable } end; end;
无法编译,我在delphi下 问题出在pDisp = CurDispatch,怎么回事?
CurDispatch是一个全局变量,要在interface部分定义它 var CurDispatch: IDispatch; {save the interface globally }可能不是这个问题,我再看看
给你一个得到网页源码的函数: function GetWebPageText( sUrl: string ):string; var hInternet: pointer ; // Handle of Internet Session (InternetOpen) hOpenUrl: pointer ; // Handle of Internet Open URL (InternetOpenURL) bLoop: boolean ; lpBuffer: Array[0..2048] of Char ; lpdwNumberOfBytesRead: DWORD ; sBuffer: string ; begin // Obtaining a handle to an internet session. // // INTERNET_OPEN_TYPE_PRECONFIG = 0; // {将Internet Option中的预设Proxy 服务器设定为主服务器} // // INTERNET_FLAG_NO_CACHE_WRITE = $04000000; // {不将Internet连接的资料写入Cache中} hInternet := InternetOpen(pchar('Application'), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, INTERNET_FLAG_NO_CACHE_WRITE) ; // If internet session created OK if (hInternet <> nil) then begin // InternetOpenURL // Begin reading a complete HTTP URL. hOpenUrl := InternetOpenUrl(hInternet, pChar(sUrl), nil, 0, INTERNET_FLAG_RELOAD, $0) ; // If Open URL OK If (hOpenUrl <> nil) Then begin bLoop := True; sBuffer := ''; while bLoop do begin lpBuffer := '' ; // InternetReadFile // Reads data from a handle opened by the InternetOpenUrl InternetReadFile(hOpenUrl, @lpBuffer, sizeof(lpBuffer), lpdwNumberOfBytesRead) ; If lpdwNumberOfBytesRead = 0 Then bLoop := False else sBuffer := sBuffer + strPas(lpBuffer) ; end; result := sBuffer; end else result := ''; end // for "If Open URL OK " else begin result := ''; end ; // close Open URL if (hOpenUrl <> nil) then InternetCloseHandle(hOpenUrl) ; // close internet session if (hInternet <> nil) then InternetCloseHandle(hInternet) ; end;使用方法: procedure TForm1.Button1Click(Sender: TObject); var s : string; begin s := GetWebPageText( 'http://www.icondiy.com' );//注意,要填写完整的url if s <> '' then Memo1.Lines.Add( s ); end;
下面是其中一段代码
repeat
downcompelete:=false;
wb.navgate(url,flags,flags,flags,flags);
repeat
application.pressmessage;
until downcompelete;
doc:=wb.document as ihtmldocument2;
str:=doc.body.outtext;
p:=pos('特征串',str);
until p<>0;
这段代码是说,浏览网页是否是正确的网页。这样下去之后内存就一直上涨没有下降过。直到内存使用率100%。(说明:这段代码能走出循环,走出循环后内存也是上涨)。
wb.navgate(url,flags,flags,flags,flags);
repeat
application.pressmessage;
until downcompelete;downcompelete???不是死循环吗?
另上面代码中:downcompelete 是在Twebbrowser控件的oncompelet(页面是否下载完成)事件改变它的值的.如果网页页面存在,上面的是一个两重循环,意思是这个页面真正打开为止。
其中某少数COM问题造成的内存泄漏..
begin
if (pDisp = CurDispatch) then
begin
Beep; {the document is loaded, not just a frame }
CurDispatch := nil; {clear the global variable }
end;
end;
问题出在pDisp = CurDispatch,怎么回事?
var CurDispatch: IDispatch; {save the interface globally }可能不是这个问题,我再看看
其实,即使是IE也无法完全释放它使用的内存。不信你就用IE访问几十个不同的网站试试。
而WebBrowser其实就是IE啊。这是微软的问题。其实你只是通过特征码判断打开的网页是否正确,根本不需要使用WB,用InternetReadFile函数吧!
function GetWebPageText( sUrl: string ):string;
var
hInternet: pointer ; // Handle of Internet Session (InternetOpen)
hOpenUrl: pointer ; // Handle of Internet Open URL (InternetOpenURL)
bLoop: boolean ;
lpBuffer: Array[0..2048] of Char ;
lpdwNumberOfBytesRead: DWORD ;
sBuffer: string ;
begin
// Obtaining a handle to an internet session.
//
// INTERNET_OPEN_TYPE_PRECONFIG = 0;
// {将Internet Option中的预设Proxy 服务器设定为主服务器}
//
// INTERNET_FLAG_NO_CACHE_WRITE = $04000000;
// {不将Internet连接的资料写入Cache中} hInternet := InternetOpen(pchar('Application'),
INTERNET_OPEN_TYPE_PRECONFIG,
nil,
nil,
INTERNET_FLAG_NO_CACHE_WRITE) ; // If internet session created OK
if (hInternet <> nil) then
begin
// InternetOpenURL
// Begin reading a complete HTTP URL.
hOpenUrl := InternetOpenUrl(hInternet,
pChar(sUrl),
nil,
0,
INTERNET_FLAG_RELOAD,
$0) ; // If Open URL OK
If (hOpenUrl <> nil) Then
begin
bLoop := True;
sBuffer := ''; while bLoop do
begin
lpBuffer := '' ;
// InternetReadFile
// Reads data from a handle opened by the InternetOpenUrl
InternetReadFile(hOpenUrl, @lpBuffer, sizeof(lpBuffer), lpdwNumberOfBytesRead) ; If lpdwNumberOfBytesRead = 0 Then
bLoop := False
else
sBuffer := sBuffer + strPas(lpBuffer) ;
end; result := sBuffer;
end
else
result := '';
end // for "If Open URL OK "
else
begin
result := '';
end ; // close Open URL
if (hOpenUrl <> nil) then InternetCloseHandle(hOpenUrl) ;
// close internet session
if (hInternet <> nil) then InternetCloseHandle(hInternet) ;
end;使用方法:
procedure TForm1.Button1Click(Sender: TObject);
var
s : string;
begin
s := GetWebPageText( 'http://www.icondiy.com' );//注意,要填写完整的url
if s <> '' then
Memo1.Lines.Add( s );
end;
就可以继续执行了。
大侠帮忙看看我的问题 解决立即给分
IE 6已经修正了这个bug。