躲宿舍研究了整整一天。总于搞定了。
想研究网页控制的朋友可以参考。
首先,基础知识,不用深究,大局把握了解以下即可。
分别是XML, HTML, DHTML(这三种语法差不多), JavaScript(语法跟C差不多)
更深入点需要掌握DOM模型,以及通过DOM的相关API访问网页元素的原理。
然后就是关键地方了, 研究了一上午自认为搞定了, 后来发现DOM中的document对象是只有在
网页JavaScript中才能被直接调用的。太坑爹了。
然后学习重点转向外部程序如何获取document对象。百度了无数文档。
另外一个关键点,大部分文档资料提到的document对象的属性在VC中是不适用的。
我一直渡认为是我装的VC有问题,纠结了很久。
在.net中或在VB等环境下, 通过WebBrowser控件提供的类, 定义好一个对象后,可直接调用
该对象.document 然后就完事了。
而在C++的CWebBrowser类下,并没有document这个成员。而只有一个GetDocument成员函数。
而GetDocument返回的并不是我们可以直接用的接口指针。而是一个DISPATCH接口。
参考了网上的代码,以及我个人的理解,
转换代码如下: LPDISPATCH docbrowser = m_webCtrl.GetDocument();
//在COM中有一个IDISPATCH接口,LPDISPATCH是一个指向这个接口的指针
IPersistStreamInit *pPSI=NULL;
//其实就是IUnknown类型的宏定义结果
docbrowser->QueryInterface(&pPSI);
//所有的COM接口都继承了IUnknown,
//每个接口的vtbl中的前三个函数都是QueryInterface、AddRef、Release。
//这样所有COM接口都可以被当成IUnknown接口来处理。
//函数功能:IUnknown的一个成员函数,
//客户可以通过此函数来查询某个组件是否支持某个特定的接口。
//若支持QueryInterface将返回一个指向这些接口的指针,
//不支持返回值将是一个失败结果。
HGLOBAL hHTMLText = GlobalAlloc(GMEM_FIXED, 1024*10);
//该函数从堆中分配一定数目的字节数,HGLOBAL表示由GlobalAlloc函数分配的内存句柄
IStream *pStream = NULL;
//定义一个空的流对象指针
memset(hHTMLText,'\0',1024*10);
//初始化
CreateStreamOnHGlobal(hHTMLText, TRUE, &pStream);
//从指定内存创建流对象
pPSI->Save(pStream, FALSE);
//保存一个对象到指定的流
//至此GetDocument返回的接口指针,转来转去到了pPSI上,头都晕了
//html代码保存在hHTMLText中,用char*指向之即可用了
::MessageBox(NULL, (char*)(hHTMLText), "", 0);
至此,我们就获得到指定页面的的代码的指针了。
接下来的事就简单,根据DOM模型,向下索引到我们要读取的元素即可。
GetElementByID 是最直接的索引方式。
余下的事过两天再研究了,明后天要开会。 |