開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 OleDraw
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト


OleDraw.cpp
#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);
}
 
最終更新:2012年09月12日 09:33