======================================================
注:本文源代码点此下载
======================================================
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^)/