• 25240阅读
  • 21回复

在Qt中如何使用WebBrowser这个ActiveX控件 [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2006-12-21
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
以前用BCB和C#的时候,都曾用到过WebBrowser这个ActiveX控件,在BCB里称为CppWebBrowser,使用它来嵌入到程序中,很不错的功能。

现在用Qt,想在程序中嵌入一个网页浏览器,有哪些方法呢?

Qt自带了一个QTextBrowser,但是它只能显示简单的网页,复杂的就不行了。
对于嵌入式的浏览器引擎,现在用得比较多的是分别基于IE, Firefox(Gecko), Opera, Konqueror(khtml)这四个引擎的,但现在使用最多的恐怕就属前两者了。

基于IE内核引擎的浏览器很多,比如Maxton, 腾迅TT等。
基于Gecko的也比较多,主要是Linux下的比较多,比如Galen, Epiphany

当然,现在市面上还是基于IE资料比较多。但Gecko现在发展迅猛,并且源码公开,在Windows下的,它有各种嵌入组件,比如mfcEmbed, winEmbed, ActiveX Control等,在Linux下,有GtkMozEmbed等。那要写跨平台的Qt程序,使用浏览器嵌入组件该怎么选择呢?
花了一整天的时间来查找Embed Gecko方面的资料和试验,发现除了Linux下GtkMozEmbed发展比较好,windows下则比较少,并且windows下要想编译Gecko,最好是使用VC来编译,这就费劲了。

现在方案出来了,可在Windows下使用WebBrowser ActiveX控件, 在Linux下使用GtkMozEmbed模块。
GtkMozEmbed就不用说了,包装得比较方便使用,在Qt中用它的和,解决了Qt和Gtk如何混合编程就可以了。在Windows下要使用WebBrowser这个ActiveX控件,则比较麻烦,因为只有商业版的Qt中才提供ActiveQt模块以支持ActiveX/COM等的开发。

于是继续找资料,找到了一个国外的用C语言写的一个使用WebBrowser的包装,很是不错,可以到下面的网址去看资料:
http://www.codeguru.com/cpp/i-n/ieprogram/article.php/c4379/

从下面的网址把他的程序源码下载下来:
http://www.codeguru.com/code/legacy/ieprogram/cwebpage.zip
解压后里面有下面我们需要的文件(原作者是用VC编译的)
cwebpage.dll     动态库,可直接拿来用
cwebpage.h     头文件
dll.def           库导出文件,我们要使用这个生成mingw编译需要的.a文件

第一步,生成.a文件:

dlltool -k -d dll.def -l libcwebpage.a

现在我们得到了Qt程序要使用的三个文件:cwebpage.dll, cwebpage.h, libcwebpage.a

接着,修改Qt程序,在.pro工程文件中加上链接库:

LIBS += -Lyour_libcwebpage_dir -lcwebpage


接着,在Qt程序中加入头文件:

#include "cwebpage.h"

下面是头文件内容:

/*
* This include file is meant to be included with any C source you
* write which uses the cwebpage DLL.
*/

#ifndef __CWEBPAGE_H_INCLUDED
#define __CWEBPAGE_H_INCLUDED

#include <windows.h>

#ifdef __cplusplus
{
#endif

long WINAPI EmbedBrowserObject(HWND);
#define EMBEDBROWSEROBJECT EmbedBrowserObject
typedef long WINAPI EmbedBrowserObjectPtr(HWND);

void WINAPI UnEmbedBrowserObject(HWND);
#define UNEMBEDBROWSEROBJECT UnEmbedBrowserObject
typedef long WINAPI UnEmbedBrowserObjectPtr(HWND);

long WINAPI DisplayHTMLPage(HWND, LPCTSTR);
#define DISPLAYHTMLPAGE DisplayHTMLPage
typedef long WINAPI DisplayHTMLPagePtr(HWND, LPCTSTR);

long WINAPI DisplayHTMLStr(HWND, LPCTSTR);
#define DISPLAYHTMLSTR DisplayHTMLStr
typedef long WINAPI DisplayHTMLStrPtr(HWND, LPCTSTR);

#ifdef __cplusplus
}
#endif
#endif /* __CWEBPAGE_H_INCLUDED */



我们看到,这个头文件中声明了四个函数:
long WINAPI EmbedBrowserObject(HWND);
void WINAPI UnEmbedBrowserObject(HWND);
long WINAPI DisplayHTMLPage(HWND, LPCTSTR);
long WINAPI DisplayHTMLStr(HWND, LPCTSTR);
参考作者提供的源代码里的程序,可知,EmbedBrowserObject用于初始化,UnEmbedBrowserObject用于卸载,DisplayHTMLPage和DisplayHTMLStr分别用于显示网址和字符串内容。

有了这些,在Qt程序中就好用了:
新建一个widget的时候:

QWidget *widget = new QWidget(this);
EmbedBrowserObject(widget->winId());

显示内容的时候:

DisplayHTMLPage(widget->winId(), (TCHAR *)(QString("http://www.qtcn.org").toStdString().c_str()));

或者显示字符串:

DisplayHTMLStr(widget->winId(), (TCHAR *)(QString("<h1>你好世界</h1>").toStdString().c_str()));

删除这个widget前的时候:

UnEmbedBrowserObject(widget->winId());
delete widget;


为了方便使用,用户可从QWidget继承一个类,把这四个函数的操作封装进去。


下面就可以开始编译了,但是,链接时会出现错误,主要问题在于库的不同而不能正确识别符号:
只要把头文件的声明头改下就可以为mingw所用了(当然以前那个VC可直接使用的)

/*
* This include file is meant to be included with any C source you
* write which uses the cwebpage DLL.
*/

#ifndef __CWEBPAGE_H_INCLUDED
#define __CWEBPAGE_H_INCLUDED

#include <windows.h>
#define DLLIMPORT __declspec (dllimport)

#ifdef __cplusplus
extern "C" {
#endif

long DLLIMPORT EmbedBrowserObject(HWND);
#define EMBEDBROWSEROBJECT EmbedBrowserObject
typedef long DLLIMPORT EmbedBrowserObjectPtr(HWND);

void DLLIMPORT UnEmbedBrowserObject(HWND);
#define UNEMBEDBROWSEROBJECT UnEmbedBrowserObject
typedef long DLLIMPORT UnEmbedBrowserObjectPtr(HWND);

long DLLIMPORT DisplayHTMLPage(HWND, LPCTSTR);
#define DISPLAYHTMLPAGE DisplayHTMLPage
typedef long DLLIMPORT DisplayHTMLPagePtr(HWND, LPCTSTR);

long DLLIMPORT DisplayHTMLStr(HWND, LPCTSTR);
#define DISPLAYHTMLSTR DisplayHTMLStr
typedef long DLLIMPORT DisplayHTMLStrPtr(HWND, LPCTSTR);

#ifdef __cplusplus
}
#endif
#endif /* __CWEBPAGE_H_INCLUDED */


关于为什么要这样改,各位可查找一下不同开发工具所做的DLL库之间的不同方面的资料。

OK,大功告成了。附件中来副截图。辛辛苦苦搞这个东西,花了三个晚上的时间找资料和试验最终确定方案,辛苦没白费。
[ 此贴被XChinux在2007-01-16 15:02重新编辑 ]
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线lsosa

只看该作者 1楼 发表于: 2006-12-22
恩,好东东。。。
离线ipconfig
只看该作者 2楼 发表于: 2007-01-20
GtkMozEmbed是基于GTK的,要是用在嵌入式领域的话,就会产生库的依赖关系。不太清楚konqueror有没有相应的Embedding Widget
离线langr
只看该作者 3楼 发表于: 2008-07-09
hehe~ 顶你一下,找了好久才找到这里来,
不过现在用 WebKit 好像就很好用了的,但网页里面有flash的地方就显示不出来了,不知道该怎样解决呢??
离线lugaideath

只看该作者 4楼 发表于: 2008-07-28
dlltool那个命令是怎么来的?
离线lugaideath

只看该作者 5楼 发表于: 2008-07-29
我的开发环境是LINUX!我在WINDOWS上用dlltool取得那文件以后,我要怎么做?在LINUX行吗?

可以给我个例子吗?谢谢!
离线XChinux

只看该作者 6楼 发表于: 2008-07-29
实际上使用的是mshtml,所以在linux下不能用。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线yxr52051801
只看该作者 7楼 发表于: 2008-07-30
好办法:我试了一下行 我是继承了QWidget类 新建一个qwidget 布局 但是我存在一点问题 :最后显示的浏览页面很小,不知道什么原因?
离线XChinux

只看该作者 8楼 发表于: 2008-07-30
使用之前先把其嵌入到的widget设置到指定大小。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线yxr52051801
只看该作者 9楼 发表于: 2008-07-31
谢谢版主,页面设置为指定大小,可以看见了  但是为什么不能跟着主窗口最大化最小化呢 ?
离线songxizg

只看该作者 10楼 发表于: 2009-04-23
为什么我用VC不改编译不过呢?
改了连接不过,提示打不开库。
1>LINK : fatal error LNK1181: cannot open input file 'cwebpage.lib'
[ 此帖被songxizg在2009-04-23 15:33重新编辑 ]
离线laurentium
只看该作者 11楼 发表于: 2009-06-30
无法加载库
不管是他自己提供的还是重新生成的
但是他的测试程序却可以打开,奇怪
离线laurentium
只看该作者 12楼 发表于: 2009-06-30
unicode程序无法加载dll
即使将他的dll重新以unicode编译
离线laurentium
只看该作者 13楼 发表于: 2009-06-30
大家都能加载吗??
unicode程序能加载吗
离线andyfly
只看该作者 14楼 发表于: 2009-09-03
请问我按照你的方法编译成功了 但是FLASH还是播放不了,在FLASH上按右键能显示播放器菜单,这是什么原因呢

QString web(
    "<html>"
    "<body>"
    //<embed src="flash/top.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="930" height="319"></embed>
    "<td><embed src='11.swf' quality='high' pluginspage='http://www.macromedia.com/go/getflashplayer' type='application/x-shockwave-flash' ></embed></td>"
    "</body>"
    "</html>"
    );
    widget = new QWidget(this);
    widget->setGeometry(0,0,200,200);
    EmbedBrowserObject(widget->winId());
  DisplayHTMLStr(widget->winId(), (TCHAR *)(web.toStdString().c_str()));
Andycavalier
离线lrbnk

只看该作者 15楼 发表于: 2010-02-09
大版主,麻烦你介绍下如何获得GtkMozEmbed这个模块好吗?我在网上查很多都是在FIREFOX目录下,而我的FIREFOX目录下却没有。
离线紫露霜凝
只看该作者 16楼 发表于: 2010-02-27
请问各位版主的.a文件是怎么生成的啊,我怎么没找到dlltool文件啊
离线午小夜

只看该作者 17楼 发表于: 2010-03-23
引用第16楼紫露霜凝于2010-02-27 14:52发表的  :
请问各位版主的.a文件是怎么生成的啊,我怎么没找到dlltool文件啊


用Qt Command Prompt.
[操作系统版本]  Windows XP;Linux Ubuntu;Linux Fedora;
[Qt SDK版本]    4.7.0
[SDK 发布日期]  2010.05
[IDE(集成开发环境)] QtCreator
个人网页:http://hi.baidu.com/午小夜
學歷:Royal Jalidon
离线huaqglxy

只看该作者 18楼 发表于: 2010-05-06
能把你的源代码穿上来给我们看看吗
离线tingsking

只看该作者 19楼 发表于: 2010-05-06
太麻烦了,Qt的example里面有例子
我的blog:http://blog.csdn.net/tingsking18
http://blog.csdn.net/tingsking18
离线huaqglxy

只看该作者 20楼 发表于: 2010-05-07
哪一个?找了,但是不能运行...能不能来个能看到结果的简单demo?
离线XChinux

只看该作者 21楼 发表于: 2011-01-23
现在没必要用这个了吧,有了webkit,就可以实现我们所需要的功能了。如果非要用IE,那就用ActiveQt来搞定。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个