万星星@豌豆荚 欢迎加入我们
一个吃软饭的男人!!!!!我只想写程序####
微博:
http://weibo.com/wanlianwen
C++博客
首页
新文章
新随笔
聚合
管理
posts - 172, comments - 1253, trackbacks - 0
用MFC实现WebGUI--(CDHtmlDialog)
自从去年年底一次棘手的界面,开始研究用web做界面到现在大约1年,这一年间不是局限在实现层面,也并非一直研究这一个问题,有很多问题其实不是问题,只是自己没有想清楚或者思想没放开。对于一个界面开发人员,想必拉的对话框不少于100个,腻味不必说,光是对话框大小改变导致控件跟着变化都需要一番功夫,加上界面美观,界面的风格统一,界面的灵活多变......,头痛。在对话框里面加载位图,加载gif,超链接......,啊,没法控制了吧!在考虑远点,现在.net3.0技术已经完全打破应用和桌面的界限,我们的界面html资源完全可以放在一个web站点上,这样界面是完全动态的。
其间写过2篇这方面的文章,基于vc6实现,绕弯很大。在vc7.1、vc8里面要简单很多,主要是把几个以前为公开的类公开了,最重要的是在CWnd里面加入了一个虚函数CreateControlSite使得有机会改变控件站点以修改控件行为。在mfc类层次上,CHTMLView和CDHtmlDialog为开发者提供了创建webgui的一系列基础设施,包括事件机制、窗口行为、以及对html文档操纵接口。我们在此基础上实现webgui很简单,然而仍然困惑我很久,经理也催过我几次我一直未肯决定最终方案。在我脑袋里一直琢磨是要应用程序完全操纵html文档,还是html访问应用获取信息,其实就是它们之间的通信模式。一直到昨天我才定下方案,应用通过IWebBrowser2接口操纵html元素,html通过vbscript、javascript脚本响应本身事件,访问应用。主要是考虑通信自然畅通,而以前我一味想通过应用指令完全控制html元素,导致去解析html文档,费力不讨好。下面开始我的想法:
写一个dll,封装CDHtmlDialog,提供一个类似html容器的对话框,功能就是加载html网页,以及创建与html呼应的com组件。它本身不包含与应用功能有关代码,应用有关的部分是html页面和对于的com功能组件。这里需要对CDHtmlDialog进行了适当的改造以适合自己的目标:
首先从CDHtmlDialog派生一个类CHTMLContainerDlg,默认情况下会生成一个网页资源,这个网页是这个对话框创建时加载的,我们需要的其实是一个容器而不是一个具体的对话框,所以删除网页资源,修改对话框头文件:
enum { IDD = IDD_HTMLCONTAINERDLG, IDH = 0 };
这里把IDH修改为0,因为我们删除了网页资源。然而在对话框创建后会加载该资源,在CDHtmlDialog的OnInitDialog函数里面我们可以看到:
if (m_nHtmlResID)
LoadFromResource(m_nHtmlResID);
else if (m_szHtmlResID)
LoadFromResource(m_szHtmlResID);
else if (m_strCurrentUrl)
Navigate(m_strCurrentUrl);
结果就是对话框一出现就会出现加载一个无效地址的页面,出现无法打开链接的页面,为了避免这个问题,需要重载OnInitDialog函数。其实就是拷贝mfc代码然后去掉上面那段代码就ok,强制不加载页面。那么为了加载指定页面,需要一个函数:
void CHTMLContainerDlg::SetHtmlAndCom(CString strURL, CString strProg)
{
HRESULT hr = NOERROR;
m_strURL = strURL;
hr = m_spComDisp.CoCreateInstance(strProg);
if(FAILED(hr))
{
TRACE(_T("Some error when create com object
\n"));
}
SetExternalDispatch(m_spComDisp);
}
指定html的url和对应功能组件的progid,这样在网页里面可以通过脚本window.external访问该com组件。
这样就可以加载html网页,但是html页面里面的元素风格却是2k风格(至少在ie7以下版本是如此),这个怕是没起到一点美观作用,为之我考虑了半天,问过做web的人是否有办法,最终还是灵感光临,误撞上了。重载GetHostInfo函数:
STDMETHODIMP CHTMLContainerDlg::GetHostInfo(DOCHOSTUIINFO* pInfo)
{
pInfo->dwFlags = DOCHOSTUIFLAG_THEME;
return S_OK;
}
这个多得不说,^_^。
下面就可以演示了,在vs2005里面找个向导来show一下:
CHTMLContainerDlg dlg;
TCHAR szPath[MAX_PATH]
=
{
0
}
;
CString strPath;
GetCurrentDirectory(MAX_PATH, szPath);
strPath
=
szPath;
strPath
+=
_T(
"
\\Default.htm
"
);
dlg.SetHtmlAndCom(strPath, _T(
"
TestWebCom.WebComCtrl
"
));
dlg.DoModal();
对话框标题其实可以通过解析html文档获取title标题设置,目前还未处理。下面看看html与应用交互的组件。
生成一个atl工程,TestWebCom,添加一个com组件WebComCtrl,添加方法处理上面那个带...的按钮(文件夹浏览按钮):
STDMETHODIMP CWebComCtrl::ShowFolderBrowser(
void
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//
TODO: 在此添加实现代码
AfxMessageBox(_T(
"
In Com, you can show folder select dialog
"
));
return
S_OK;
}
这里不作具体处理,只是象征性弹出一个对话框。好了,上面我们在对话框里面已经设置了com组件的progid,这里可以把html和组件关联上了,通过脚本可以访问com组件方法:
<
BUTTON
CLASS
="buttonClass3Custom"
ID
="BrowseBtn"
TYPE
="BUTTON"
TITLE
="浏览头文件。"
onClick
="OnBrowseHeaderFile();"
>
</
BUTTON
>
脚本如下:
function
OnBrowseHeaderFile()
{
window.external.ShowFolderBrowser();
}
下面运行试一试,按下选择文件夹按钮会出现如下询问组件是否安全的对话框:
这个很恼人,用户可没有耐心忍受每次多弹出这个对话框询问组件是否安全。我开始打算将组件实现安全接口解决掉此问题,不过不知道缘何,没有成功,网上搜索一下好像说在ie7里面无效,没办法还是看mfc源码来解决问题。
CDHtmlDialog类获取external代码如下:
STDMETHODIMP CDHtmlDialog::GetExternal(IDispatch
**
ppDispatch)
{
if
(ppDispatch
==
NULL)
return
E_POINTER;
*
ppDispatch
=
NULL;
if
(m_spExternalDisp.p
&&
CanAccessExternal())
{
m_spExternalDisp.p
->
AddRef();
*
ppDispatch
=
m_spExternalDisp.p;
return
S_OK;
}
return
E_NOTIMPL;
}
看到CanAccessExternal函数,肯定就是验证安全性的代码,找到函数声明,幸好是虚函数,重载直接返回TRUE:
BOOL CHTMLContainerDlg::CanAccessExternal()
{
//
we trust all com object (haha, you can make virus)
return
TRUE;
}
有兴趣的朋友可以看下内部实现。
这下就好了,按下网页选择文件夹按钮,弹出对话框:
一套流程完备,方案个人觉得不错,各司其职,通信自然畅通,一个html配对一个com功能组件,功能组件化不仅使代码封装性好,而且可以用于多种语言。
由于此技术不用于公司开发,今整理提供
下载
posted on 2006-12-15 21:11
万连文
阅读(25808)
评论(40)
编辑
收藏
引用
所属分类:
MFC
FeedBack:
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2006-12-19 22:40 |
noname
的确不错. 用 html 做界面在开发效率, 扩展性等方面都很好. 正巧这两天需要做一个程序. 界面要求比较灵活. 就试试万兄的 idea 了.
用 WTL 做了一个 demo. 因为是第一次做这样的应用, 先不考虑代码复用了. 所以没有做成 DLL. 连页面的 ExternalDispatch 都是在程序内部实现的.
既然万兄没有给出源码, 我把代码放上来. 算是狗尾续貂把. :)
http://nicoster.googlepages.com/wtlhtml.rar
lieph $(at) 163 $(dot) com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2006-12-20 14:10 |
cooelaf
看了万兄的blog,很赞叹万兄在这方面的造诣。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2006-12-25 10:51 |
shaolong
万哥,可否把你说的这个例子代码公开一下呢?我刚入门做嵌入html的vc项目,也是CDHTMLDialog派生的类,但不知该如何实现函数接口的对应,时间很紧,郁闷的很,谢谢了!
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2006-12-25 11:04 |
万连文
邮件给我,我发你。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2006-12-26 23:59 |
xhl
我在VC6下曾做过WEBGUI,对你的想法很感兴趣,想知道如何用com封装功能,已经在html中怎样调用com组件。
能把你的示例代码发一份给我吗?
我的邮箱hongziyue@sina.com
多谢!
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2006-12-27 00:01 |
xhl
我在VC6下曾做过WEBGUI,对你的想法很感兴趣,想知道如何用com封装功能,以及在html中怎样调用com组件。
能把你的示例代码发一份给我吗?
我的邮箱hongziyue@sina.com
多谢!
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-01-28 14:04 |
xie
我是个初学者也想要一份多谢了
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-02-25 17:55 |
kukustream
很感兴趣,可否将示例的源码发给我一份,谢谢! kukuStream@hotmail.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-03-05 17:24 |
xq
万前辈,我早就想想学学这种技术,苦于资料难找,今得遇高人。
给我一份,万分感谢。waterdo@gmail.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-03-05 22:47 |
万连文
看有如此多人索要代码,实感意外。由于当时调试代码比较凌乱外加当初是为公司开发,代码没有公开。现在看来公司不会采用了,可能思考方式不同。最近在搞毕业开题,过1周后我将整理代码并公布于本页下载。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-03-10 13:08 |
万连文
下载文件已经提供,vs2005环境,关于其他环境本人不打算移植。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-08-15 18:44 |
lanse
我想要一份
lanse8482@sina.com.cn
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-09-05 11:35 |
我也想要一份,拜托啦
我也想要一份,拜托啦
haiminger@163.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-09-05 14:10 |
万连文
唉,真不知该如何说了,下载就在下面,不过字有些小罢了。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-10-13 08:52 |
yefeng
我也想要一份,拜托啦 !
yefeng654321@126.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-12-03 16:12 |
Ason Jia
最近我也在弄这个,但是我有遇见一个问题,因为中间的html大小(不是文件大小,是html的宽度和高度)是会变的,所以我有想动态从html获取大小,具体做法是,html中有一个变量来保存html大小,当html被加载的时候,就由js动态算出大小,然后我们的dialog去获取这个大小(使用IWebBrowser2直接去查询html中此值),然后动态调整dialog的大小以适应html的大小,但是问题也就出在这儿:html在加载的时候,经常会因为一些原因使得DOM中这个element没有创建出来,或者此element有创建出来,但是大小却没有计算出来(也就是此节点有,但是value是“0”),汗~~~~~这个问题我想了很久都解决不了
不知道作者可否提供一些帮助,再次非常感谢~~~
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-12-04 10:10 |
万连文
我的想法:
html被加载的时候,最好不要去使用html的东西,这个时候dom文档还没有加载完全。你需要在OnDocumentCompleted事件的时候去调用脚本,然后去修改对话框大小。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-12-04 15:04 |
Ason Jia
我也想过OnDocumentCompleted消息被触发的时候去获取,但是测试的时候发现,这个消息函数被触发了,但是html还是没有准确的计算出大小。
那你提到的在这个函数里面调用JS的方法算出大小,这个我没去试过,其实我是不知道,汗~~~对COM不太熟悉。
但是这样看来,好像是可行的。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-12-04 15:14 |
万连文
我想你可能错误的认识了这个东西。html是没有办法计算大小的,它的layout依赖于web控件的大小。采取这种方法做界面,最好针对一类html页面大小固定的功能使用一个对话框类,这样设置对话框固定大小即可以,且对于一类对话框,功能处理也比较类似。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2007-12-05 17:38 |
Ason Jia
目前我也是比较倾向这种思路,无奈老板说,俺们的产品要做n国语言,因为语言的不同,还是你提到的控件的不同,直接造成html大小的变化,晕~~~
不过在C中调用js方法,我已经弄出来了,无奈只能在这个方向先做一番苦功先了
汗~~
实在不行,那我就只能写死了~
谢谢老万同学的帮忙和指点,呵呵。。。。再次感谢~
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2008-06-19 06:39 |
arthurlee
一开始以为需要自己实现active scriping的接口,看了这篇文章才知道方法如此简单。
十分感谢!
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2008-10-13 17:58 |
阿里
实际上这并未提供active scriping的接口,而仅仅是对WebBrowser控件的额外控制,如果不用MFC可能需要用到接口IDocHostUIHandler,IDocHostUIHandler2和IDocHostShowUI。
实现自己的Active Scripting,需要用IActiveScriptSite
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)[未登录]
2008-11-06 12:01 |
yy
您好 我也想要一份代码看看,谢谢!
yangyong_v@163.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2008-11-10 10:28 |
万连文
来自原子时代--您的email有问题???
很抱歉这么晚回复你,因为最近病了。首先,我对一个女孩子从事C++开发表达敬佩。说到界面开发,绝对不会是一个简单的任务,甚至连一本真正的好的技术书籍都没有。CDHtmlDialog是vs2003以后的sdk添加进去的,不过这个用的人也不多,但是简单很多。我一般使用的是atl里面提供的一个窗口类ATLAXWIN_CLASS来实现的,这个在vc6里面也有。根据我的经验,能使用html+css+JS来实现界面编程的人技术都不一般,至少对com有一些了解。对于您目前的情况,如果使用vc6开发可以考虑ATLAXWIN_CLASS这个类进行编程,依赖atl库,跟mfc无关。具体的例子我手头没有,可以查阅www.codeproject.com
www.codeguru.com等技术网站。如果你自己尝试之后还是无法得到结果,请与我联系,我会做一个demo。因为这段时间确实病的不轻,本想顺手做一个给你,但是一看电脑脑袋晕。不好意思。
总是发不出去,再试试.
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)[未登录]
2009-02-23 16:34 |
小四
lz你好,我是谢老师同门师兄,最近也用类似的界面解决方案。
有空加我msn聊聊 cugdj@hotmail.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2009-10-27 18:07 |
鑫
你好,我想学习一下html内嵌到vc中使用,能给我发份代码吗?zxx8224@163.com 非常感谢
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2009-10-28 09:02 |
WXX
下载就在最后面2个字,不明白为什么那么多人看不见。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2009-12-30 09:45 |
Eleanor
你好,我最近才开始弄html嵌入mfc对话框,我想问一下我只想得到网页的某些按钮的链接地址,调用我的程序去ping它,返回一个ping通时间给网页。我查了下网上说用IHTMLElement里的put_onclick,可是这些接口我不熟,我发现vc2005里的mshtml.h中定义了好几个IHTMLDocument和IHTMLElement接口方便的话加下我msn:lizzywater@hotmail.com指导一下,谢谢
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2010-04-18 14:08 |
jjqcat
很感兴趣,可否将示例的源码发给我一份,谢谢!
jjqcat@gmail.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2010-08-26 10:19 |
yyk
很好。你的想法不错。take a look!!
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2011-01-28 12:07 |
无未
最近也在考虑这个东西 不过令我很为难的是在vc6.0下 加之对com不是很了解…… 努力 关注……
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2011-07-25 19:14 |
tammy
我的怎么在DEBUG文件夹下打不开应用程序呢.
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2011-07-26 10:19 |
tammy
急....
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2011-07-26 10:19 |
tammy
程序运行起来了.但点击浏览按钮时..报错说当前页的脚本运行错误
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2011-07-26 10:23 |
万连文
@tammy
应该是没有注册com组件。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2012-09-22 15:25 |
芦苇
前辈 我是刚开始学习这方面内容的新手,您有木有这方面的资料、书籍推荐呢,跪求拜谢。联系方式:1071932819@qq.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2013-01-30 18:02 |
云怜秀年
下载不到,打不开@noname
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2013-01-30 18:03 |
云怜秀年
我想要一份源码
O(∩_∩)O谢谢
wywangyun1124@163.com
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2015-03-11 10:53 |
冷风X
820225092@qq.com ,求一源码学习一下。。
回复
更多评论
#
re: 用MFC实现WebGUI--(CDHtmlDialog)
2016-07-18 15:37 |
王同林
前辈好,代码下载之后怎么用啊?我生成的exe打开是空白的页面,菜单新建不知道建的啥,打开一个html页面也没有反应,我的环境是vs2010
回复
更多评论
刷新评论列表
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
VC8中MFC集成ATL组件注册时注意的一个问题
未来界面应该是这样的
纯技术讨论com控件创建过程
界面终于出来一点拉
自己画的好友列表
用WLWUI库描述kugoo界面
上班半个月的总结
用MFC实现WebGUI--(CDHtmlDialog)
闲暇时间做的几个界面
转孙辉老师《十年MFC经历认识的Microsoft技术》
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
简历下载
联系我
<
2012年8月
>
日
一
二
三
四
五
六
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(66)
给我留言
查看公开留言
查看私人留言
随笔分类
.NET(6)
ACDK(6)
ATL(11)
MFC(29)
richedit(9)
WTL(1)
乱七八糟(61)
模板(8)
小作品(40)
随笔档案
2013年3月 (2)
2012年9月 (2)
2012年8月 (2)
2012年7月 (2)
2012年6月 (3)
2012年5月 (2)
2011年9月 (2)
2011年8月 (1)
2011年6月 (2)
2011年5月 (4)
2011年4月 (2)
2011年3月 (2)
2010年12月 (1)
2009年9月 (1)
2009年8月 (2)
2009年7月 (2)
2009年6月 (2)
2009年5月 (1)
2009年4月 (1)
2009年1月 (1)
2008年12月 (5)
2008年11月 (2)
2008年10月 (1)
2008年9月 (7)
2008年8月 (2)
2008年3月 (3)
2008年2月 (2)
2008年1月 (3)
2007年12月 (6)
2007年11月 (1)
2007年10月 (3)
2007年9月 (1)
2007年8月 (5)
2007年7月 (5)
2007年6月 (3)
2007年5月 (5)
2007年4月 (5)
2007年3月 (4)
2007年2月 (2)
2007年1月 (2)
2006年12月 (4)
2006年11月 (8)
2006年10月 (1)
2006年9月 (9)
2006年8月 (7)
2006年7月 (10)
2006年6月 (1)
2006年5月 (2)
2006年4月 (10)
2006年3月 (3)
2006年2月 (3)
2006年1月 (2)
2005年12月 (8)
相册
new
个人相册
搜索
最新评论
1. re: 用MFC实现WebGUI--(CDHtmlDialog)
前辈好,代码下载之后怎么用啊?我生成的exe打开是空白的页面,菜单新建不知道建的啥,打开一个html页面也没有反应,我的环境是vs2010
--王同林
2. re: 使MFC变漂亮一:MFC与Flash交互示例
能不能把Flash源文件共享一下,要不然Flash端变量不知道怎么操作
--ddd
3. re: 甘特图第一版本发布
你这个附件有什么功能限制?
--xrczld
4. re: 并行编程--MPI开发入门
我是用的vs+MPICH2,用wmpiexec运行我的exe的时候,不能连接到主机是什么鬼啊。。求回复
--M琨M
5. re: 基于Chrome开源提取的界面开发框架 三(.3)
豌豆荚非常不错的应用
--mmocake
阅读排行榜
1. 基于Chrome开源提取的界面开发框架开篇(32289)
2. 用MFC实现WebGUI--(CDHtmlDialog)(25808)
3. 并行编程--MPI开发入门(19091)
4. 使MFC变漂亮二:MFC与HTML交互示例(17301)
5. FreeType2研究(16056)
评论排行榜
1. 我把初恋搞丢了(原创)(55)
2. 一个小型绘图程序(45)
3. 并行编程--MPI开发入门(42)
4. 我得C++学习心得(41)
5. 用MFC实现WebGUI--(CDHtmlDialog)(40)