郁闷呀!这两段程序有什么不一样的?送分

xiujiang 2003-03-17 10:16:05
最近太郁闷了,在csdn中c++builder版中问了半天问题都没人理,现在只好把代码拿出来再次恳请各位帮忙指导一下。情况是这样的,我在form上放了一个tcppwebbrowser控件,然后想取到所载入页面的内容,比如取得一个文本框中的内容。下面两个函数,第一个可以取到改文本框的属性和名字,可是取值时却返回为空,第二个则可以取到内容。小弟看了半天也没看出这两个有什么本质不同,不知前个函数到底哪出问题了,恳请各位试好后将代码告诉我。具体如下:

void __fastcall TForm1::Button4Click(TObject *Sender)
{
IDispatch *WebDocument = static_cast<IDispatch *>(CppWebBrowser1->Document);
IHTMLDocument2 *HTMLDocument = static_cast<IHTMLDocument2 *>(WebDocument);

IHTMLElementCollection *pAll;
HTMLDocument->get_all(&pAll);
long AllLen;
pAll->get_length(&AllLen);
VARIANT vIndex,vName;
IHTMLElement *pElement;
IHTMLInputTextElement *pInput;
IDispatch *IDisp;
for(long i= 0;i<AllLen;++i)
{
vName.vt=VT_I4;
vIndex.vt=VT_I4;
vName.lVal=i;
vIndex.llVal=i;

pAll->item(vName,vIndex,&IDisp);
IDisp->QueryInterface(IID_IHTMLElement,(void **)&pElement);
BSTR ItemTag;
pElement->get_tagName(&ItemTag);
AnsiString TagName = ItemTag;
if(TagName.UpperCase() == (AnsiString)"INPUT")
{

pElement->QueryInterface(IID_IHTMLInputTextElement,(void**)&pInput);
BSTR pwd;
AnsiString tmp;
pInput->get_type(&pwd);//这里都有值返回
tmp = pwd;
pInput->get_name(&pwd);//这里也有返回
tmp = pwd;

pInput->get_value(&pwd);//这里为空了
tmp = pwd;
break;
}

}

}
void __fastcall TForm1::Button3Click(TObject *Sender)
{
IHTMLDocument2 *pDoc = NULL;
IHTMLElementCollection* Col;
IDispatch *ppvdisp;
IHTMLInputTextElement *pPwdElement;
IHTMLFormElement *pFormElement;
HRESULT hr;
long len;

(void *)pDoc = CppWebBrowser1->Document;
hr = pDoc->get_forms(&Col);
if(hr == S_OK)
{
VARIANT index;
index.vt = 0x0003;
index.wReserved1 = 0xcccc;
index.wReserved2 = 0xcccc;
index.wReserved3 = 0xcccc;
index.lVal = 0x00000000;
Col->item(index,index,&ppvdisp);
hr = ppvdisp->QueryInterface(IID_IHTMLFormElement,(void**)&pFormElement);
if(hr == S_OK)
{
IDispatch* dispatch;
pFormElement->item(index,index,&dispatch);
hr = dispatch->QueryInterface(
IID_IHTMLInputTextElement,
(void**)&pPwdElement);
if(hr == S_OK)
{
BSTR pwd;

hr=pPwdElement->get_value(&pwd);
if(SUCCEEDED(hr))
{
AnsiString tmp = pwd;
//Edit2->Text = pwd;
}
}
}

}
pDoc->Release();

}
所在入页面内容如下:
<HTML>
<HEAD>
<TITLE>IE TEST</TITLE>
</HEAD>
<BODY>
<FORM NAME="contest" >
<INPUT TYPE="TEXT" NAME="first" VALUE="skdjfk">
<INPUT TYPE="TEXT" NAME="initial">
<INPUT TYPE="TEXT" NAME="email">
</FORM>
</BODY>
</HTML>
...全文
33 点赞 收藏 16
写回复
16 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
LanceX 2003-03-18
看来确实是函数的问题了,你有没有函数的具体说明?
是不是因为什么原因,不能用第二种方法?
回复
waq 2003-03-18
两点疑问,说不定能帮上忙
1.
IHTMLElementCollection *pAll;
HTMLDocument->get_all(&pAll);

这里的&pAll得到的是 pAll指针的内存地址,get_all真的接收这种参数而不是直接的pAll吗?

2.
AnsiString tmp;
pInput->get_type(&pwd);//这里都有值返回
tmp = pwd;
pInput->get_name(&pwd);//这里也有返回
tmp = pwd;

pInput->get_value(&pwd);//这里为空了
tmp = pwd;

