刚刚结的那个帖子在这里:
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;
}
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;
}
解决方案 »
- 如何让一个MFC规则的DLL文件返回一个BOOL值?
- 如何利用Winsock 发送和接收文件(Client、Server)
- 视图边框颜色
- 关于动态创建和动态信息,请指教。9.51
- 如何:在点击x退出时,弹出确认对话框,选择取消的话就不退出
- VC的可选参数是怎么用的?
- 请教怎么刷新List Control?
- 数据库应用的设计问题
- 怎样让程序在系统启动时不能被Ctrl+Alt+Delete杀掉?
- 用ShellExecute启动屏幕保护程序后,为什么屏幕保护程序的密码不起作用?
- C/S 怎么提高客户端的访问速度,现在我是直接连接的远程mssqlsever数据库("Provider=SQLOLEDB;Data Source=216.143...........")
- 奇思怪想的界面缩放,如何实现啊?
类型为image的input元素往往不执行提交动作,你还不如寻找类型为submit的input元素。
呵呵,是这样的,我们公司正在搞一个能支持自动登录的插件,并且能帮助用户管理帐号信息。。所以,你看有些网站用的就是一个 image 类型的登录按钮嘛。。当然,不管是什么类型的,我必然是要能保证能收到表单提交的消息。我在上一个帖子里面就已经改了个自己的 invoke 用来接收消息了。所以不管是 submit的input元素,还是 image的input元素 ,我都是要关心的。所以,老大能指点一下,怎么做成后台驻留的不?
额,估计版主还是没有看懂我的意思
我现在确实是可以收到 onsubmit 的消息。。但是呢,我想做的功能是这样的,就是,用我原来的代码呢,因为是用连接点设定一个自定义的接受消息的 invoke,然后紧接着的代码就是模拟点击我感兴趣的页面元素提交表单。这样确实能收到。但是我想做的是,只用代码来设定一个 invoke用来接收事件,然后程序保持不退出。然后当用户用手工点击提交表单的时候,我之前设定的 invoke 能收到。但是现在的情况是,我把后面的提交表单的代码注释掉之后,设定的 invoke 就没反应了,是不是因为设定了 invoke 的 spFormElement 是个临时变量的问题?代码我发一份到版主邮箱([email protected])吧,代码很简单。有代码可能好沟通一些,先谢谢了。
额,如果那样用的话,会报在 ULONG __stdcall Release(void) 的时候,内存错误。奇怪。
把 CComVariant vEvent; 也提到前面去作为全局变量,就可以了但是,依然还是那样,如果我不注释掉 下面的 模拟点击 image 代码,就能进入我的 invoke
如果是用手工去点击,但是保持程序不退出,我的invoke 就收不到消息。是不是还有哪个变量应该要注意保存??
额,我倒是觉得,估计还是哪个变量要保存为全局变量的问题你想啊,我不注释掉下面的模拟点击的代码的话, 我的 invoke 是可以收到消息的。所以我怀疑是循环结束后,虽然我的程序还没有推出,但是一些变量就被销毁了。版主觉得有没有这个可能?
可以写个测试例子,嵌入一个webbrowser在你自已的进程中,然后,看调不调用?
啊,我是说,
我先,在上面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 就收不到消息了。不知道这回说清楚没有?
啊? 你的意思是不是说,程序点击确实可以收到,但是手工点击必然是收不到的?这是一种特性?
不知道我理解错你的说法没有。
那如果是这样,得想办法去 Hook 其他IE进程的函数了?
啊,先谢谢了,我想了下,
应该是这个的问题
::CoInitialize(NULL); //初始化 COM 公寓 EnumIE(); //枚举浏览器 ::CoUninitialize(); //释放 COM 公寓
看,当 EnumIE() 结束的时候 ,跟着就 CoUninitialize() 了,所以,我的程序虽然没有退出,但是 所有的COM对象 已经销毁了,所以不管是 new 出来的还是全局变量,都不起作用。。版主觉得呢?
源代码已发送到你邮箱。