MsHtml的问题
网页里<table>怎么找出来?
我查了很9的MSDN
也不知道table对应着哪个接口
也不知道用什么方法能获得这个接口
问题点数:300、回复次数:41Top
1 楼111222(www.111222.cn)回复于 2001-11-01 19:24:41 得分 0
前提:我必须用COM的方法!Top
2 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-01 19:26:11 得分 0
IHTMLTableTop
3 楼21bird(世纪笨鸟:csdn的blog啊啥时能不出错?!)回复于 2001-11-01 19:29:40 得分 0
不好意思,我先问你一下!
总算找到你了!:)
听你以前说过,用CHtmlView时,可以在网叶现实之前先得到它的数据,修改后再让它显示.
这具体要怎么做呀?都要调用哪些函数?
我会另开帖子给你分的,最多可给1xx分!Top
4 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-02 15:40:51 得分 0
不行
必须在网页载入成功后才修改网页元素。参见我的文档
在对话框中使用网页输入数据 (jiangsheng原创)
http://www.csdn.net/develop/read_article.asp?id=9408Top
5 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-02 15:52:28 得分 0
自己枚举元素,看看是否支持IHTMLTable接口。Top
6 楼wwtmw(剑重无锋 大巧不工)回复于 2001-11-02 15:53:45 得分 0
Hi,11122,
Hi,蒋晟,
IHTMLTable Collection NoneTop
7 楼zj_ok(zj_ok)回复于 2001-11-02 16:01:19 得分 0
各位都是网页高手,小弟听课Top
8 楼111222(www.111222.cn)回复于 2001-11-03 09:08:16 得分 0
jiangsheng(蒋晟):
没发现什么方法能获得IHTMLTable的Interface啊、、、
我的目的是这样的
<html>
<head>
<title>
一个网页
</title>
</head>
<body>
<table>
<tr>
<td>
我想把table所在部分的HTML源代码弄出来!
</td>
</tr>
</table>
</html>
上面是一个含有table的网页
我想获得
<table>
<tr>
<td>
我想把table所在部分的HTML源代码弄出来!
</td>
</tr>
</table>
这部分代码。必须用COM方法。Top
9 楼111222(www.111222.cn)回复于 2001-11-03 10:56:31 得分 0
21bird:
COM集中营从前有篇文章是修改、显示源代码的、、、不过那种方法修改后网页的属性变成了about:blank
不过,利用IMarkupPointer Interface和IMarkupContainer Interface可以做到直接修改内容而不改变网页属性。(Fast Browser有个检测LINKS就是这么做的)
不过具体的还是得你自己实验。Top
10 楼111222(www.111222.cn)回复于 2001-11-03 12:34:20 得分 0
upupTop
11 楼ray2_ls(轻衫踏雪)回复于 2001-11-03 13:18:46 得分 0
poppopTop
12 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-03 15:40:01 得分 0
看看tagName是不是TABLETop
13 楼21bird(世纪笨鸟:csdn的blog啊啥时能不出错?!)回复于 2001-11-03 17:36:47 得分 0
谢谢你的线索,111222()!
不过我是帮不了你了,高出不胜寒呀!@_@
早看到你的帖子就好了!
我刚把那个贴字结了,分都给了蒋晟兄了!^_^Top
14 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-04 14:01:05 得分 0
对于IHTMLElement QI一下看看是不是支持IHTMLTableTop
15 楼wwtmw(剑重无锋 大巧不工)回复于 2001-11-04 14:22:38 得分 0
joinTop
16 楼111222(www.111222.cn)回复于 2001-11-06 15:54:42 得分 0
抱歉,来晚了
jiangsheng(蒋晟) :
下面是我遍历元素比较tagName的代码,有些问题.
我这样做:
IHTMLDocument2 *pDoc = NULL;
IHTMLElementCollection * pAllElem = NULL;
IHTMLElement *pElem = NULL;
BSTR tag; //for Element's tagName
long p; //for IHTMLElementCollection's item number
VARIANT name;
name.vt = VT_I4;
//获取IHTMLDocument2接口指针略
pDoc->get_all(&pAllElem); //从文档中获取元素集合
if(pAllElem!=NULL)
{
for(int i=0;i<p;i++)//遍历所有元素
{
name.lVal = i;
pAllElem->item(name,name,(LPDISPATCH*)&pElem);//获取元素对象指针
pElem->get_tagName(&tag);//获取tagName
CString ss(tag); //转化成CString
//if(ss.CompareNoCase("table") ==0)//比较是否为table
AfxMessageBox(ss); //在对话框中显示tagName
::SysFreeString(tag);
}
}
//.....
可是,AfxMessageBox(ss); 显示出的tagName是乱码
if(ss.CompareNoCase("table") ==0)这个条件也总是假
Top
17 楼111222(www.111222.cn)回复于 2001-11-06 17:44:54 得分 0
upppTop
18 楼111222(www.111222.cn)回复于 2001-11-06 18:32:02 得分 0
tttttttopTop
19 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-06 19:49:12 得分 0
BOOL CAboutBox::ReplaceHtmlByID(LPCTSTR lpszTagID,LPCTSTR lpszHtml,BOOL bIsInnerHtml)
{
CComDispatchDriver pHTMLDispatch(m_wndBrowser.GetDocument());
if(pHTMLDispatch.p){
HRESULT hr;
CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> pHTMLDocument(pHTMLDispatch);
if(pHTMLDocument.p){
CComPtr<IHTMLElementCollection> pHTMLElementCollection;
hr=pHTMLDocument->get_all(&pHTMLElementCollection);
if(hr==S_OK && pHTMLElementCollection.p!=NULL){
LONG celem;
hr=pHTMLElementCollection->get_length(&celem);
if(hr==S_OK){
for(int i=0;i<celem;i++){
COleVariant varIndex,var2;//var2 is not used because accessing index,not name
varIndex.vt=VT_UINT;
varIndex.lVal=i;
CComDispatchDriver pDisp;
hr=pHTMLElementCollection->item(varIndex,var2,&pDisp);
if(hr==S_OK){
CComQIPtr<IHTMLElement, &IID_IHTMLElement> pHTMLElement(pDisp);
if(pHTMLElement){
//find html element
BSTR bstrTagID;
if(pHTMLElement->get_id(&bstrTagID)==S_OK){
if(bstrTagID!=NULL){
_bstr_t bstrHTML(lpszHtml);
_bstr_t bstrTagIDToCompare(lpszTagID);
_bstr_t _bstrTagID(bstrTagID,FALSE);
if(_bstrTagID==bstrTagIDToCompare){
if(bIsInnerHtml)
pHTMLElement->put_innerHTML(bstrHTML);
else
pHTMLElement->put_outerHTML(bstrHTML);
#ifdef _DEBUG
BSTR bstrTag;
hr=pHTMLElement->get_outerHTML(&bstrTag);
CString strTag=bstrTag;
::afxDump<<strTag;
#endif
}
}
}
}
}
}
}
}
}
}
return TRUE;
}
Top
20 楼111222(www.111222.cn)回复于 2001-11-07 20:04:56 得分 0
蒋晟你有OICQ吗?我的OICQ号码是1819625
我获得元素的IHTMLElement之后直接get_outerHTML(&bstrTag);怎么非法操作?Top
21 楼111222(www.111222.cn)回复于 2001-11-07 20:13:06 得分 0
我糊涂了啊
我还试了----
IHTMLElementCollection * pAllElem = NULL;
IHTMLElementCollection* pTableCol = NULL;
pDoc->get_all(&pAllElem); //元素集合
if(pAllElem!=NULL)
{
COleVariant vtag(_T("table"));
pAllElem->tags(vtag,(LPDISPATCH*)pTableCol);
结果pTableCol总是NULL
按照MSDN说的,应该是table的集合、、、
我该怎么办啊
Top
22 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-08 15:31:45 得分 300
1看看是不是大小写的问题,我用全大写没有问题的
2试试IHTMLDocument3::getElementsByTagName
Dim Tables As IHTMLElementCollection
Set Tables = doc.All.tags("TABLE")
'Get the 14th table 2nd item (zero based)
Dim Quote As IHTMLElement
Set Quote = _
Tables.Item(14, 14).All.tags("TD").Item(2, 2)
'Display the text between the start and end tags
MsgBox Quote.innerText
Top
23 楼111222(www.111222.cn)回复于 2001-11-09 18:58:25 得分 0
搞定了Top
24 楼111222(www.111222.cn)回复于 2001-11-10 13:58:33 得分 0
COleVariant varIndex,var2;//var2 is not used because accessing index,not name
varIndex.vt=VT_UINT;//为什么要是UINT?
varIndex.lVal=i;
/////////////////////////
我的代码
IHTMLDocument3 *pDoc = NULL;
IHTMLElement *pElem = NULL;
IHTMLElementCollection* pTableCol = NULL; //tagName =>"table"
long p;
BSTR bstrSrc;
VARIANT name;
name.vt = VT_I4;
CString cs("table");
BSTR tagName = cs.AllocSysString();
pDoc->getElementsByTagName(tagName,&pTableCol);//pDoc是IHTMLDocument3
if(pTableCol!=NULL)
{
pTableCol->get_length(&p);
for(int i=0;i<p;i++)
{ name.lVal = i; pTableCol->item(name,name,(LPDISPATCH*)&pElem);//
if(pElem!=NULL)
{
pElem->get_outerHTML(&bstrSrc);//这句或着下面的那句,总是非法操作,pElem不是空的,可是、、也不是正常的
//pElem->get_innerHTML(&bstrSrc);
CString ss(bstrSrc);
::SysFreeString(bstrSrc);
AfxMessageBox(ss);
}
}
}Top
25 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-10 16:03:10 得分 0
给TABLE一个ID,用我的代码看看能不能get_outerHTMLTop
26 楼111222(www.111222.cn)回复于 2001-11-10 16:21:51 得分 0
void CHtmlParsingDlg::GetTables(CString cs)
{
//convert CString to widechar
int nFromLen=cs.GetLength()+1;
OLECHAR *szHTML;
szHTML= new OLECHAR[ nFromLen];
MultiByteToWideChar( CP_ACP, 0, cs, -1, szHTML, nFromLen);
IHTMLDocument2 *pDoc1 = NULL;
CoCreateInstance(CLSID_HTMLDocument,
NULL,
CLSCTX_INPROC_SERVER,
IID_IHTMLDocument2,
(LPVOID *) &pDoc1);
if (pDoc1)
{
IPersistStreamInit *pPersist = NULL;
pDoc1->QueryInterface(IID_IPersistStreamInit,
(LPVOID *) &pPersist);
if (pPersist)
{
IMarkupServices *pMS = NULL;
pPersist->InitNew();
pPersist->Release();
pDoc1->QueryInterface(IID_IMarkupServices,
(LPVOID *) &pMS);
if (pMS)
{
IMarkupContainer *pMC = NULL;
IMarkupPointer *pMkStart = NULL;
IMarkupPointer *pMkFinish = NULL;
pMS->CreateMarkupPointer(&pMkStart);
pMS->CreateMarkupPointer(&pMkFinish);
pMS->ParseString(szHTML,
0,
&pMC,
pMkStart,
pMkFinish);
if (pMC)
{
IHTMLDocument3 *pDoc = NULL;
IHTMLElementCollection * pAllElem = NULL;
IHTMLElement *pElem = NULL;
IHTMLTable* pTable = NULL;
IHTMLElementCollection* pCells = NULL; //link's text
IHTMLElementCollection* pTableCol = NULL; //tag =>"table"
long p;
BSTR bstrSrc,tag;
// BSTR tag = "TABLE";
VARIANT name,index;
name.vt = VT_I4;
index.vt = VT_I4;
//name.bstrVal = "TABLE";
COleVariant tags(_T("a"));
//get IHTMLDocument2's pointer
pMC->QueryInterface(IID_IHTMLDocument3,
(LPVOID *) &pDoc);
if(pDoc!=NULL)
{
CString cs("table");
BSTR tagName = cs.AllocSysString();
pDoc->getElementsByTagName(tagName,&pTableCol);
//get document2's all elementcollection
// pDoc->QueryInterface(IID_IHTMLTable,(LPVOID *) &pTable);
if(pTableCol!=NULL)
{
pTableCol->get_length(&p);
for(int i=0;i<p;i++)//±éÀúËùÓÐÔªËØ
{
// AfxMessageBox("table");
index.lVal = i;
name.lVal = i;
pTableCol->item(name,index,(LPDISPATCH*)&pElem);//»ñÈ¡ÔªËØ¶ÔÏóÖ¸Õë
if(pElem!=NULL)
{
// long l;
// pElem->QueryInterface(IID_IHTMLTable,(LPVOID*)&pTable);
// pTable->get_cols(&l
pElem->get_outerHTML(&bstrSrc);
// pElem->get_innerHTML(&bstrSrc);
CString ss(bstrSrc);
::SysFreeString(bstrSrc);
AfxMessageBox(ss);
}
}
}
上面是原代码,Release接口部分我略了。
我没用IE控件,直接分析的字符串,那部分没什么问题。Top
27 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-11 03:25:48 得分 0
倒~
pElem->QueryInterface(IID_IHTMLTable,(LPVOID*)&pTable);
pElem->get_outerHTML(&bstrSrc);//??
改成
pTable->get_outerHTML
Top
28 楼111222(www.111222.cn)回复于 2001-11-11 10:05:19 得分 0
蒋晟啊~
你没看清楚啊,那段我已经注释掉了。
IHTMLTable没有get_outerHTML属性的。
get_outerHTML只有IHTMLElement接口才能用。Top
29 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-11 18:12:41 得分 0
o
pElem->QueryInterface(IID_IHTMLElement3,(LPVOID*)&pTable);
pTable->get_outerHTML
Top
30 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-12 03:52:03 得分 0
#include <afxpriv.h>
#include <mshtml.h>
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>
#include <COMDEF.h>
改过后的CHtmlParsingDlg::GetTables
void CHtmlParsingDlg::GetTables(CString cs)
{
//convert CString to widechar
int nFromLen=cs.GetLength()+1;
OLECHAR *szHTML;
szHTML= new OLECHAR[ nFromLen];
MultiByteToWideChar( CP_ACP, 0, cs, -1, szHTML, nFromLen);
try{
CComPtr<IHTMLDocument2> pDoc2; // document to create IMarkupServices
COM_CHECK(CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER,IID_IHTMLDocument2,(void**)&pDoc2));
CComQIPtr<IPersistStreamInit,&IID_IPersistStreamInit> pPersist(pDoc2);
if(pPersist){
COM_CHECK(pPersist->InitNew());
CComQIPtr<IMarkupServices,&IID_IMarkupServices> pMS(pDoc2);
if(pMS){
CComPtr<IMarkupContainer> pMC ;
CComPtr<IMarkupPointer> pMkStart ;
CComPtr<IMarkupPointer> pMkFinish ;
CComPtr<IHTMLDocument2> pDoc2;
COM_CHECK(pMS->CreateMarkupPointer(&pMkStart));
COM_CHECK(pMS->CreateMarkupPointer(&pMkFinish));
COM_CHECK(pMS->ParseString(szHTML, 0, &pMC, pMkStart, pMkFinish));
CComQIPtr<IHTMLDocument3,&IID_IHTMLDocument3> pDoc3(pMC);
if(pDoc3){
CComBSTR tagName("TABLE");
if(pDoc3){
CComPtr<IHTMLElementCollection> pTableCol;
long p;
CComBSTR bstrOuterHTML;
CComVariant varIndex,varDummy;
COM_CHECK(pDoc3->getElementsByTagName(tagName,&pTableCol));
COM_CHECK(pTableCol->get_length(&p));
IDispatch * pDummy;
for(int i=0;i<p;i++){//遍历所有元素
varIndex= i;
COM_CHECK(pTableCol->item(varIndex,varDummy,&pDummy));//获取元素对象指针
CComQIPtr<IHTMLElement,&IID_IHTMLElement> pTableElement(pDummy);
if(pTableElement){
//do something with this element
COM_CHECK(pTableElement->get_outerHTML(&bstrOuterHTML));
TRACE(CString(bstrOuterHTML)+"\n");
}
}
}
}
}
}
}
catch(HRESULT hr){
TRACE(_T("COM ERROR:%d"),hr);
}
delete szHTML;
}
Top
31 楼wwtmw(剑重无锋 大巧不工)回复于 2001-11-12 14:45:16 得分 0
轻轻敲醒沉睡的心灵 慢慢张开你的眼睛
看看忙碌的世界是否依然 孤独的转个不停
春风不解风情 吹动少年的心
让昨日脸上的泪痕 随记忆风干了
抬头寻找天空的翅膀 候鸟出现它的影迹
带来远处的饥荒无情的战火 依然存在的消息
玉山白雪飘零 燃烧少年的心
使真情溶化成音符 倾诉遥远的祝福 Top
32 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-12 16:36:11 得分 0
#define COM_CHECK(hr) {if(FAILED(hr))throw hr;}Top
33 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-14 16:50:31 得分 0
BUG:内存泄漏,由于bstrOuterHTML的重复使用造成。
把CComBSTR bstrOuterHTML;这行搬到
if(pTableElement){
之后去。Top
34 楼111222(www.111222.cn)回复于 2001-11-15 18:40:45 得分 0
我那种方法也是可以的,我那问题出在:
for(int i=0;i<p;i++){//遍历所有元素
varIndex= i;
COM_CHECK(pTableCol->item(varIndex,varDummy,&pDummy));//获取元素对象指针
你这里把varIndex放到第一个参数处了。
我按照MSDN的叙述,使其是第2个参数。
按理说应该我的对劲啊(我按照MSDN做的呀)
可结果是:我那样不行Top
35 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-15 20:29:56 得分 0
HRESULT item(
VARIANT name,
VARIANT index,
IDispatch **pdisp
);
Parameters
name
[in] VARIANT of type VT_I4 or VT_BSTR that specifies the object or collection to retrieve. If this parameter is an integer, it is the zero-based index of the object. If this parameter is a string, all objects with matching name or id properties are retrieved, and a collection is returned if more than one match is made.
index
[in] VARIANT of type VT_I4 that specifies the zero-based index of the object to retrieve when a collection is returned.
pdisp
[out, retval] Address of a pointer that receives an IDispatch interface for the object or collection if successful, or NULL otherwise.
如果通过索引来访问,则第二个参数被忽略
如果通过名字来访问,则第二个参数为同名元素集中的序号。
Top
36 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-11-16 00:56:07 得分 0
可以去看看http://www.csdn.net/expert/topic/360/360785.shtm里面怎么分析表格Top
37 楼ChinaOk(农村表哥)回复于 2002-02-24 21:54:02 得分 0
TTTop
38 楼MSVCer(家宝)回复于 2002-02-27 00:27:57 得分 0
学习Top
39 楼jiangsheng(蒋晟.Net[MVP])回复于 2002-02-27 10:33:56 得分 0
到现在还没会??晕~Top
40 楼borz(中五百万或是更多)回复于 2002-06-15 20:01:55 得分 0
此等狗屁话题可以休矣,地球人都知道这并不单单是程序员的问题,有哪个程序员不希望自己的东东配有详细的设计资料,只是项目时间不允许,系统分析员的无能所导致程序员承担了太多的指责!
Top
41 楼borz(中五百万或是更多)回复于 2002-06-15 20:02:20 得分 0
对不起,发错了Top
42 楼ForeverListen(寻求)回复于 2002-08-22 12:39:04 得分 0
upTop
43 楼ForeverListen(寻求)回复于 2002-08-22 12:40:37 得分 0
upTop



