问========================================
你好:
在你的博客上看到了一些关于操作Internet Explorer的代码,有个问题请教
目的:在html页面中创建一个控件,程序动态创建。
我已经获得要创建页面的IHTMLDocument2指针,看msdn提示使用createElement函数调用后能够创建以及设置属性,创建为一个element我如何把它设置为一个对象或者applet对象或一个embed对象
我调用原有页面上的控件发现为一个applet对象,以下为动态创建的函数:
void InsertElement(IHTMLDocument2 * pIHTMLDocument2 )
{
HRESULT hr;
IHTMLElement *pHtmlElement = NULL;
CComBSTR bstrTitle = L"applet";
pIHTMLDocument2->createElement(bstrTitle, &pHtmlElement);
//创建后不知道如何设置成一个applet的对象或者embed对象
VARIANT vRet;
VariantInit(&vRet);
CComBSTR bstrClassID = L"classid";
vRet.bstrVal = L"clsid:75B6E755-01FB-46C0-BA16-27350A1855B1";
vRet.vt = VT_BSTR;
hr = pHtmlElement->setAttribute(bstrClassID, vRet);
if ( FAILED( hr ) )
{
cout << _T("setAttribute错误") << endl;
return;
}
CComBSTR bstrID = L"id";
vRet.bstrVal = L"myocx1";
vRet.vt = VT_BSTR;
hr = pHtmlElement-> setAttribute (bstrID, vRet);
if ( FAILED( hr ) )
{
cout << _T("setAttribute错误") << endl;
return;
}
CComBSTR bstrName = L"name";
vRet.bstrVal = L"myocx1";
hr = pHtmlElement-> setAttribute (bstrName, vRet);
if ( FAILED( hr ) )
{
cout << _T("setAttribute错误") << endl;
return;
}
//如果创建applet对象,是否需要其他的属性或者设置,其他方法????
。。。
}
答========================================
创建Element之后,应通过IHTMLDOMNode::insertBefore或IHTMLDOMNode::appendChild把元素添加到DOM树中去,所以代码本来应该是这样的:
LPDISPATCH lpDisp = GetHtmlDocument();if (lpDisp)...{ CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> spDoc(lpDisp); if ( spDoc ) ...{ CComPtr<IHTMLElement> spElem; HRESULT hr = spDoc->createElement(L"applet", &spElem); if ( FAILED(hr) || !spElem ) return; CComPtr<IHTMLElement> pBodyElem; hr = spDoc->get_body(&pBodyElem); if ( FAILED(hr) || !pBodyElem ) return; CComPtr<IHTMLDOMNode> pBodyNode(pBodyElem); if ( !pBodyNode ) return; CComPtr<IHTMLDOMNode> pNewChild(pElem); CComPtr<IHTMLDOMNode> pRefChild; hr = pBodyNode->appendChild(pNewChild, &pRefChild); if ( FAILED(hr) || !pRefChild ) return; CComQIPtr<IHTMLObjectElement, &IID_IHTMLObjectElement> pObj(pRefChild); if ( pObj ) ...{ //修改属性等等 } }}但试验下来最后一步总是不能成功,从pRefChild得不到pObj,尽管类似的代码用脚本实现没有什么问题:
<HTML><HEAD><SCRIPT>...function createRadioButton()...{ // Create radio button object with value="First Choice" and then insert // this element into the document hierarchy. var newRadioButton = document.createElement("<INPUT TYPE='RADIO' NAME='RADIOTEST' VALUE='First Choice'>") document.body.insertBefore(newRadioButton); // Create radio button object with value="Second Choice" and then insert // this element into the document hierarchy. newRadioButton = document.createElement("<INPUT TYPE='RADIO' NAME='RADIOTEST' VALUE='Second Choice'>") document.body.insertBefore(newRadioButton);}</SCRIPT></HEAD><BODY><INPUT TYPE="BUTTON" ONCLICK="createRadioButton()" VALUE="Create two Radio Buttons"><BR>
<INPUT TYPE="BUTTON" ONCLICK="alert ( document.body.outerHTML )" VALUE="Click here to see HTML"><BODY></HTML>看来我们只能用另外一种办法了——insertAdjacentHTML,如下:
LPDISPATCH lpDisp = GetHtmlDocument();if (lpDisp)...{ CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> spDoc(lpDisp); if ( spDoc ) ...{ CComPtr<IHTMLElement> spBodyElem; HRESULT hr = spDoc->get_body(&spBodyElem); if ( FAILED(hr) || !spBodyElem ) return; //我们先创建网页元素,注意给一个ID hr = spBodyElem->insertAdjacentHTML(L"beforeEnd", L"<applet code='RainbowText.class' ID='my applet' width='297' height='48' codebase='class/' name='rainbowText'><param name='TEXT' value='test' ></applet>"); if ( FAILED(hr) ) return; //再通过IHTMLDocument3来访问它 CComQIPtr<IHTMLDocument3, &IID_IHTMLDocument3> spDoc3(lpDisp); if ( !spDoc3 ) return; CComQIPtr<IHTMLElement> spElemTemp; hr = spDoc3->getElementById(L"my applet", &spElemTemp); if ( FAILED(hr) || !spElemTemp) return; //把Applet作为IHTMLObjectElement来处理 CComQIPtr<IHTMLObjectElement, &IID_IHTMLObjectElement> pApplet(spElemTemp); if ( pApplet ) ...{ //这样就行了 } }}能抓到老鼠就是好猫:)
参考文献: