您的位置:首页 > 其它

开源项目之在线网页截图工具 IECapt

2012-09-10 14:13 453 查看
这个项目是win32程序,就一个目标文件。

class CEventSink :public CComObjectRootEx <CComSingleThreadModel>, public IDispatch 实现了网页接口的事件***。

class CMain :public CWindowImpl <CMain> 窗口主要界面,快照的实现(获得网页接口对象)。



快照实现部分:

//////////////////////////////////////////////////////////////////
// Implementation of CMain::SaveSnapshot
//////////////////////////////////////////////////////////////////
BOOL CMain::SaveSnapshot(void)
{
long bodyHeight, bodyWidth, rootHeight, rootWidth, height, width;

CComPtr<IDispatch> pDispatch;

// TODO: "If the document object type is not safe for scripting,
// this method returns successfully but sets ppDisp to NULL. For
// Internet Explorer 7 and later, the return code is S_FALSE..."

//获得对象
HRESULT hr = m_pWebBrowser->get_Document(&pDispatch);

if (FAILED(hr))
return true;

//获得ihtml接口
CComPtr<IHTMLDocument2> spDocument;
hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&spDocument);

if (FAILED(hr))
return true;

//获得内容
CComPtr<IHTMLElement> spBody;
hr = spDocument->get_body(&spBody);

// Apparently with MSHTML failing to get the body is not a failure,
// so if there is no HTML body to get, which may be the case with
// SVG images loaded directly, this succeeds but sets spBody to the
// NULL pointer, leading to a crash. I am not sure how to obtain
// the sizing information for SVG documents so this errors out here.
// A work around would be the make HTML host documents or wrapping
// the SVG code in a XHTML document, but that may break scripts.
if (FAILED(hr) || spBody == NULL)
return true;

//查找相关接口
CComPtr<IHTMLElement2> spBody2;
hr = spBody->QueryInterface(IID_IHTMLElement2, (void**)&spBody2);

if (FAILED(hr))
return true;

hr = spBody2->get_scrollHeight(&bodyHeight);

if (FAILED(hr))
return true;

hr = spBody2->get_scrollWidth(&bodyWidth);

if (FAILED(hr))
return true;

CComPtr<IHTMLDocument3> spDocument3;
hr = pDispatch->QueryInterface(IID_IHTMLDocument3, (void**)&spDocument3);

if (FAILED(hr))
return true;

// We also need to get the dimensions from the <html> due to quirks
// and standards mode differences. Perhaps this should instead check
// whether we are in quirks mode? How does it work with IE8?
CComPtr<IHTMLElement> spHtml;
hr = spDocument3->get_documentElement(&spHtml);

if (FAILED(hr))
return true;

CComPtr<IHTMLElement2> spHtml2;
hr = spHtml->QueryInterface(IID_IHTMLElement2, (void**)&spHtml2);

if (FAILED(hr))
return true;

hr = spHtml2->get_scrollHeight(&rootHeight);

if (FAILED(hr))
return true;

hr = spHtml2->get_scrollWidth(&rootWidth);

if (FAILED(hr))
return true;

width = bodyWidth;
height = rootHeight > bodyHeight ? rootHeight : bodyHeight;

// TODO: What if width or height exceeds 32767? It seems Windows limits
// the window size, and Internet Explorer does not draw what's not visible.
::MoveWindow(m_hwndWebBrowser, 0, 0, width, height, TRUE);

CComPtr<IViewObject2> spViewObject;

// This used to get the interface from the m_pWebBrowser but that seems
// to be an undocumented feature, so we get it from the Document instead.
hr = spDocument3->QueryInterface(IID_IViewObject2, (void**)&spViewObject);

if (FAILED(hr))
return true;

RECTL rcBounds = { 0, 0, width, height };

_TCHAR* tcsExt = _tcsrchr(m_fileName, '.');
if (tcsExt && _tcscmp(_T(".emf"), tcsExt) == 0) {

USES_CONVERSION;
HDC hdcMain = GetDC();
int iWidthMM = GetDeviceCaps(hdcMain, HORZSIZE); 
int iHeightMM = GetDeviceCaps(hdcMain, VERTSIZE); 
int iWidthPels = GetDeviceCaps(hdcMain, HORZRES); 
int iHeightPels = GetDeviceCaps(hdcMain, VERTRES); 

Gdiplus::RectF rcBoundsX(0, 0,
(Gdiplus::REAL)width, (Gdiplus::REAL)height);

rcBoundsX.Y      *= iHeightMM * 100 / iHeightPels; 
rcBoundsX.X      *= iWidthMM  * 100 / iWidthPels; 
rcBoundsX.Width  *= iWidthMM  * 100 / iWidthPels; 
rcBoundsX.Height *= iHeightMM * 100 / iHeightPels; 

Gdiplus::Metafile emf(T2W(m_fileName), hdcMain, rcBoundsX,
Gdiplus::MetafileFrameUnitGdi, Gdiplus::EmfTypeEmfPlusDual,
L"[TODO: Description]");

//获得图片
Gdiplus::Graphics g(&emf);
HDC imgDc = g.GetHDC();

// For unknown reasons Internet Explorer will sometimes
// fail to draw glyphs for certain characters here even
// though they are rendered in Internet Explorer itself.
// On other pages, Internet Explorer will simply render
// a single bitmap into the emf which isn't really what
// this should do. I've no idea how to fix that however.

hr = spViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, imgDc,
imgDc, &rcBounds, NULL, NULL, 0);

g.ReleaseHDC(imgDc);
ReleaseDC(hdcMain);

return false;
}

CImage image;

// TODO: check return value;
// TODO: somehow enable alpha
image.Create(width, height, 24);

HDC imgDc = image.GetDC();
hr = spViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, imgDc,
imgDc, &rcBounds, NULL, NULL, 0);
image.ReleaseDC();

//保存
if (SUCCEEDED(hr))
hr = image.Save(m_fileName);

return false;
}


学习的目的是成熟!~


源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: