⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 createhtmlimage.cpp

📁 顾名思义
💻 CPP
字号:
/*
 *	$Header: $
 *
 *	$History: $
 */
#include "stdafx.h"
#include <exdispid.h>
#include "CreateHTMLImage.h"
#include "FileSpec.h"
#include "BitmapDC.h"

IMPLEMENT_DYNCREATE(CCreateHTMLImage, CWnd)

BEGIN_EVENTSINK_MAP(CCreateHTMLImage, CWnd)
	ON_EVENT(CHtmlView, CHILDBROWSER, DISPID_DOCUMENTCOMPLETE, DocumentComplete, VTS_DISPATCH VTS_PVARIANT)
END_EVENTSINK_MAP()

LPCTSTR CCreateHTMLImage::m_ImageFormats[] =
{
	"image/bmp",
	"image/jpeg",
	"image/gif",
	"image/tiff",
	"image/png"
};

// CCreateHTMLImage
CCreateHTMLImage::CCreateHTMLImage() : CWnd()
{
	SetSaveImageFormat(eJPG);
}

CCreateHTMLImage::~CCreateHTMLImage()
{
}

BOOL CCreateHTMLImage::SetSaveImageFormat(eOutputImageFormat format)
{
	USES_CONVERSION;
	ASSERT(format >= 0 && format < eImgSize);

	return GetEncoderClsid(A2W(m_ImageFormats[format]), &m_encoderClsid) != -1;
}

BOOL CCreateHTMLImage::CreateControlSite(COleControlContainer* pContainer,  COleControlSite** ppSite, UINT /* nID */, REFCLSID /* clsid */)
{
	ASSERT(ppSite != NULL);
	*ppSite = new CHTMLImageControlSite(pContainer);
	return TRUE;
}

// CCreateHTMLImage member functions
BOOL CCreateHTMLImage::Create(CWnd *pParent)
{
	ASSERT(GetSafeHwnd() == HWND(NULL));
	ASSERT(pParent);
	ASSERT_KINDOF(CWnd, pParent);
	ASSERT(IsWindow(pParent->GetSafeHwnd()));

	CRect rect;

	if (!CWnd::Create(NULL, NULL, WS_CHILD, rect, pParent, 0, NULL))
		return FALSE;

	//	Window style must include WS_VISIBLE even though we never see the window. Otherwise the WebBrowser
	//	seems not to load documents.
	if (!m_pBrowserWnd.CreateControl(CLSID_WebBrowser, _T(""), WS_VISIBLE | WS_CHILD, rect, this, CHILDBROWSER))
	{
		DestroyWindow();
		return FALSE;
	}

	// cache the dispinterface
	LPUNKNOWN lpUnk = m_pBrowserWnd.GetControlUnknown();
	HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowser);

	if (!SUCCEEDED(hr))
	{
		m_pBrowser = NULL;
		m_pBrowserWnd.DestroyWindow();
		DestroyWindow();
		return FALSE;
	}

	return TRUE;
}

BOOL CCreateHTMLImage::CreateImage(LPCTSTR szSrcFilename, LPCTSTR szDestFilename, CSize srcSize, CSize outputSize)
{
	ASSERT(GetSafeHwnd());
	ASSERT(IsWindow(GetSafeHwnd()));
	ASSERT(szSrcFilename);
	ASSERT(AfxIsValidString(szSrcFilename));
	ASSERT(szDestFilename);
	ASSERT(AfxIsValidString(szDestFilename));

	CRect rect(CPoint(0, 0), srcSize);

	//	The WebBrowswer window size must be set to our srcSize
	//	else it won't render everything
	MoveWindow(&rect);
	m_pBrowserWnd.MoveWindow(&rect);

	COleVariant	  vUrl(szSrcFilename, VT_BSTR),
				  vFlags(long(navNoHistory | navNoReadFromCache | navNoWriteToCache), VT_I4),
				  vNull(LPCTSTR(NULL), VT_BSTR);
	COleSafeArray vPostData;

	if (m_pBrowser->Navigate2(&vUrl, &vFlags, &vNull, &vPostData, &vNull) == S_OK)
		//	We have to pump messages to ensure the event handler (DocumentComplete)
		//	is called.
		RunModalLoop();
	else
		return FALSE;

	//	We only get here when DocumentComplete has been called, which calls EndModalLoop
	//	and causes RunModalLoop to exit.
	IDispatch *pDoc = (IDispatch *) NULL;
	HRESULT	  hr = m_pBrowser->get_Document(&pDoc);

	if (FAILED(hr))
		return FALSE;

	return CreateImage((IHTMLDocument2 *) pDoc, szDestFilename, srcSize, outputSize);
}

BOOL CCreateHTMLImage::CreateImage(IHTMLDocument2 *pDoc, LPCTSTR szDestFilename, CSize srcSize, CSize outputSize)
{
	USES_CONVERSION;
	ASSERT(szDestFilename);
	ASSERT(AfxIsValidString(szDestFilename));
	ASSERT(pDoc);

	//	Get our interfaces before we create anything else
	IHTMLElement	   *pElement = (IHTMLElement *) NULL;
	IHTMLElementRender *pRender = (IHTMLElementRender *) NULL;

	//	Let's be paranoid...
	if (pDoc == (IHTMLDocument2 *) NULL)
		return FALSE;

	pDoc->get_body(&pElement);

	if (pElement == (IHTMLElement *) NULL)
		return FALSE;

	pElement->QueryInterface(IID_IHTMLElementRender, (void **) &pRender);

	if (pRender == (IHTMLElementRender *) NULL)
		return FALSE;

	CFileSpec fsDest(szDestFilename);
	CBitmapDC destDC(srcSize.cx, srcSize.cy);

	pRender->DrawToDC(destDC);

	CBitmap *pBM = destDC.Close();
	
	Bitmap *gdiBMP = Bitmap::FromHBITMAP(HBITMAP(pBM->GetSafeHandle()), NULL);
	Image  *gdiThumb = gdiBMP->GetThumbnailImage(outputSize.cx, outputSize.cy);

	gdiThumb->Save(A2W(fsDest.GetFullSpec()), &m_encoderClsid);
	delete gdiBMP;
	delete gdiThumb;
	delete pBM;
	return TRUE;
}

void CCreateHTMLImage::DocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
{
	UNUSED_ALWAYS(pDisp);
	UNUSED_ALWAYS(URL);
	TRACE("CCreateHTMLImage::DocumentComplete\n");
	EndModalLoop(0);
}

int CCreateHTMLImage::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	UINT  num = 0;          // number of image encoders
	UINT  size = 0;         // size of the image encoder array in bytes

	ImageCodecInfo* pImageCodecInfo = NULL;
	GetImageEncodersSize(&num, &size);

	if(size == 0)
		return -1;  // Failure

	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));

	if(pImageCodecInfo == NULL)
		return -1;  // Failure

	GetImageEncoders(num, size, pImageCodecInfo);

	for(UINT j = 0; j < num; ++j)
	{
		if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;  // Success
		}    
	}

	free(pImageCodecInfo);
	return -1;  // Failure
}

//////////////////////////////////////////////////////////////////////
//	Implementation of the CHTMLImageControlSite class, including the
//	IDocHostUIHandler implementation
BEGIN_INTERFACE_MAP(CHTMLImageControlSite, COleControlSite)
	INTERFACE_PART(CHTMLImageControlSite, IID_IDocHostUIHandler, DocHostUIHandler)
END_INTERFACE_MAP()

CHTMLImageControlSite::CHTMLImageControlSite(COleControlContainer* pContainer) : COleControlSite(pContainer)
{
}

// IUnknown methods
STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::QueryInterface(REFIID riid, void **ppvObj)
{
	METHOD_PROLOGUE_EX_(CHTMLImageControlSite, DocHostUIHandler)
	return pThis->ExternalQueryInterface(&riid, ppvObj);
}

STDMETHODIMP_(ULONG) CHTMLImageControlSite::XDocHostUIHandler::AddRef()
{
	METHOD_PROLOGUE_EX_(CHTMLImageControlSite, DocHostUIHandler)
	return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CHTMLImageControlSite::XDocHostUIHandler::Release()
{
	METHOD_PROLOGUE_EX_(CHTMLImageControlSite, DocHostUIHandler)
	return pThis->ExternalRelease();
}

// IDocHostUIHandler methods
STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::ShowContextMenu(DWORD /*dwID*/, POINT * /*ppt*/, IUnknown * /*pcmdtReserved*/, IDispatch * /*pdispReserved*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
{
	pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_SCROLL_NO;
	return S_OK;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::ShowUI(DWORD /*dwID*/, IOleInPlaceActiveObject * /*pActiveObject*/, IOleCommandTarget * /*pCommandTarget*/, IOleInPlaceFrame * /*pFrame*/, IOleInPlaceUIWindow * /*pDoc*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::HideUI(void)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::UpdateUI(void)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::EnableModeless(BOOL /*fEnable*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::OnDocWindowActivate(BOOL /*fActivate*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::OnFrameWindowActivate(BOOL /*fActivate*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::ResizeBorder(LPCRECT /*prcBorder*/, IOleInPlaceUIWindow * /*pUIWindow*/, BOOL /*fRameWindow*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::TranslateAccelerator(LPMSG /*lpMsg*/, const GUID * /*pguidCmdGroup*/, DWORD /*nCmdID*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::GetOptionKeyPath(LPOLESTR * /*pchKey*/, DWORD /*dw*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::GetDropTarget(IDropTarget * /*pDropTarget*/, IDropTarget ** /*ppDropTarget*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::GetExternal(IDispatch ** /*ppDispatch*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::TranslateUrl(DWORD /*dwTranslate*/, OLECHAR * /*pchURLIn*/, OLECHAR ** /*ppchURLOut*/)
{
	return S_FALSE;
}

STDMETHODIMP CHTMLImageControlSite::XDocHostUIHandler::FilterDataObject(IDataObject * /*pDO*/, IDataObject ** /*ppDORet*/)
{
	return S_FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -