Delphi TWebBrowser编程简述(转帖)

本文介绍了Delphi中TWebBrowser控件的基本使用方法,包括打开本地网页文件、处理JS代码执行错误、初始化与终止化、命令操作、字体大小调整、收藏夹操作、焦点获取、点击提交按钮等常见问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


======================================================
注:本文源代码点此下载
======================================================

delphi twebbrowser编程简述(转帖)

delphi 3开始有了twebbrowser构件,不过那时是以activex控件的形式出现的,而且需要自己引入,在其后的4.0和5.0中,它就在封装好shdocvw.dll之后作为internet构件组之一出现在构件面板上了。常常听到有人骂delphi的帮助做得极差,这次的twebbrowser又是microsoft的东东,自然

这里有平时我自己用twebbrowser做程序的一些心得和上网收集到的部分例子和资料,整理了一下,希望能给有兴趣用twebbrowser编程的朋友带来些帮助。

-----------------------------------------------------------------

twebbrowser控件打开本地网页文件,如何让它不弹出警告

twebbrowser控件打开包含了js代码本地的网页文件就会弹出错误对话框

请问怎么才能去掉这个对话框并且能执行js脚本?

网友回复:twebbrowser控件打开包含了js代码的本地网页文件就会弹出错误对话框

请问怎么才能去掉这个对话框并且能执行js脚本?

看到一些邮件客户端的编辑器就是调用了本地网页文件,但是却不弹出对话框

网友回复:twebbrowser的ondownloadcomplete事件里面执行

(webbrowser1.document as ihtmldocument2).parentwindow.execscript('window.onerror=function(){return true}','javascript');

网友回复:谢谢ideation_shang

------------------------------------------------------------------

注意:

1、css对打印的控制:

noprint样式可以使页面上的打印按钮等不出现在打印页面上,这一点非常重要,因为它可以用最少的代码完成最需要的功能

pagenext样式可以设置分页,在需要分页的地方

就ok了,呵呵

-----------------------------------------------------------------

webbrowser.execwb(1,1)打开

webbrowser.execwb(2,1)关闭现在所有的ie窗口,并打开一个新窗口

webbrowser.execwb(4,1)保存网页

webbrowser.execwb(6,1)打印

webbrowser.execwb(7,1)打印预览

webbrowser.execwb(8,1)打印页面设置

webbrowser.execwb(10,1)查看页面属性

webbrowser.execwb(15,1)好像是撤销,有待确认

webbrowser.execwb(17,1)全选

webbrowser.execwb(22,1)刷新

webbrowser.execwb(45,1)关闭窗体无提示

----------------------------------------------------------

1、初始化和终止化(initialization & finalization)

大家在执行twebbrowser的某个方法以进行期望的操作,如execwb等的时候可能都碰到过“试图激活未注册的丢失目标”或“ole对象未注册”等错误,或者并没有出错但是得不到希望的结果,比如不能将选中的网页内容复制到剪贴板等。以前用它编程的时候,我发现execwb有时侯起作用但有时侯又不行,在delphi生成的缺省工程主窗口上加入twebbrowser,运行时并不会出现“ole对象未注册”的错误。同样是一个偶然的机会,我才知道ole对象需要初始化和终止化(懂得的东东实在太少了)。

我用我的前一篇文章《delphi程序窗口动画&正常排列平铺的解决》所说的方法编程,运行时出了上面所说的错误,我便猜想应该有oleinitialize之类的语句,于是,找到并加上了下面几句话,终于搞定!究其原因,我想大概是由于twebbrowser是一个嵌入的ole对象而不算是用delphi编写的vcl吧。

initialization

oleinitialize(nil);

finalization

try

oleuninitialize;

except

end;

这几句话放在主窗口所有语句之后,“end.”之前。

-----------------------------------------------------------------------------------

2、emptyparam

在delphi 5中twebbrowser的navigate方法被多次重载:

procedure navigate(const url: widestring); overload;

procedure navigate(const url: widestring; var flags: olevariant); overload;

procedure navigate(const url: widestring; var flags: olevariant; var targetframename:olevariant); overload;

procedure navigate(const url: widestring; var flags: olevariant; var targetframename:olevariant; var postdata: olevariant); overload;

procedure navigate(const url: widestring; var flags: olevariant; var targetframename:olevariant; var postdata: olevariant; var headers: olevariant); overload;

而在实际应用中,使用后几种方法调用时,由于我们很少用到后面几个参数,但函数声明又要求是变量参数,一般的做法如下:

var

t:olevariant;

begin

webbrowser1.navigate(edit1.text,t,t,t,t);

end;

需要定义变量t(还有很多地方要用到它),很麻烦。其实我们可以用emptyparam来代替(emptyparam是一个公用的variant空变量,不要对它赋值),只需一句话就可以了:

webbrowser1.navigate(edit1.text,emptyparam,emptyparam,emptyparam,emptyparam);

虽然长一点,但比每次都定义变量方便得多。当然,也可以使用第一种方式。

webbrowser1.navigate(edit1.text)

-----------------------------------------------------------------------------------

3、命令操作常用的命令操作用execwb方法即可完成,execwb同样多次被重载:

procedure execwb(cmdid: olecmdid; cmdexecopt: olecmdexecopt); overload;

procedure execwb(cmdid: olecmdid; cmdexecopt: olecmdexecopt; var pvain:

olevariant); overload;

procedure execwb(cmdid: rolecmdid; cmdexecopt: olecmdexecopt; var pvain:

olevariant; var pvaout: olevariant); overload;

打开: 弹出“打开internet地址”对话框,commandid为olecmdid_open(若浏览器版本为ie5.0,则此命令不可用)。

另存为:调用“另存为”对话框。

execwb(olecmdid_saveas,olecmdexecopt_dodefault, emptyparam,

emptyparam);

打印、打印预览和页面设置: 调用“打印”、“打印预览”和“页面设置”对话框(ie5.5及以上版本才支持打印预览,故实现应该检查此命令是否可用)。

execwb(olecmdid_print, olecmdexecopt_dodefault, emptyparam,

emptyparam);

if querystatuswb(olecmdid_printpreview)=3 then

execwb(olecmdid_printpreview, olecmdexecopt_dodefault,

emptyparam,emptyparam);

execwb(olecmdid_pagesetup, olecmdexecopt_dodefault, emptyparam,

emptyparam);

剪切、复制、粘贴、全选: 功能无须多说,需要注意的是:剪切和粘贴不仅对编辑框文字,而且对网页上的非编辑框文字同样有效,用得好的话,也许可以做出功能特殊的东东。获得其命令使能状态和执行命令的方法有两种(以复制为例,剪切、粘贴和全选分别将各自的关键字替换即可,分别为cut,paste和selectall):

a、用twebbrowser的querystatuswb方法。

if(querystatuswb(olecmdid_copy)=olecmdf_enabled) or

olecmdf_supported) then

execwb(olecmdid_copy, olecmdexecopt_dodefault, emptyparam,

emptyparam);

b、用ihtmldocument2的querycommandenabled方法。

var

doc: ihtmldocument2;

begin

doc :=webbrowser1.document as ihtmldocument2;

if doc.querycommandenabled('copy') then

doc.execcommand('copy',false,emptyparam);

end;

查找: 参考第九条“查找”功能。

-----------------------------------------------------------------------------------

4、字体大小

类似“字体”菜单上的从“最大”到“最小”五项(对应整数0~4,largest等假设为五个菜单项的名字,tag 属性分别设为0~4)。

a、读取当前页面字体大小。

var

t: olevariant;

begin

webbrowser1.execwb(olecmdid_zoom, olecmdexecopt_dontpromptuser,

emptyparam,t);

case t of

4: largest.checked :=true;

3: larger.checked :=true;

2: middle.checked :=true;

1: small.checked :=true;

0: smallest.checked :=true;

end;

end;

b、设置页面字体大小。

largest.checked :=false;

larger.checked :=false;

middle.checked :=false;

small.checked :=false;

smallest.checked :=false;

tmenuitem(sender).checked :=true;

t :=tmenuitem(sender).tag;

webbrowser1.execwb(olecmdid_zoom, olecmdexecopt_dontpromptuser,

t,t);

-----------------------------------------------------------------------------------

5、添加到收藏夹和整理收藏夹

const

clsid_shelluihelper: tguid = '{64ab4bb7-111e-11d1-8f79-00c04fc2fbe1}';

var

p:procedure(handle: thandle; path: pchar); stdcall;

procedure tform1.organizefavorite(sender: tobject);

var

h: hwnd;

begin

h := loadlibrary(pchar('shdocvw.dll'));

if h' then

begin

shelluihelper := createcomobject(clsid_shelluihelper) as ishelluihelper;

shelluihelper.addfavorite(url, title);

end;

end;

用上面的通过ishelluihelper接口来打开“添加到收藏夹”对话框的方法比较简单,但是有个缺陷,就是打开的窗口不是模式窗口,而是独立于应用程序的。可以想象,如果使用与organizefavorite过程同样的方法来打开对话框,由于可以指定父窗口的句柄,自然可以实现模式窗口(效果与在资源管理器和ie中打开“添加到收藏夹”对话框相同)。问题显然是这样的,上面两个过程的作者当时只知道shdocvw.dll中doorganizefavdlg的原型而不知道doaddtofavdlg的原型,所以只好用ishelluihelper接口来实现(或许是他不够严谨,认为是否是模式窗口无所谓?)。

下面的过程就告诉你doaddtofavdlg的函数原型。需要注意的是,这样打开的对话框并不执行“添加到收藏夹”的操作,它只是告诉应用程序用户是否选择了“确定”,同时在doaddtofavdlg的第二个参数中返回用户希望放置internet快捷方式的路径,建立.url文件的工作由应用程序自己来完成。

procedure tform1.addfavorite(ie: tembeddedwb);

procedure createurl(aurlpath, aurl: pchar);

var

urlfile: tinifile;

begin

urlfile := tinifile.create(string(aurlpath));

rlfile.writestring('internetshortcut', 'url', string(aurl));

rlfile.free;

end;

var

addfav: function(handle: thandle;

urlpath: pchar; urlpathsize: cardinal;

title: pchar; titlesize: cardinal;

favidlist: pitemidlist): bool; stdcall;

fdoc: ihtmldocument2;

urlpath, url, title: array[0..max_path] of char;

h: hwnd;

pidl: pitemidlist;

fretok: bool;

begin

fdoc := ihtmldocument2(ie.document);

if fdoc = nil then exit;

strpcopy(title, fdoc.get_title);

strpcopy(url, fdoc.get_url);

if url0 then

begin

shgetspecialfolderlocation(0, csidl_favorites, pidl);

addfav := getprocaddress(h, pchar('doaddtofavdlg'));

if assigned(addfav) then

fretok :=addfav(handle, urlpath, sizeof(urlpath), title, sizeof(title), pidl)

end;

freelibrary(h);

if fretok then

createurl(urlpath, url);

end

end;

-----------------------------------------------------------------------------------

6、使webbrowser获得焦点

twebbrowser非常特殊,它从twincontrol继承来的setfocus方法并不能使得它所包含的文档获得焦点,从而不能立即使用internet explorer本身具有得快捷键,解决方法如下: nil then

with webbrowser1.application as ioleobject do

doverb(oleiverb_uiactivate, nil, webbrowser1, 0, handle, getclientrect);

end;

除此之外,我还找到一种更简单的方法,这里一并列出:

if webbrowser1.documentnil then

ihtmlwindow4(webbrowser1.document).focus

还有,需要判断文档是否获得焦点这样来做:

if ihtmlwindow4(webbrowser1.document).hasfocus then

-----------------------------------------------------------------------------------

7、点击“提交”按钮

如同程序里每个窗体上有一个“缺省”按钮一样,web页面上的每个form也有一个“缺省”按钮——即属性为“submit”的按钮,当用户按下回车键时就相当于鼠标单击了“submit”。但是twebbrowser似乎并不响应回车键,并且,即使把包含twebbrowser的窗体的keypreview设为true,在窗体的keypress事件里还是不能截获用户向twebbrowser发出的按键。

我的解决办法是用applicatinevents构件或者自己编写tapplication对象的onmessage事件,在其中判断消息类型,对键盘消息做出响应。至于点击“提交”按钮,可以通过分析网页源代码的方法来实现,不过我找到了更为简单快捷的方法,有两种,第一种是我自己想出来的,另一种是别人写的代码,这里都提供给大家,以做参考。

a、用sendkeys函数向webbrowser发送回车键

在delphi 5光盘上的info\extras\sendkeys目录下有一个sndkey32.pas文件,其中包含了两个函数sendkeys和appactivate,我们可以用sendkeys函数来向webbrowser发送回车键,我现在用的就是这个方法,使用很简单,在webbrowser获得焦点的情况下(不要求webbrowser所包含的文档获得焦点),用一条语句即可:

sendkeys('~',true);// press return key

sendkeys函数的详细参数说明等,均包含在sndkey32.pas文件中。

b、在onmessage事件中将接受到的键盘消息传递给webbrowser。

procedure tform1.applicationevents1message(var msg: tmsg; var handled: boolean);

{fixes the malfunction of some keys within webbrowser control}

const

stdkeys = [vk_tab, vk_return]; { standard keys }

extkeys = [vk_delete, vk_back, vk_left, vk_right]; { extended keys }

fextended = $01000000; { extended key flag }

begin

handled := false;

with msg do

if ((message >= wm_keyfirst) and (message 关注我收藏该文与我联系

posted on 2008-06-26 10:03 imustdo 阅读(1943) 评论(0)编辑 收藏


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值