使用MSHTML 对 Html 进行DOM 操作(放缩,颜色...),HTML抓图(放缩,滚动,拼接)
以前的代码,使用ATL会更整洁
// 放缩抓图
void CPageCaptureView::GetZoomPageDC()
{
LONG lWidth = WINDOW_WIDTH;
LONG lHeight = WINDOW_HEIGHT;
BOOL bMargin = TRUE;
IOleWindow *InterfacePtr = NULL;
IHTMLDocument2* pDoc = NULL;
IHTMLElement* pBodyElem = NULL;
IHTMLBodyElement* pBody = NULL;
IHTMLElement2* pBodyElement2=NULL;
IHTMLStyle* pStyle = NULL;
IHTMLStyle3 *pStyle3=NULL;
LPDISPATCH pDisp = NULL;
IOleObject * pObj = NULL;
HRESULT hr = S_OK;
pDisp = GetHtmlDocument();
ASSERT(pDisp);
if (pDisp)
{
hr = pDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
if (SUCCEEDED(hr)&&pDoc)
{
hr = pDoc->get_body(&pBodyElem);
if (SUCCEEDED(hr)&&pBodyElem)
{
// hide 3D border
hr =pBodyElem->get_style(&pStyle);
if (SUCCEEDED(hr)&&pStyle)
{
pStyle->put_borderStyle(CComBSTR("none"));
hr = pStyle->QueryInterface(IID_IHTMLStyle3,(void**)&pStyle3);
if (SUCCEEDED(hr&&pStyle3))
{
CString str(ZOOM);
BSTR bStr = str.AllocSysString();
VARIANT var;
var.vt = VT_BSTR;
var.bstrVal= bStr;
pStyle3->put_zoom(var);
if (bStr)
{
SysFreeString(bStr);
}
pStyle3->Release();
}
pStyle->Release();
}
// hide scroll bars
hr = pBodyElem->QueryInterface(IID_IHTMLBodyElement, (void**)&pBody);
if (SUCCEEDED(hr)&&pBody)
{
pBody->put_scroll(CComBSTR("no"));
pBody->Release();
}
// get dimension and resize
hr = pBodyElem->QueryInterface(IID_IHTMLElement2, (void**)&pBodyElement2);
if (SUCCEEDED(hr)&&pBodyElement2)
{
long iScrollWidth = 0,iScrollHeight = 0,
iClientWidth = 0,iClientHeight = 0;
pBodyElement2->get_scrollWidth(&iScrollWidth);
pBodyElement2->get_scrollHeight(&iScrollHeight);
pBodyElement2->get_clientWidth(&iClientWidth);
pBodyElement2->get_clientHeight(&iClientHeight);
CString strZoom(ZOOM);
strZoom.Replace("%","");
float fZoom = atof(strZoom)/100.0;
if (iScrollWidth>iClientWidth)
{
lWidth = fZoom * iScrollWidth;
bMargin = FALSE;
}
if (iScrollHeight>iClientHeight)
{
lHeight = fZoom * iScrollHeight;
}
SetWindowPos(NULL,0,0,lWidth,lHeight,SWP_HIDEWINDOW);
pBodyElement2->Release();
}
LONG lBmpWidth = lWidth;
LONG lBmpHeight = lHeight;
LONG lMarginLeft = 50, lMarginRight = 50, lMarginTop = 35, lMarginBottom = 35;
if (lBmpWidth > lBmpHeight*ASPECT_RADIO)
{
lBmpHeight = lBmpWidth/ASPECT_RADIO;
}
else
{
lBmpWidth = lBmpHeight*ASPECT_RADIO;
}
if (!bMargin)
{
lMarginLeft = lMarginRight = lMarginTop = lMarginBottom = 0;
lBmpWidth = lWidth;
lBmpHeight = lHeight;
}
LONG lPageWidth = lBmpWidth + lMarginLeft + lMarginRight;
LONG lPageHeight = lBmpHeight + lMarginTop + lMarginBottom;
// resize ole
hr = m_pBrowserApp->QueryInterface(IID_IOleObject,(void**)&pObj);
if (SUCCEEDED(hr)&&pObj)
{
SIZEL size ={lWidth,lHeight};
pObj->SetExtent(DVASPECT_CONTENT,&size);
pObj->Release();
}
//Draw
HDC hScreenDC = ::GetDC(NULL);
HDC hDrawDC = CreateCompatibleDC(NULL);
// SIZE PrevExt1, PrevExt2;
// SetMapMode(hImageDC, MM_HIENGLISH);
// GetWindowExtEx(hImageDC, &PrevExt1);
// GetViewportExtEx(hImageDC, &PrevExt2);
//
// PrevExt1.cx *= 0.6;
// PrevExt1.cy *= 0.6;
// SetMapMode(hImageDC, MM_ISOTROPIC);
// SetWindowExtEx(hImageDC, PrevExt1.cx, PrevExt1.cy, NULL); //600DPI
// SetViewportOrgEx(hImageDC, 0, 0, NULL);
// SetViewportExtEx(hImageDC, PrevExt2.cx, -PrevExt2.cy, NULL);
HBITMAP hDrawBmp = NULL;
hDrawBmp = CreateCompatibleBitmap(hScreenDC, lWidth,
lHeight);
if(!hDrawBmp)
return;
HGDIOBJ hOld = SelectObject(hDrawDC, hDrawBmp);
RECT rt = {0,0,lWidth,lHeight};
HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
FillRect(hDrawDC,&rt,hBrush);
RECT rcSource={0,0,lWidth,lHeight};
OleDraw(m_pBrowserApp,DVASPECT_CONTENT,hDrawDC,&rcSource);
HANDLE hDibNew = pDib->CreateDib(lPageWidth,lPageHeight,NULL, 24);
if (pDib->hdib)
{
GlobalFree(pDib->hdib);
pDib->hdib = NULL;
}
if (hDibNew)
{
pDib->CreateDibFromHandle(hDibNew);
}
CDrawDib dib;
HANDLE handle = NULL;
handle = dib.DibFromBitmap(hDrawBmp,BI_RGB,24,NULL);
if (handle&&pDib)
{
pDib->BitBlts(lMarginLeft+(lBmpWidth-lWidth)/2.0,lMarginTop+(lBmpHeight-lHeight)/2.0,
handle);
GlobalFree(handle);
}
::DeleteObject(hBrush);
::DeleteObject(hDrawBmp);
::ReleaseDC(0, hScreenDC);
::DeleteDC(hDrawDC);
pBodyElem->Release();
}
pDoc->Release();
}
pDisp->Release();
}
g_eventComplete->SetEvent();
}
// 改变Font
HRESULT CPageCaptureView::ChangeFontSize(float nZoom)
{
CComQIPtr<IHTMLDocument2,&IID_IHTMLDocument2> pDoc2;
CComQIPtr<IHTMLElementCollection,&IID_IHTMLElementCollection> pCollection;
//CComQIPtr<IHTMLDocument3,&IID_IHTMLDocument2> pDoc3;
CComQIPtr<IHTMLElement,&IID_IHTMLElement> pBody;
CComQIPtr<IHTMLElement2,&IID_IHTMLElement2> pBody2;
LPDISPATCH pDisp = NULL;
HRESULT hr = S_OK;
pDisp = GetHtmlDocument();
if(!pDisp)
{
return E_FAIL;
}
// hr = pDoc->QueryInterface(IID_IHTMLDocument3,(void**)&pDoc3);
hr = pDisp->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&pDoc2);
if (hr || (!pDoc2))
{
return E_FAIL;
}
hr = pDoc2->get_body(&pBody);//getElementsByTagName(L"SPAN",&pCollection);
if (hr || (!pBody))
{
return E_FAIL;
}
pBody->QueryInterface(IID_IHTMLElement2,(void**)&pBody2);
if (hr || (!pBody2))
{
return E_FAIL;
}
pBody2->getElementsByTagName(L"SPAN",&pCollection);;
if (hr || (!pCollection))
{
return E_FAIL;
}
long len;
VARIANT varIndex;
VARIANT var2;
varIndex.vt=VT_I4;
VariantInit( &var2 );
pCollection->get_length(&len);
CComVariant var;
for(long i=0; i<len; i++)
{
CComQIPtr<IHTMLStyle,&IID_IHTMLStyle> pStyle;
varIndex.lVal=i;
CComPtr<IDispatch> pDisp;
pCollection->item(varIndex,var2, &pDisp);
if (hr || (!pDisp))
{
return E_FAIL;
}
CComQIPtr<IHTMLElement,&IID_IHTMLElement> pElement(pDisp);
if ((!pElement))
{
return E_FAIL;
}
hr = pElement->get_style(&pStyle);
if (hr || (!pStyle))
{
continue;
}
hr = pStyle->get_fontSize(&var);
if(var.bstrVal != NULL && var.vt == VT_BSTR)
{
CString strSize(var.bstrVal);
strSize.TrimLeft();
strSize.TrimRight();
if (strSize.Find("pt")!=-1)
{
CString str =strSize.Left(strSize.GetLength()-2);
int n = atoi(str);
str.Format("%dpt",(int)(n*nZoom));
var.bstrVal = str.AllocSysString();
pStyle->put_fontSize(var);
}
}
}
return hr;
}