在对话框上放置一个WebBrowser控件,取得所加载页面的某一个select表单元素的指针IHTMLSelectElement,
然后此接口指针列集后传递给一个工作线程,在此线程中用散列得到接口spSelectElement。
用spSelectElement成功得到此select域里面的所有option元素;
然后用put_selectedIndex()设定选中项。
hr = spSelectElem->put_selectedIndex(i);
执行完毕后hr==SD_OK。
然后试图用IHTMLElement3的fireEvent()来激发onchange事件。
VARIANT_BOOL vRect;
BSTR Eventonchange = SysAllocString(L"onchange");
CComQIPtr< IHTMLElement3 > spElem3;
hr=spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);
ASSERT(SUCCEEDED(hr));
hr=spElem3->fireEvent(Eventonchange,0,&vRect);
ASSERT(SUCCEEDED(hr));
spElem3.Release();
但执行到
hr=spElem3->fireEvent(Eventonchange,0,&vRect);
ASSERT(SUCCEEDED(hr)); 这一步时,编译器指出:
hr 0x800706f4 向占位程序传送了空的索引指针。 HRESULT
然后就报错。大家注意上面是通过spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);得到IHTMLElement3接口的;
后来我把IHTMLElement3接口也在主线程列集,传递到工作线程再散列,爆出的问题跟之前一模一样。高人指点下是怎么回事?
然后此接口指针列集后传递给一个工作线程,在此线程中用散列得到接口spSelectElement。
用spSelectElement成功得到此select域里面的所有option元素;
然后用put_selectedIndex()设定选中项。
hr = spSelectElem->put_selectedIndex(i);
执行完毕后hr==SD_OK。
然后试图用IHTMLElement3的fireEvent()来激发onchange事件。
VARIANT_BOOL vRect;
BSTR Eventonchange = SysAllocString(L"onchange");
CComQIPtr< IHTMLElement3 > spElem3;
hr=spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);
ASSERT(SUCCEEDED(hr));
hr=spElem3->fireEvent(Eventonchange,0,&vRect);
ASSERT(SUCCEEDED(hr));
spElem3.Release();
但执行到
hr=spElem3->fireEvent(Eventonchange,0,&vRect);
ASSERT(SUCCEEDED(hr)); 这一步时,编译器指出:
hr 0x800706f4 向占位程序传送了空的索引指针。 HRESULT
然后就报错。大家注意上面是通过spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);得到IHTMLElement3接口的;
后来我把IHTMLElement3接口也在主线程列集,传递到工作线程再散列,爆出的问题跟之前一模一样。高人指点下是怎么回事?
将主线程对话框上的(WebBrowser控件页面元素的DOM接口指针IHTMLSelectElement)传递给新线程,为什么操作不成功?之前发贴有人说:每个使用COM的线程都要调用CoInitialize和Counitialize。
我在线程函数的里面加上这两个函数后,问题依然如果。
而且我之前没有用线程时,没有用此连个函数初始化,也很正常。不知何故,是否因为程序中有使用ADO,所以我在app中曾经调用过:
BOOL CWorkshopApp::InitInstance()
{
//TODO: call AfxInitRichEdit2() to initialize richedit2 library.
if(!AfxOleInit())
{
AfxMessageBox(_T("OLE初始化出错!"));
return FALSE;
} 出问题的这部分代码是:
HRESULT hr;
m_listTT[k].ResetContent();
CComQIPtr< IHTMLSelectElement > spSelectElem;
if(ArrSpSelectElem.GetAt(k, spSelectElem))
{
nCount--;
long length = 0;
spSelectElem->get_length(&length); CStringArray strArrText;
if(GetOptionsTextValue(spSelectElem, strArrText, 0))
{
for(int i=0; i<strArrText.GetCount(); i++)
{
m_listTT[k].AddString(strArrText[i]);
}
}
else
{ return false; }
for(int i=0; i<length; i++)
{
//AddToDB(i);
hr = spSelectElem->put_selectedIndex(i);
if(FAILED(hr)) AfxMessageBox(_T("Fail to put_selectedIndex"));
//********************************点燃"onchange"事件********************************/
VARIANT_BOOL vRect;
BSTR Eventonchange = SysAllocString(L"onchange");
CComQIPtr< IHTMLElement3 > spElem3;
hr=spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);
ASSERT(SUCCEEDED(hr));
hr=spElem3->fireEvent(Eventonchange,0,&vRect);
ASSERT(SUCCEEDED(hr));//此处报错,前一步编译器显示:
//hr 0x800706f4 向占位程序传送了空的索引指针。 HRESULT
spElem3.Release();
//****************************************************************/
m_listTT[k].SetCurSel(i);
------------------------
ps:LZ上一个帖子还没结呢
我严重确认列集散列都做成功了,因为我在调试中仔细观察每一步执行的情况,列集散列以及传递都没有问题。
而且很蹊跷的是,传过来的IHTMLSelectElement指针可以得到这个表单域的option选项,spSelectElem->get_length也很准确。
但是spSelectElem->put_selectedIndex执行后返回的hr显示SD_OK.
pElem3->fireEvent执行后显示:/hr 0x800706f4 向占位程序传送了空的索引指针。 HRESULT
然后就报错。
VARIANT_BOOL vRect;
BSTR Eventonchange = SysAllocString(L"onchange");
CComQIPtr< IHTMLElement3 > spElem3;
hr=spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);
ASSERT(SUCCEEDED(hr));
hr=spElem3->fireEvent(Eventonchange,0,&vRect);
ASSERT(SUCCEEDED(hr));//此处报错,前一步编译器显示:
//hr 0x800706f4 向占位程序传送了空的索引指针。 HRESULT
spElem3.Release();
//****************************************************************/
你看我代码都贴出来了。spElem3->fireEvent(Eventonchange,0,&vRect);有三个参数,看哪一个都不像会出错的啊?
还有,为什么0x800706f4表明是参数的问题?
BSTR bstrEventName,
VARIANT *pvarEventObject,
VARIANT_BOOL *pfCancelled
);
Parameters bstrEventName
[in] BSTR that specifies the name of the event to fire.
pvarEventObject
[in] Pointer to a VARIANT that specifies the IHTMLEventObj interface from which the event properties are obtained.
pfCancelled
[out, retval] VARIANT_BOOL that receives one of the following values: VARIANT_TRUE
Event fired successfully.
VARIANT_FALSE
Event was cancelled.我觉得应该是第二个参数不能设置为空,具体怎么设偶也没弄过,不太了解。
这么多接口需要列集,是不是觉得列集太麻烦?其实不麻烦,只需要列集一个根接口即可,比如IWebBrowser2或者IHTMLDocument2即可,剩下的事情就从这个接口开始导航吧,后续接口不再需要列集。
CComQIPtr< IHTMLEventObj > spEo;
hr = spDoc4->createEventObject(NULL, &spEo);CComQIPtr<IDispatch> spDisp(spEo);
CComVariant var(spDisp);
VARIANT_BOOL bCancel = VARIANT_FALSE;CComQIPtr< IHTMLElement3 > spElem3;
hr=spSelectElem->QueryInterface(IID_IHTMLElement3,(void**)&spElem3);
ASSERT(SUCCEEDED(hr));hr = spElem3->fireEvent(L"onchange", &var, &bCancel);
ASSERT(SUCCEEDED(hr));上面是我从网上找到的代码,来createEventObject。但执行报错createEventObject参数貌似不应该为空。我真是搞不懂这个createEventObject到底是怎么用的。以前没用它,fireEvent也很成功啊?
hr = spSelectElem->QueryInterface(IID_IHTMLDocument4,(void**)&spDoc4);
编译器指出: hr E_NOINTERFACE HRESULT
看来这样不行,有木别的方法可以达到这个目的?