难道是Delphi的Bug?(WebBrowser的问题) WEBBrowser只是用IE的核心ActiveX控件而已,這裡Delphi只是做了接口的單元而已,不會是Delphi的Bug, 可能是你的瀏覽器太粗糙了... 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 当时我一直不敢相信,后来启动vc,vb分别做了同样的东西,呵呵一切正常~~~ 看来比尔还是对自己的亲生儿子要好一点,呵呵~ 不知道下面一段程序对你有无帮助:首先来实现写,因为这是最迫切的要求:procedure SetHtml(const WebBrowser: TWebBrowser; const Html: string);varStream: IStream;hHTMLText: HGLOBAL;psi: IPersistStreamInit;beginif not Assigned(WebBrowser.Document) then Exit;hHTMLText := GlobalAlloc(GPTR, Length(Html) + 1);if 0 = hHTMLText then RaiseLastWin32Error;CopyMemory(Pointer(hHTMLText), PChar(Html), Length(Html));OleCheck(CreateStreamOnHGlobal(hHTMLText, True, Stream));tryOleCheck(WebBrowser.Document.QueryInterface(IPersistStreamInit, psi));tryOleCheck(psi.InitNew);OleCheck(psi.Load(Stream));finallypsi := nil;end;finallyStream := nil;end;end;---- 首先,此过程需要的两个参数,WebBrowser是显示目的控件,Html是需要显示的HTML源码;然后,先检查WebBrowser.Document对象是否有效,无效则退出;接着在系统全局堆里分配一块内存,将需要显示的HTML源码复制进去。这是因为下一步需要建立一个WebBrowser控件可以读取的流。GlobalAlloc函数的参数GPTR表示需要分配一块固定的以0初始化过的内存区域,如果分配失败则返回0,则通过RaiseLastWin32Error函数引发一个异常,提示用户;然后用CreateStreamOnHGlobal函数建立一个基于全局堆内存块的流,第二个参数如果为True则流在释放时自动释放所占全局堆内存。如果建立成功则此流和刚刚建立的内存块共用同一块内存区域。接着用WebBrowser.Document.QueryInterface函数建立一个IPersistStreamInit接口。然后就可以直接使用此接口,psi.InitNew初始化状态;psi.Load(Stream)从流中载入HTML源码。 ---- 至此,以Html参数指定的HTML源码就在WebBrowser参数指定的控件中显示出来。 ---- 值得注意的是,每个关于COM接口的函数调用,也就是那些返回类型为HResult的函数,都必须以OleCheck包装,因为一个不检查返回状态的COM接口操作实在太危险了;此外接口的释放,虽然Delphi可以在后台自动完成,但作为一个好的编程习惯,还是应该显式地手工释放,释放只需将接口设为nil即可。 ---- 接着来实现HTML源码的读: function GetHtml(const WebBrowser:TWebBrowser): string;constBufSize = $10000;varSize: Int64;Stream: IStream;hHTMLText: HGLOBAL;psi: IPersistStreamInit;beginif not Assigned(WebBrowser.Document) then Exit;OleCheck(WebBrowser.Document.QueryInterface(IPersistStreamInit, psi));try//OleCheck(psi.GetSizeMax(Size));hHTMLText := GlobalAlloc(GPTR, BufSize);if 0 = hHTMLText then RaiseLastWin32Error;OleCheck(CreateStreamOnHGlobal(hHTMLText,True, Stream));tryOleCheck(psi.Save(Stream, False));Size := StrLen(PChar(hHTMLText));SetLength(Result, Size);CopyMemory(PChar(Result), Pointer(hHTMLText), Size);finallyStream := nil;end;finallypsi := nil;end;end;---- 此函数有一个参数WebBrowser指定从那个控件读取HTML源码,返回一个字符串为此控件中的HTML源码。首先还是要先检查WebBrowser.Document对象是否有效,无效则退出;然后取得IPersistStreamInit接口;接着取得HTML源码的大小:本来应该使用IPersistStreamInit接口的GetSizeMax函数,但在我的机器上测试,这个函数范围值衡为0,无效。因此只能先定义一个足够大的缓冲区,如BufSize = $10000字节(注意此缓冲区应该足够大);然后同样地分配全局堆内存块,建立流,然后将HTML文本写到流中。因为此HTML文本在流中是以#0结尾的字符串,因此可以用Size := StrLen(PChar(hHTMLText))取得实际长度,用SetLength(Result, Size);设置返回字符串长度为HTML源码实际长度,最后复制字符串到返回字符串中。 ---- 至此,直接访问WebBrowser控件中的HTML源码所需的两个函数全部解析完毕。 ---- 不过需要注意的时,在使用这两个函数前,最好对WebBrowser.Document对象进行初始化。下面提供一个函数,通过显示一个空白页面实现WebBrowser.Document对象初始化。 procedure ShowBlankPage(WebBrowser: TWebBrowser);varURL: OleVariant;beginURL := 'about:blank';WebBrowser.Navigate2(URL);end;---- 建议在你有WebBrowser控件的Form的FormCreate事件里调用此函数,初始化WebBrowser.Document对象。 ---- 本文程序在Win NT + Delphi 5 环境下调试通过 也可以说是delphi的bug。因为VCL库,把回车吃掉了。 我想了一个办法: 用hook监听键盘事件,当form获得焦点的时候用户敲回车了,我就在<textarea>中加一个Chr(13),呵呵~可惜不能给自己加分…… 同意easypaper的意见,世界上没有十全十美的事物嘛…… 数据库封装思路 控制控件名称问题 两个半月的足不出户的开发,很有心得,也领悟到了一些!叽叽歪歪,散分为主!“0” 如何才能提高级别散分呀我的分数太多了 请问如何枚举本机的所有的网卡和modem,并且获得他们的名称,IP地址和子网掩码? 请教!在com+的服务端如何取得客户端的ip地址,急用!! 怎么遍历树或者遍历树的某个子节点啊 有事没事多【散分】,请做选择题。 有谁知道珠海天心?给个意见哈! delphi自己的向下兼容性太差拉! 毛病多多... 真正的高手这边来!!! 关于货币格式转换问题
当时我一直不敢相信,后来启动vc,vb分别做了同样的东西,呵呵
一切正常~~~ 看来比尔还是对自己的亲生儿子要好一点,呵呵~
首先来实现写,因为这是最迫切的要求:
procedure SetHtml(const WebBrowser:
TWebBrowser; const Html: string);
var
Stream: IStream;
hHTMLText: HGLOBAL;
psi: IPersistStreamInit;
begin
if not Assigned(WebBrowser.Document) then Exit;hHTMLText := GlobalAlloc(GPTR, Length(Html) + 1);
if 0 = hHTMLText then RaiseLastWin32Error;CopyMemory(Pointer(hHTMLText),
PChar(Html), Length(Html));OleCheck(CreateStreamOnHGlobal
(hHTMLText, True, Stream));
try
OleCheck(WebBrowser.Document.
QueryInterface(IPersistStreamInit, psi));
try
OleCheck(psi.InitNew);
OleCheck(psi.Load(Stream));
finally
psi := nil;
end;
finally
Stream := nil;
end;
end;
---- 首先,此过程需要的两个参数,WebBrowser是显示目的控件,Html是需要显示的HTML源码;然后,先检查WebBrowser.Document对象是否有效,无效则退出;接着在系统全局堆里分配一块内存,将需要显示的HTML源码复制进去。这是因为下一步需要建立一个WebBrowser控件可以读取的流。GlobalAlloc函数的参数GPTR表示需要分配一块固定的以0初始化过的内存区域,如果分配失败则返回0,则通过RaiseLastWin32Error函数引发一个异常,提示用户;然后用CreateStreamOnHGlobal函数建立一个基于全局堆内存块的流,第二个参数如果为True则流在释放时自动释放所占全局堆内存。如果建立成功则此流和刚刚建立的内存块共用同一块内存区域。接着用WebBrowser.Document.QueryInterface函数建立一个IPersistStreamInit接口。然后就可以直接使用此接口,psi.InitNew初始化状态;psi.Load(Stream)从流中载入HTML源码。
---- 至此,以Html参数指定的HTML源码就在WebBrowser参数指定的控件中显示出来。 ---- 值得注意的是,每个关于COM接口的函数调用,也就是那些返回类型为HResult的函数,都必须以OleCheck包装,因为一个不检查返回状态的COM接口操作实在太危险了;此外接口的释放,虽然Delphi可以在后台自动完成,但作为一个好的编程习惯,还是应该显式地手工释放,释放只需将接口设为nil即可。 ---- 接着来实现HTML源码的读: function GetHtml(const WebBrowser:
TWebBrowser): string;
const
BufSize = $10000;
var
Size: Int64;
Stream: IStream;
hHTMLText: HGLOBAL;
psi: IPersistStreamInit;
begin
if not Assigned(WebBrowser.Document) then Exit;OleCheck(WebBrowser.Document.QueryInterface
(IPersistStreamInit, psi));
try
//OleCheck(psi.GetSizeMax(Size));
hHTMLText := GlobalAlloc(GPTR, BufSize);
if 0 = hHTMLText then RaiseLastWin32Error;OleCheck(CreateStreamOnHGlobal(hHTMLText,
True, Stream));
try
OleCheck(psi.Save(Stream, False));Size := StrLen(PChar(hHTMLText));
SetLength(Result, Size);
CopyMemory(PChar(Result), Pointer(hHTMLText),
Size);
finally
Stream := nil;
end;
finally
psi := nil;
end;
end;---- 此函数有一个参数WebBrowser指定从那个控件读取HTML源码,返回一个字符串为此控件中的HTML源码。首先还是要先检查WebBrowser.Document对象是否有效,无效则退出;然后取得IPersistStreamInit接口;接着取得HTML源码的大小:本来应该使用IPersistStreamInit接口的GetSizeMax函数,但在我的机器上测试,这个函数范围值衡为0,无效。因此只能先定义一个足够大的缓冲区,如BufSize = $10000字节(注意此缓冲区应该足够大);然后同样地分配全局堆内存块,建立流,然后将HTML文本写到流中。因为此HTML文本在流中是以#0结尾的字符串,因此可以用Size := StrLen(PChar(hHTMLText))取得实际长度,用SetLength(Result, Size);设置返回字符串长度为HTML源码实际长度,最后复制字符串到返回字符串中。
---- 至此,直接访问WebBrowser控件中的HTML源码所需的两个函数全部解析完毕。 ---- 不过需要注意的时,在使用这两个函数前,最好对WebBrowser.Document对象进行初始化。下面提供一个函数,通过显示一个空白页面实现WebBrowser.Document对象初始化。 procedure ShowBlankPage(WebBrowser:
TWebBrowser);
var
URL: OleVariant;
begin
URL := 'about:blank';
WebBrowser.Navigate2(URL);
end;---- 建议在你有WebBrowser控件的Form的FormCreate事件里调用此函数,初始化WebBrowser.Document对象。
---- 本文程序在Win NT + Delphi 5 环境下调试通过
用hook监听键盘事件,当form获得焦点的时候用户敲回车了,我就在<textarea>
中加一个Chr(13),呵呵~可惜不能给自己加分……
同意easypaper的意见,世界上没有十全十美的事物嘛……