这是什么意思啊?tmp=pwd连续三次!前面两次还有什么用啊?
回复
xiujiang 2003-03-18
to waq(我要它干什么?) :
1.msdn中是这样要求传入参数的
2.tmp只是一个临时变量而已,主要就是想看一下get_type,get_name,get_value方法得到的值,并无其他意思。

to LanceX(小军) :
get_type(&pwd); //这里pwd的值付给tmp后,可以看到tmp的内容为"TEXT"
get_name(&pwd); //这里pwd的值付给tmp后,可以看到tmp的内容为"first"
回复
LanceX 2003-03-18
pInput->get_type(&pwd);//这里都有值返回
能将值打出来让我看看吗?
因为我不知道下面几个接口在哪里找到,没法调试,只好你调试再告诉我结果了。
回复
xiujiang 2003-03-18
漂亮漂亮,豁然开朗!多谢多谢!我回去再试试
回复
LanceX 2003-03-18
ThinkX(思考中) 高手就是高手,敬佩中。。。
惭愧中。。。学习。。。
回复
ThinkX 2003-03-18
你的两段代码问题多多呀,

1.明显没有Release接口,Release和成功返回的QueryInterface是一一对应的。
2.IHTMLDocument2 *HTMLDocument = static_cast<IHTMLDocument2 *>(WebDocument);这行代码没有遵守COM规范,永远不要对COM指针进行向下转换,而是使用QueryInterface,尽管目前可以正确的执行,但是这种代码与COM内部实现是有直接联系的,如果COM对象内部实现有所改变,很可能就会引起非法操作了。
3.BSTR使用结束后,应该用SysFreeString释放的。COM规定对于out的参数,释放应该由客户进行。
4.同样道理对VARIANT也是这样,要用VariantClear释放。可能对于I4这种简单类型不会有什么不同,而对 IDispatch和BSTR类型的VARIANT会出现问题的。
5.IHTMLElementCollection中的item可以通过名字直接得到某个页面元素的指针,如果你想实现遍历的话,要用get__newEnum方法得到枚举器再遍历,再COM中,所有的枚举器其实都很像。

我写了一些简单的代码,可以得到first的value值

HRESULT hr;

IHTMLDocument2* pDoc;
hr = CppWebBrowser1->Document->QueryInterface(&pDoc);
if (SUCCEEDED(hr))
{
IHTMLElementCollection* pAll;
hr = pDoc->get_all(&pAll);
if (SUCCEEDED(hr))
{
TVariant name = "first";
TVariant id = 0;
IDispatch* tmpDisp;
hr = pAll->item(name, id, &tmpDisp);
if (SUCCEEDED(hr))
{
IHTMLInputElement* pInput;
hr = tmpDisp->QueryInterface(&pInput);
if (SUCCEEDED(hr))
{
WideString value;
hr = pInput->get_value(&value);
if (SUCCEEDED(hr))
ShowMessage(value);

pInput->Release();
}

tmpDisp->Release();
}

pAll->Release();
}

pDoc->Release();
}

回复
LanceX 2003-03-18
那你该加一个返回值看看,如果是错误的话,还要查一下error value对应的情况了。
回复
xiujiang 2003-03-18
也没有什么原因,只是当时看到一个例子是这么写的,就抄过来用了,结果发现不行,后来同事用第二个方法就可以了,觉得挺奇怪的,想知道为什么?那错了?IHTMLInputTextElement::get_value

HRESULT get_value(
BSTR *p
);

Retrieves the default or "selected" value of the given control.

Returns S_OK if successful, or an error value otherwise.
msdn中查的
回复
jbz 2003-03-17
看看先
回复
eastnofail 2003-03-17
友情关注
回复
Jim3 2003-03-17
mark
回复
xiujiang 2003-03-17
to LanceX(小军) : 我得到的pInput->get_type(&pwd);//这里都有值返回
tmp = pwd;
pInput->get_name(&pwd);//这里也有返回
tmp = pwd;
返回值都是正确的,就是取值就不行了。
回复
LanceX 2003-03-17
pElement->QueryInterface(IID_IHTMLInputTextElement,(void**)&pInput);
得到的会不会并不是你要的结点?你试试把<INPUT>结点都赋上值,再试试。
而第二种方法则是确切的得到你想要的结点。
回复
LanceX 2003-03-17
好象是没有什么本质不同,都是求得当前结点并把值取出来。不过我不知道下面几个接口在哪里找到,有没有说明文档?
IHTMLFormElement *pFormElement;
IHTMLElement *pElement;
IHTMLInputTextElement *pInput;
回复
SharpKing515 2003-03-17
接分!
回复
相关推荐
发帖
C++ Builder
创建于2007-08-02

1.3w+

社区成员

C++ Builder相关内容讨论区
申请成为版主
帖子事件
创建了帖子
2003-03-17 10:16
社区公告
暂无公告