#include <Windows.h>
#include <MsHTML.h>
// 定数定義
static const TCHAR CLASS_NAME[] = TEXT("OleDraw");
static const TCHAR WINDOW_NAME[] = TEXT("OleDraw");
// 関数プロトタイプ宣言
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL GetObjectFromFile(LPWSTR lpszFilePath, IOleObject **ppOleObject);
void DPtoHIMETRIC(LPSIZEL lpSizel);
//==============================================================================
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcx;
HWND hWnd;
MSG msg;
// ウィンドウクラスの登録
wcx.cbSize = sizeof (WNDCLASSEX);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = WindowProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = CLASS_NAME;
wcx.hIconSm = NULL;
if (RegisterClassEx(&wcx) == 0) {
return 0;
}
// ウィンドウの作成
hWnd = CreateWindow(
CLASS_NAME,
WINDOW_NAME,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL,
NULL,
hInstance,
NULL);
if (hWnd == NULL) {
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// メッセージループ
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//------------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static IOleObject *pOleObject = NULL;
switch (uMsg) {
case WM_CREATE:
CoInitializeEx(NULL, COINIT_MULTITHREADED);
GetObjectFromFile(L"C:\\tmp\\index.html", &pOleObject);
break;
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
SIZEL sizel;
hdc = BeginPaint(hWnd, &ps);
if (pOleObject) {
SetRect(&rc, 0, 0, 800, 600);
sizel.cx = rc.right - rc.left;
sizel.cy = rc.bottom - rc.top;
DPtoHIMETRIC(&sizel);
pOleObject->SetExtent(DVASPECT_CONTENT, &sizel);
OleDraw(pOleObject, DVASPECT_CONTENT, hdc, &rc);
}
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
if (pOleObject) pOleObject->Release();
CoUninitialize();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//------------------------------------------------------------------------------
BOOL GetObjectFromFile(LPWSTR lpszFilePath, IOleObject **ppOleObject)
{
HRESULT hr;
IHTMLDocument2 *pDocument2;
IPersistFile *pPersistFile = NULL;
BSTR bstrState;
hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pDocument2));
if (FAILED(hr)) return FALSE;
hr = pDocument2->QueryInterface(IID_PPV_ARGS(&pPersistFile));
if (FAILED(hr)) goto Exit;
hr = pPersistFile->Load(lpszFilePath, STGM_READ);
if (FAILED(hr)) goto Exit; // URLではE_UNEXPECTEDとなる
while (1) {
Sleep(10);
pDocument2->get_readyState(&bstrState);
if (lstrcmpW(bstrState, L"complete") == 0) {
SysFreeString(bstrState);
break;
}
SysFreeString(bstrState);
}
hr = pDocument2->QueryInterface(IID_PPV_ARGS(ppOleObject));
Exit:
if (pPersistFile) pPersistFile->Release();
pDocument2->Release();
return SUCCEEDED(hr);
}
//------------------------------------------------------------------------------
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);
}