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();工作者系程是不是不能取得元素焦点?

解决方案 »

  1.   

    运行到那句就弹出个错误提示框,我是想写个网页游戏的辅助工具,想通过后台来模拟操作,模拟按键都需要获得FLASH的焦点,就是在工作都线程里获得FLASH焦点出错,
    等下我截个图给你看看
      

  2.   

    主线程里测试是没错的,循环按键程序一直阻塞,
    放线程里就出错
    后台线程是不是不能取焦点呢?
    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;
    }
      

  3.   

     GameStart作为类的成员函数,再试试看
      

  4.   

    只要把线程方法GameStart()里的
    hr = pControl->focus();
    去掉程序运行正常,就是得不到FLASH的焦点
      

  5.   

    在类的函数申明加static,否则会调用约定出错,可以将类的this指针当参数传给线程函数
      

  6.   

    COM 基础还没打好。
    WM_HTML_GETOBJECT 消息不能跨线程发送,当然更不能跨进程。返回的 LRESULT 里面保存的是一个 IUnknown*,不可以把一个接口指针到处乱传,几乎所有组件都是对线程敏感的。
      

  7.   

    嗯,不知道有什么方式可以实现我的需求不,
    希望jameshooo胡大哥指点下
    :)
      

  8.   

    你可以继续使用线程,但是涉及到组件操作的地方应该交给组件所在的线程来完成,如果还未完全了解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;
    }
      

  9.   

    哦,我懂你的意思了.
    "组件所在线程"
    那程序阻塞没办法解决了
    非常感谢jameshooo大哥指点!
      

  10.   

    学习。
    我的COM基础还是很模糊的,看来得进补了
      

  11.   

    问题解决了,很HAPPY
    再次谢谢jameshooo大哥