Skip to content

Instantly share code, notes, and snippets.

@yak1ex
Created December 31, 2013 12:50
Show Gist options
  • Save yak1ex/8196323 to your computer and use it in GitHub Desktop.
Save yak1ex/8196323 to your computer and use it in GitHub Desktop.
COM / DistHelper samples
// ref. http://www.ne.jp/asahi/hishidama/home/tech/vcpp/webbrowser.html
// This document includes MANY misleading explanations but is useful anyway for implementation reference.
#include <iostream>
#include <windows.h>
#include <exdisp.h>
#include <comdef.h>
__CRT_UUID_DECL(IWebBrowser2, 0xd30c1661, 0xcdaf, 0x11d0, 0x8a, 0x3e, 0x00, 0xc0, 0x4f, 0xc9, 0xe2, 0x6e);
// Not deeply analyzed, but definition in comdefsp.h seems to have no effect.
_COM_SMARTPTR_TYPEDEF(IWebBrowser2,__uuidof(IWebBrowser2));
_COM_SMARTPTR_TYPEDEF(IViewObject,__uuidof(IViewObject));
_COM_SMARTPTR_TYPEDEF(IOleObject,__uuidof(IOleObject));
#include "disphelper/disphelper.h"
void DPtoHIMETRIC(LPSIZEL lpSizel)
{
HDC hdc;
const int HIMETRIC_INCH = 2540;
hdc = GetDC(NULL);
lpSizel->cx = MulDiv(lpSizel->cx, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSX));
lpSizel->cy = MulDiv(lpSizel->cy, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSY));
ReleaseDC(NULL, hdc);
}
int main(void)
{
HRESULT hr = CoInitialize(0);
if(FAILED(hr)) {
std::cout << "CoInitialize() error" << std::endl;
return -1;
}
try {
IWebBrowser2Ptr pIE;
HRESULT hrCreate = pIE.CreateInstance(L"InternetExplorer.Application");
if(FAILED(hrCreate)) {
std::cout << "IECreate failed" << std::endl;
}
dhCheck(dhCallMethod(pIE, L".Navigate(%S)", L"About:blank"));
dhPutValue(pIE, L"Visible = %b", TRUE);
BOOL bBusy;
while (dhCheck(dhGetValue(L"%b", &bBusy, pIE, L".Busy")) && bBusy) Sleep(150);
WITH(pDoc, pIE, L".Document")
{
dhCallMethod(pDoc, L".Open");
dhCallMethod(pDoc, L".Writeln(%S)", L"<html><body>Test</body></html>");
dhCallMethod(pDoc, L".Close");
} END_WITH_THROW(pDoc);
} catch (std::string errstr) {
std::cerr << "Fatal error details:" << std::endl << errstr << std::endl;
}
CoUninitialize();
return 0;
}
// ref. http://eternalwindows.jp/ole/oledraw/oledraw01.html
#include <iostream>
#include <windows.h>
#include <exdisp.h>
#include <comdef.h>
#include <mshtml.h>
__CRT_UUID_DECL(IWebBrowser2, 0xd30c1661, 0xcdaf, 0x11d0, 0x8a, 0x3e, 0x00, 0xc0, 0x4f, 0xc9, 0xe2, 0x6e);
__CRT_UUID_DECL(IHTMLDocument2, 0x332C4425, 0x26CB, 0x11D0, 0xB4, 0x83, 0x00, 0xC0, 0x4F, 0xD9, 0x01, 0x19);
// Not deeply analyzed, but definition in comdefsp.h seems to have no effect.
_COM_SMARTPTR_TYPEDEF(IWebBrowser2,__uuidof(IWebBrowser2));
_COM_SMARTPTR_TYPEDEF(IHTMLDocument2,__uuidof(IHTMLDocument2));
_COM_SMARTPTR_TYPEDEF(IViewObject,__uuidof(IViewObject));
_COM_SMARTPTR_TYPEDEF(IOleObject,__uuidof(IOleObject));
const CLSID CLSID_HTMLDocument = { 0x25336920, 0x03F9, 0x11CF, 0x8F, 0xD0, 0x00, 0xAA, 0x00, 0x68, 0x6F, 0x13 };
#include "disphelper/disphelper.h"
void DPtoHIMETRIC(LPSIZEL lpSizel)
{
HDC hdc;
const int HIMETRIC_INCH = 2540;
hdc = GetDC(NULL);
lpSizel->cx = MulDiv(lpSizel->cx, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSX));
lpSizel->cy = MulDiv(lpSizel->cy, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSY));
ReleaseDC(NULL, hdc);
}
/* **************************************************************************
* WaitForHTMLDocToLoad:
* This function waits for an html document's readystate to equal 'complete'
* so that its dom can be used.
* You may wish to implement a timeout.
*
============================================================================ */
HRESULT WaitForHTMLDocToLoad(IDispatch * pDoc)
{
HRESULT hr;
while (TRUE)
{
MSG msg;
CDhStringW szReadyState;
hr = dhGetValue(L"%S", &szReadyState, pDoc, L".readyState");
if (FAILED(hr) || !szReadyState || 0 == wcsicmp(szReadyState, L"complete"))
{
break;
}
/* We must pump the message loop while the document is downloading */
if (WAIT_TIMEOUT != MsgWaitForMultipleObjects(0, NULL, FALSE, 250, QS_ALLEVENTS))
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return hr;
}
int main(void)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(FAILED(hr)) {
std::cout << "CoInitialize() error" << std::endl;
return -1;
}
try {
IHTMLDocument2Ptr pDoc;
HRESULT hrCreate = pDoc.CreateInstance(L"htmlFile", 0, CLSCTX_INPROC_SERVER);
// HRESULT hrCreate = pDoc.CreateInstance(CLSID_HTMLDocument, 0, CLSCTX_INPROC_SERVER);
if(FAILED(hrCreate)) {
std::cout << "HTMLDocument creation failed" << std::endl;
}
dhCheck(dhCallMethod(pDoc, L".Writeln(%S)", L"<html><body>Test</body></html>"));
dhCallMethod(pDoc, L".Write");
dhCheck(dhCallMethod(pDoc, L".Close"));
CDhStringA szHTML;
dhGetValue(L"%s", &szHTML, pDoc, L".documentElement.outerHTML");
std::cout << szHTML << std::endl;
RECT imageRect = {0, 0, 256, 256};
HDC hDC = GetDC(0);
HDC hCompDC = CreateCompatibleDC(hDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, 256, 256);
SelectObject(hCompDC, hBitmap);
IOleObjectPtr pOleObject;
pDoc->QueryInterface(IID_PPV_ARGS(&pOleObject));
SIZEL sizel = { 256, 256 };
DPtoHIMETRIC(&sizel);
pOleObject->SetExtent(DVASPECT_CONTENT, &sizel);
OleDraw(pDoc, DVASPECT_CONTENT, hCompDC, &imageRect);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
} catch (std::string errstr) {
std::cerr << "Fatal error details:" << std::endl << errstr << std::endl;
}
CoUninitialize();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment