最近在SDK下使用WebBrowser遇到了个问题,就是VK_TAB加速健,经后来分析,其实Ctrl+C等操作也是不行的,只不过已经事先在框架中执行了ExecWeb操作。
一开始,我还以为是MFC的CHtmlView对WebBrowser的包装过程中也象我处理Ctrl+C处理好了。因此,从早上到今晚的12点,我都试图使用这种方法来解决。就是在DocumetComplete后得到所有的Input link和textarea以及frame,然后实现SetFocusToNext和SetFocusToPrev.等函数。
//////////////////////////
BOOL CHtmlView::SetFocusToNext(LPDISPATCH pHtmlDocument)
{
BOOL bFocus=FALSE;
BOOL bFassCurFocus=FALSE;
IHTMLDocument2 *pDoc=NULL;
pHtmlDocument->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
if(pDoc)
{
IHTMLElementCollection* pColl = NULL;
//得到所有元素
if(SUCCEEDED(pDoc->get_all(&pColl)))
{
long nNumElements;
if(SUCCEEDED(pColl->get_length(&nNumElements)))
{
if(nNumElements)
{
IHTMLElement* pActiveElement=NULL;
if(SUCCEEDED(pDoc->get_activeElement(&pActiveElement)))
{
IHTMLFrameBase2* pFrame=NULL;
if(SUCCEEDED(pActiveElement->QueryInterface(IID_IHTMLFrameBase2,(void**)&pFrame)))
{
if(pFrame)
{
IHTMLWindow2 *pWin;
if(SUCCEEDED(pFrame->get_contentWindow(&pWin)))
{
if(pWin)
{
IHTMLDocument2 *pDoc2=NULL;
if(SUCCEEDED(pWin->get_document(&pDoc2)))
{
if(pDoc2)
{
SetFocusToFirst(pDoc2);
pDoc2->Release();
}
}
pWin->Release();
}
}
pFrame->Release();
}
}
//这里已获得activeElement http://www.wzszf.com/
long lActSrcIndex;
pActiveElement->get_sourceIndex(&lActSrcIndex);
for(long i = 0;i< nNumElements;i++)
{
VARIANT varName;
varName.vt=VT_UINT;
varName.lVal = i;
VARIANT varIndex;
LPDISPATCH lpElementDisp=NULL;
pColl->item(varName,varIndex,&lpElementDisp);
{
if(bFassCurFocus)//过了焦点,出现可焦则焦
{
IHTMLElement2* pElement2=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLElement2,(void**)&pElement2)))
{
IHTMLInputElement2*pInput=NULL;
IHTMLAnchorElement2* pAnchor=NULL;
IHTMLTextAreaElement* pTextArea=NULL;
IHTMLFrameBase2* pFrame=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLInputElement2,(void**)&pInput))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLAnchorElement2,(void**)&pAnchor))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLTextAreaElement,(void**)&pTextArea))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLFrameBase2,(void**)&pFrame)))
{
if(pInput||pAnchor||pTextArea||pFrame)
{
if(SUCCEEDED(pElement2->focus()))
bFocus=TRUE;
if(pInput)
pInput->Release();
if(pAnchor)
pAnchor->Release();
if(pTextArea)
pTextArea->Release();
if(pFrame&&bFocus)
pFrame->Release();
if(bFocus)
{
pElement2->Release();
break;
}
}
}
pElement2->Release();
}
}
else
{
IHTMLElement* pElement=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLElement,(void**)&pElement)))
{
long lCurSrcIndex;
pElement->get_sourceIndex(&lCurSrcIndex);
if(lCurSrcIndex==lActSrcIndex)//找到当前活动元素
{
bFassCurFocus=TRUE;
}
pElement->Release();
}
}
}
}//for
pActiveElement->Release();
}
}
}
pColl->Release();
}
pDoc->Release();
}
return bFocus;
}
//////////////////////////
BOOL CHtmlView::SetFocusToPrev()
{
BOOL bFocus=FALSE;
BOOL bFassCurFocus=FALSE;
LPDISPATCH lpDisp=NULL;
m_pHost->m_pWebBrowser->get_Document(&lpDisp);
IHTMLDocument2 *pDoc=NULL;
lpDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
if(pDoc)
{
IHTMLElementCollection* pColl = NULL;
//得到所有元素
if(SUCCEEDED(pDoc->get_all(&pColl)))
{
long nNumElements;
if(SUCCEEDED(pColl->get_length(&nNumElements)))
{
if(nNumElements)
{
IHTMLElement* pActiveElement=NULL;
if(SUCCEEDED(pDoc->get_activeElement(&pActiveElement)))
{
//这里已获得activeElement
long lActSrcIndex;
pActiveElement->get_sourceIndex(&lActSrcIndex);
for(long i=nNumElements-1;i>=0;i--)
{
VARIANT varName;
varName.vt=VT_UINT;
varName.lVal = i;
VARIANT varIndex;
LPDISPATCH lpElementDisp=NULL;
pColl->item(varName,varIndex,&lpElementDisp);
{
if(bFassCurFocus)//过了焦点,出现可焦则焦
{
IHTMLElement2* pElement2=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLElement2,(void**)&pElement2)))
{
IHTMLInputElement2*pInput=NULL;
IHTMLAnchorElement2* pAnchor=NULL;
IHTMLTextAreaElement* pTextArea=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLInputElement2,(void**)&pInput))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLAnchorElement2,(void**)&pAnchor))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLTextAreaElement,(void**)&pTextArea)))
{
if(pInput||pAnchor||pTextArea)
{
if(SUCCEEDED(pElement2->focus()))
{
pElement2->Release();
bFocus=TRUE;
break;
}
if(pInput)
pInput->Release();
if(pAnchor)
pAnchor->Release();
if(pTextArea)
pTextArea->Release();
}
}
pElement2->Release();
}
}
else
{
IHTMLElement* pElement=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLElement,(void**)&pElement)))
{
long lCurSrcIndex;
pElement->get_sourceIndex(&lCurSrcIndex);
if(lCurSrcIndex==lActSrcIndex)//找到当前活动元素
{
bFassCurFocus=TRUE;
}
pElement->Release();
}
}
}
}//for
pActiveElement->Release();
}
}
}
pColl->Release();
}
else
Alert("er");
pDoc->Release();
}
lpDisp->Release();
return bFocus;
}
void CHtmlView::SetFocusToFirst(LPDISPATCH pHtmlDocument)
{
IHTMLDocument2 *pDoc=NULL;
pHtmlDocument->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
if(pDoc)
{
IHTMLElementCollection* pColl = NULL;
//得到所有元素
if(SUCCEEDED(pDoc->get_all(&pColl)))
{
long nNumElements;
if(SUCCEEDED(pColl->get_length(&nNumElements)))
{
if(nNumElements)
{
for(long i = 0;i< nNumElements;i++)
{
VARIANT varName;
varName.vt=VT_UINT;
varName.lVal = i;
VARIANT varIndex;
LPDISPATCH lpElementDisp=NULL;
pColl->item(varName,varIndex,&lpElementDisp);
{
IHTMLElement2* pElement2=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLElement2,(void**)&pElement2)))
{
IHTMLInputElement2*pInput=NULL;
IHTMLAnchorElement2* pAnchor=NULL;
IHTMLTextAreaElement* pTextArea=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLInputElement2,(void**)&pInput))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLAnchorElement2,(void**)&pAnchor))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLTextAreaElement,(void**)&pTextArea)))
{
if(pInput||pAnchor||pTextArea)
{
if(SUCCEEDED(pElement2->focus()))
{
pElement2->Release();
break;
}
if(pInput)
pInput->Release();
if(pAnchor)
pAnchor->Release();
if(pTextArea)
pTextArea->Release();
}
}
pElement2->Release();
}
}
}
}
}
pColl->Release();
}
pDoc->Release();
}
}
////////////////////////// http://www.wzszf.com/
void CHtmlView::SetFocusToLast()
{
LPDISPATCH lpDisp=NULL;
m_pHost->m_pWebBrowser->get_Document(&lpDisp);
IHTMLDocument2 *pDoc=NULL;
lpDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
if(pDoc)
{
IHTMLElementCollection* pColl = NULL;
//得到所有元素
if(SUCCEEDED(pDoc->get_all(&pColl)))
{
long nNumElements;
if(SUCCEEDED(pColl->get_length(&nNumElements)))
{
if(nNumElements)
{
for(long i = nNumElements-1;i>=0;i--)
{
VARIANT varName;
varName.vt=VT_UINT;
varName.lVal = i;
VARIANT varIndex;
LPDISPATCH lpElementDisp=NULL;
pColl->item(varName,varIndex,&lpElementDisp);
{
IHTMLElement2* pElement2=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLElement2,(void**)&pElement2)))
{
IHTMLInputElement2*pInput=NULL;
IHTMLAnchorElement2* pAnchor=NULL;
IHTMLTextAreaElement* pTextArea=NULL;
if(SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLInputElement2,(void**)&pInput))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLAnchorElement2,(void**)&pAnchor))
||SUCCEEDED(lpElementDisp->QueryInterface(IID_IHTMLTextAreaElement,(void**)&pTextArea)))
{
if(pInput||pAnchor||pTextArea)
{
if(SUCCEEDED(pElement2->focus()))
{
pElement2->Release();
break;
}
if(pInput)
pInput->Release();
if(pAnchor)
pAnchor->Release();
if(pTextArea)
pTextArea->Release();
}
}
pElement2->Release();
}
}
}
}
}
pColl->Release();
}
pDoc->Release();
}
lpDisp->Release();
}
理论上这个方法可以解决,事实也接近解决,当然在遇到Frame时候我碰到了极大挑战。结果,我开始重新思考解决方案。