通过IHTMLControlElement在工作者线程里不能取得页面元素的焦点的?

老邓IT 2010-01-23 06:23:16
CComPtr<IHTMLElement > pElem = NULL;
......

CComPtr<IHTMLControlElement> pControl=NULL;
hr = pElem->QueryInterface(&pControl);
if (SUCCEEDED(hr) && pControl!=NULL)
{
hr = pControl->focus();
}

已经获得了IHTMLElement接口,
在主线程里也可以通过IHTMLControlElement取得页面元素的焦点的。

现在我想在工作者线程里获得页面元素的焦点的,
但只要运行到这句就报错
hr = pControl->focus();

工作者系程是不是不能取得元素焦点?

...全文
299 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
老邓IT 2010-01-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 tr0j4n 的回复:]
引用 7 楼 wmcoo 的回复:
引用 6 楼 tr0j4n 的回复:
GameStart作为类的成员函数,再试试看

我试着将它作为类成员函数,出错,
线程方法好像只能定义为全局或静态的

静态和成员函数不矛盾。
[/Quote]
嗯,我把函数声明为静态还是有那个错误
老邓IT 2010-01-24
  • 打赏
  • 举报
回复
不知道可不可以发送消息给主线(组件所在线程)获得焦点,
再由后台线程模拟按键,先试试:)
老邓IT 2010-01-24
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jameshooo 的回复:]
你可以继续使用线程,但是涉及到组件操作的地方应该交给组件所在的线程来完成,如果还未完全了解COM,最简单的解决方法就是使用自定义消息,线程直接发送消息给组件线程,由组件线程完成实际操作,比如:
..........
[/Quote]
哦,我懂你的意思了.
"组件所在线程"
那程序阻塞没办法解决了
非常感谢jameshooo大哥指点!
jukique 2010-01-24
  • 打赏
  • 举报
回复
好东西,高人,学习
老邓IT 2010-01-24
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jameshooo 的回复:]
COM 基础还没打好。
WM_HTML_GETOBJECT 消息不能跨线程发送,当然更不能跨进程。返回的 LRESULT 里面保存的是一个 IUnknown*,不可以把一个接口指针到处乱传,几乎所有组件都是对线程敏感的。
[/Quote]
嗯,不知道有什么方式可以实现我的需求不,
希望jameshooo胡大哥指点下
:)

老邓IT 2010-01-24
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jameshooo 的回复:]
....
[/Quote]
用自定义消息,程序是不报错了,但会阻塞卡死,
难道这个消息还是让主线程去执行的吗
jameshooo 2010-01-24
  • 打赏
  • 举报
回复
COM 基础还没打好。
WM_HTML_GETOBJECT 消息不能跨线程发送,当然更不能跨进程。返回的 LRESULT 里面保存的是一个 IUnknown*,不可以把一个接口指针到处乱传,几乎所有组件都是对线程敏感的。
jameshooo 2010-01-24
  • 打赏
  • 举报
回复
你可以继续使用线程,但是涉及到组件操作的地方应该交给组件所在的线程来完成,如果还未完全了解COM,最简单的解决方法就是使用自定义消息,线程直接发送消息给组件线程,由组件线程完成实际操作,比如:
定义自定义消息:
#define WM_FOCUS WM_USER + 1


消息响应代码:
xxx::OnFocus()
{
// 这里就是你操作的地方,把代码粘贴过来
HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
if ( hInst == NULL )
{
return 0;
}

HWND p_Hwnd=::FindWindow("Liao","无标题 - MyIE");

...

} // else document not ready
::FreeLibrary( hInst );
}


线程函数:
UINT GameStart(LPVOID lpParam)
{
// 当需要设置控件焦点时,发送自定义消息给组件线程中的某个窗口
::SendMessage(hwnd, WM_FOCUS, 0, 0);
return 0;
}
老邓IT 2010-01-24
  • 打赏
  • 举报
回复
问题解决了,很HAPPY
再次谢谢jameshooo大哥
MoXiaoRab 2010-01-24
  • 打赏
  • 举报
回复
学习。
我的COM基础还是很模糊的,看来得进补了
vclongking 2010-01-23
  • 打赏
  • 举报
回复
关注 学习
zoulie 2010-01-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wmcoo 的回复:]
引用 6 楼 tr0j4n 的回复:
GameStart作为类的成员函数,再试试看

我试着将它作为类成员函数,出错,
线程方法好像只能定义为全局或静态的
[/Quote]
在类的函数申明加static,否则会调用约定出错,可以将类的this指针当参数传给线程函数
MoXiaoRab 2010-01-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wmcoo 的回复:]
引用 6 楼 tr0j4n 的回复:
GameStart作为类的成员函数,再试试看

我试着将它作为类成员函数,出错,
线程方法好像只能定义为全局或静态的
[/Quote]
静态和成员函数不矛盾。
老邓IT 2010-01-23
  • 打赏
  • 举报
回复
只要把线程方法GameStart()里的
hr = pControl->focus();
去掉程序运行正常,就是得不到FLASH的焦点
老邓IT 2010-01-23
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tr0j4n 的回复:]
GameStart作为类的成员函数,再试试看
[/Quote]
我试着将它作为类成员函数,出错,
线程方法好像只能定义为全局或静态的
MoXiaoRab 2010-01-23
  • 打赏
  • 举报
回复
GameStart作为类的成员函数,再试试看
MoXiaoRab 2010-01-23
  • 打赏
  • 举报
回复
这不是常见的调用约定问题么。
你这里怎么出现了?
老邓IT 2010-01-23
  • 打赏
  • 举报
回复
主线程里测试是没错的,循环按键程序一直阻塞,
放线程里就出错
后台线程是不是不能取焦点呢?


void CMyIEView::OnGameStart()
{
// TODO: Add your command handler code here
pThread=AfxBeginThread(GameStart,(LPVOID)this);

}
UINT GameStart(LPVOID lpParam)
{
CoInitialize( NULL );

// Explicitly load MSAA so we know if it's installed
HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
if ( hInst == NULL )
{
return 0;
}

HWND p_Hwnd=::FindWindow("Liao","无标题 - MyIE");
HWND hWndChild=NULL;
// Get 1st IE window
::EnumChildWindows( p_Hwnd, EnumChildProc, (LPARAM)&hWndChild );

if ( hWndChild )
{
CComPtr<IHTMLDocument2> pDoc;
LRESULT lRes;

UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );

LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") );
if ( pfObjectFromLresult != NULL )
{
HRESULT hr;
hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)&pDoc );
if ( SUCCEEDED(hr) )
{
CComPtr<IHTMLDocument2 > pIframeDoc = NULL;
HWND iframeHwnd;
getFrameDocumentById(pDoc,L"TEST",&pIframeDoc,&iframeHwnd);

if(SUCCEEDED(hr) && pIframeDoc!=NULL){
CComPtr<IHTMLElementCollection> pAllElems = NULL;
hr =pIframeDoc->get_all(&pAllElems);
if(SUCCEEDED(hr) && pAllElems!=NULL){

long nrEmbeds = 0;
hr = pAllElems->get_length(&nrEmbeds);
if (SUCCEEDED(hr) && nrEmbeds > 0)
{

//hr = pAllElems->item(CComVariant("game") ,CComVariant("0"),&objectDis);
for(long i=0;i<nrEmbeds;i++){
CComPtr<IDispatch> objectDis = NULL;
CComPtr<IHTMLElement > pElem = NULL;
_variant_t index = i;
hr = pAllElems->item(index ,index,&objectDis);
hr = objectDis->QueryInterface(IID_IHTMLElement ,(void**)&pElem);
BSTR Name={0};
hr=pElem->get_id(&Name);
if(SUCCEEDED(hr)&&Name!=NULL){
CString pName;
pName=(CString)Name;
if(strcmp(pName,"game")==0){
::OutputDebugString(pName);
CComPtr<IHTMLControlElement> pControl=NULL;
hr = pElem->QueryInterface(&pControl);
if (SUCCEEDED(hr) && pControl!=NULL)
{
::OutputDebugString("pControl!=NULL");
hr = pControl->focus();
game_status=true;
while(game_status){

::PostMessage( hWndChild ,WM_KEYDOWN ,VK_TAB,0);
::PostMessage( hWndChild ,WM_KEYUP ,VK_TAB,0);

::PostMessage( hWndChild ,WM_KEYDOWN,49,0);
::PostMessage( hWndChild ,WM_KEYUP,49,0);

Sleep(1000);
}
}
break;
}
}
}
}//nrEmbeds > 0
}//pAllElems!=NULL
}//pIframeDoc!=NULL
}//if ( SUCCEEDED(hr) )
}//if ( pfObjectFromLresult != NULL )
} // else document not ready
::FreeLibrary( hInst );
CoUninitialize();

return 0;
}
老邓IT 2010-01-23
  • 打赏
  • 举报
回复

刚学VC错误都不知道查,哎,外挂是学习他的动力,
先谢谢各位帮忙解答了
老邓IT 2010-01-23
  • 打赏
  • 举报
回复
运行到那句就弹出个错误提示框,我是想写个网页游戏的辅助工具,想通过后台来模拟操作,模拟按键都需要获得FLASH的焦点,就是在工作都线程里获得FLASH焦点出错,
等下我截个图给你看看
加载更多回复(1)

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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