还是那个 put_onsubmit 的我问题,刚刚想起另外一个问题。

vcPlayer 2008-09-12 01:09:59
刚刚结的那个帖子在这里:
http://topic.csdn.net/u/20080911/15/6cec0b2c-9574-4662-b41b-d5f6e685c065.html?seed=1848159299

我发现的一个新问题是
现在的代码是设定一个自定义的接受消息的 invoke,然后紧接着的代码就是模拟点击我感兴趣的页面元素提交表单。但是我不模拟点击,而是用手工点击的话,我的接收器就接收不到消息。

我现在想枚举到所有的页面表单之后,不用代码去立即点击。而是用手工去点击了页面之后,我的接收器也能收到消息,是需要保存哪个变量?还是说应该怎么做?


... ...

hr = spFormElement->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if (hr == S_OK)
{
// Find the connection point.
hr = pCPC->FindConnectionPoint( DIID_HTMLFormElementEvents , &pCP);
if (hr == S_OK)
{
// Advise the connection point.
hr = pCP->Advise((IUnknown*)&pOnWebEvent, &dwCookie);
if ( FAILED( hr ) ) ::AfxMessageBox("bbb");
}
pCPC->Release();
}


//----------------------------------------------------------------------------------
//枚举表单中的元素,找到与input 有关的项,如果发现为 image 类型的按钮,就点击。

CComQIPtr< IHTMLElement > spAllInputElement;
spFormElement->QueryInterface( IID_IHTMLElement , (void**)&spAllInputElement );

CComQIPtr< IDispatch > spCollDisp;
CComQIPtr< IHTMLElementCollection > spCollElement;

spAllInputElement->get_all( (IDispatch**)&spCollDisp );
spCollDisp->QueryInterface( IID_IHTMLElementCollection , (void**)&spCollElement );

long nCollCount = 0;
spCollElement->get_length(&nCollCount);

for( long i = 0 ; i< nCollCount ; i++ )
{
CComQIPtr< IDispatch > MyDisp;
CComQIPtr< IHTMLInputElement > spInputElement;


hr = spCollElement->item( CComVariant(i) , CComVariant() , &MyDisp );
if ( FAILED( hr ) ) continue;

if( !MyDisp )//容错
return;

hr = MyDisp->QueryInterface( IID_IHTMLInputElement , (void**)&spInputElement );
if ( FAILED( hr ) ) continue;

//取得表单域,并且点击按钮
CComBSTR vName,vVal,vType;

hr = spInputElement->get_name( &vName );
if( FAILED( hr ) ) continue;

hr = spInputElement->get_value( &vVal );
if( FAILED( hr ) ) continue;

hr = spInputElement->get_type( &vType );
if( FAILED( hr ) ) continue;


if( !strnicmp(lpType , "image" , 5) )//如果发现 为 image 类型的按钮就点击之
{
CComQIPtr< IHTMLElement > spSingleElement;

hr = spInputElement->QueryInterface( IID_IHTMLElement , (void**)&spSingleElement);
if( FAILED( hr ) ) continue;

hr = spSingleElement->click();
if( FAILED( hr ) ) continue;

}


...全文
351 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
vcPlayer 2008-09-13
  • 打赏
  • 举报
回复
谢谢两位,我看看先。。。
jameshooo 2008-09-12
  • 打赏
  • 举报
回复
设置好所有东西后,请保持一个消息循环的代码来维持运行,COM调用依赖于消息循环,否则你的事件方法肯定不会被调用到。
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
应该是这个问题,另外,你的getchar()函数可能阻止消息发送,我修改你的debug版变成了winmain的工程,并用了你相同的代码,调试通过。
源代码已发送到你邮箱。
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 yjgx007 的回复:]
我也不确信,你先试下我的办法, 看看行不行?我有时间也看下...
[/Quote]

啊,先谢谢了,

我想了下,
应该是这个的问题


::CoInitialize(NULL); //初始化 COM 公寓

EnumIE(); //枚举浏览器

::CoUninitialize(); //释放 COM 公寓


看,当 EnumIE() 结束的时候 ,跟着就 CoUninitialize() 了,所以,我的程序虽然没有退出,但是 所有的COM对象 已经销毁了,所以不管是 new 出来的还是全局变量,都不起作用。。版主觉得呢?
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 vcPlayer 的回复:]
引用 19 楼 yjgx007 的回复:
是这样的, 你程序化的点击是可以收到的,表明事件sink设置是没问题的, 但是手工点击不行, 按照, 我上面说的你嵌入一个webbrowser控件到你的程序进程中, 用同样方法调试下.


啊? 你的意思是不是说,程序点击确实可以收到,但是手工点击必然是收不到的?这是一种特性?
不知道我理解错你的说法没有。


那如果是这样,得想办法去 Hook 其他IE进程的函数了?
[/Quote]
我也不确信,你先试下我的办法, 看看行不行?我有时间也看下...
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 yjgx007 的回复:]
是这样的, 你程序化的点击是可以收到的,表明事件sink设置是没问题的, 但是手工点击不行, 按照, 我上面说的你嵌入一个webbrowser控件到你的程序进程中, 用同样方法调试下.
[/Quote]

啊? 你的意思是不是说,程序点击确实可以收到,但是手工点击必然是收不到的?这是一种特性?
不知道我理解错你的说法没有。


那如果是这样,得想办法去 Hook 其他IE进程的函数了?
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 vcPlayer 的回复:]
引用 17 楼 yjgx007 的回复:

你是说?



啊,我是说,
我先,在上面
C/C++ codehr=spFormElement->put_onsubmit( vEvent );


然后,立即使用下面的代码立即点击,然后我的 invoke 是可以收到消息的。

C/C++ codeif(!strnicmp(lpType ,"image",5) )//如果发现 为 image 类型的按钮就点击之{
CComQIPtr<IHTMLElement>spSingleElement;

hr=spInputElement->QueryInterface( I…
[/Quote]
是这样的, 你程序化的点击是可以收到的,表明事件sink设置是没问题的, 但是手工点击不行, 按照, 我上面说的你嵌入一个webbrowser控件到你的程序进程中, 用同样方法调试下.
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yjgx007 的回复:]

你是说?
[/Quote]



啊,我是说,
我先,在上面

hr = spFormElement->put_onsubmit( vEvent );



然后,立即使用下面的代码立即点击,然后我的 invoke 是可以收到消息的。


if( !strnicmp(lpType , "image" , 5) )//如果发现 为 image 类型的按钮就点击之
{
CComQIPtr< IHTMLElement > spSingleElement;

hr = spInputElement->QueryInterface( IID_IHTMLElement , (void**)&spSingleElement);
if( FAILED( hr ) ) continue;

hr = spSingleElement->click();
if( FAILED( hr ) ) continue;

}



但是我光

hr = spFormElement->put_onsubmit( vEvent );


而把 hr = spSingleElement->click(); 给注释掉的话,然后我转到页面去手工点击,我的 invoke 就收不到消息了。

不知道这回说清楚没有?

yjgx007 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 vcPlayer 的回复:]
引用 15 楼 yjgx007 的回复:
全局变量,new出来都是一样, 我怀疑是跨进程访问的问题,你的IHTMLDocument2不属于当前进程中,你
可以写个测试例子,嵌入一个webbrowser在你自已的进程中,然后,看调不调用?

额,那为啥我不注释掉下面的点击代码,却可以收到消息?

[/Quote]
你是说?
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 yjgx007 的回复:]
全局变量,new出来都是一样, 我怀疑是跨进程访问的问题,你的IHTMLDocument2不属于当前进程中,你
可以写个测试例子,嵌入一个webbrowser在你自已的进程中,然后,看调不调用?
[/Quote]
额,那为啥我不注释掉下面的点击代码,却可以收到消息?
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
全局变量,new出来都是一样, 我怀疑是跨进程访问的问题,你的IHTMLDocument2不属于当前进程中,你
可以写个测试例子,嵌入一个webbrowser在你自已的进程中,然后,看调不调用?
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 yjgx007 的回复:]
有时间我想下,好像不是那么容易 :(
[/Quote]

额,我倒是觉得,估计还是哪个变量要保存为全局变量的问题。。。

你想啊,我不注释掉下面的模拟点击的代码的话, 我的 invoke 是可以收到消息的。

所以我怀疑是循环结束后,虽然我的程序还没有推出,但是一些变量就被销毁了。

版主觉得有没有这个可能?
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
有时间我想下,好像不是那么容易 :(
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yjgx007 的回复:]
稍等,我调试下,可能需要在onsubmit属性变化前对onsubmit事件进行拦截, 也就是jameshooo说的:脚本中使用了onsubmit,并且终止了事件的继续传递。
[/Quote]

有劳了,
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
稍等,我调试下,可能需要在onsubmit属性变化前对onsubmit事件进行拦截, 也就是jameshooo说的:脚本中使用了onsubmit,并且终止了事件的继续传递。
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yjgx007 的回复:]
把delete this去掉... : )
[/Quote]

把 CComVariant vEvent; 也提到前面去作为全局变量,就可以了。。。

但是,依然还是那样,如果我不注释掉 下面的 模拟点击 image 代码,就能进入我的 invoke
如果是用手工去点击,但是保持程序不退出,我的invoke 就收不到消息。

是不是还有哪个变量应该要注意保存??
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
恩,如果用 put_onsubmit 的话,得把 CComVariant vEvent; 也提到前面去作为全局变量才行。
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 vcPlayer 的回复:]
引用 6 楼 yjgx007 的回复:
put_onsubmit是可以实现的, 详见我在上个帖 子的结尾留言.


额,如果那样用的话,会报在 ULONG __stdcall Release(void) 的时候,内存错误。奇怪。
[/Quote]
把delete this去掉... : )
vcPlayer 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yjgx007 的回复:]
put_onsubmit是可以实现的, 详见我在上个帖 子的结尾留言.
[/Quote]

额,如果那样用的话,会报在 ULONG __stdcall Release(void) 的时候,内存错误。奇怪。
yjgx007 2008-09-12
  • 打赏
  • 举报
回复
put_onsubmit是可以实现的, 详见我在上个帖 子的结尾留言.
加载更多回复(5)

3,055

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC HTML/XML
社区管理员
  • HTML/XML社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