/*
  GDI+のBitmapでJpegと透過PNG画像を読み込む

      2011/07/12  宍戸 輝光
*/
#pragma once
#pragma	comment(lib, "Gdiplus.lib")

#include <windows.h>
#include <gdiplus.h>
#include <olectl.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE g_hInstance;
HWND g_hwMain;

Gdiplus::Bitmap * g_bmp1;
Gdiplus::Bitmap * g_bmp2;

IStream * getFileIStream(char *);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {

	MSG msg;
	WNDCLASS wndclass;

	Gdiplus::GdiplusStartupInput gpSI;
	ULONG_PTR lpToken;

	g_hInstance = hInstance;

	/* GDI+初期化 */
	Gdiplus::GdiplusStartup(&lpToken, &gpSI, NULL);

	/* 画像ファイルを読み込んだIStreamを作成 */
	IStream * is = getFileIStream("d:/test.jpg");

	/* IStreamからBitmap作成 */
	g_bmp1 = new Gdiplus::Bitmap(is);

	/* IStream解放 */
	is->Release();

	/* ファイルパスの文字列からBitmap作成 */
	g_bmp2 = new Gdiplus::Bitmap(L"d:/test.png");

	/* ウインドウクラス設定 */
	wndclass.style         = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc   = WndProc;
	wndclass.cbClsExtra    = 0;
	wndclass.cbWndExtra    = 0;
	wndclass.hInstance     = hInstance;
	wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.lpszMenuName  = NULL;
	wndclass.lpszClassName = "GDIPLUSLOADTEST";

	RegisterClass(&wndclass);

	/* メインウインドウ作成 */
	g_hwMain = CreateWindow("GDIPLUSLOADTEST", "GDI+のBitmapでJpegと透過PNG画像を読み込む", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 720, 520, NULL, NULL, hInstance, NULL);

	ShowWindow(g_hwMain, iCmdShow);

	while (GetMessage(&msg, NULL, 0, 0)) { /* メッセージループ */

		TranslateMessage(&msg);
		DispatchMessage(&msg);

	}

	/* Bitmapを削除 */
	delete g_bmp1;
	delete g_bmp2;

	/* GDI+終了 */
	Gdiplus::GdiplusShutdown(lpToken);

	return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) {

	HDC hdc;
	PAINTSTRUCT ps;

	Gdiplus::Graphics * g;

	switch (iMsg) {

	case WM_PAINT:

		hdc = BeginPaint(hwnd, &ps);

		/* GDI+のGraphicsオブジェクトを作成 */
		g = new Gdiplus::Graphics(hdc);

		/* 画像を読み込んでおいたBitmapを描画 */
		g->DrawImage(g_bmp1, 0, 0);
		g->DrawImage(g_bmp2, 0, 0);

		/* Graphicsオブジェクトを破棄 */
		delete g;

		EndPaint(hwnd, &ps);

		return 0;

	case WM_DESTROY :

		PostQuitMessage(0);

		return 0;

	}

	return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

/* 画像を読み込んだメモリブロックのIStreamを作成 */
IStream * getFileIStream(char *lpszPath) {

	HANDLE hFile;
	HGLOBAL hBuf;
	LPVOID lpBuf;

	IStream * isFile;

	DWORD dwFileSize, dwLoadSize;

	/* 画像ファイルオープン */
	hFile = CreateFile(lpszPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	/* ファイルサイズ取得 */
	dwFileSize = GetFileSize(hFile, NULL);

	/* 画像ファイルデータ格納用メモリブロック確保 */
	hBuf = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);

	/* メモリブロックをロックしアドレスを取得 */
	lpBuf = GlobalLock(hBuf);

	/* 画像ファイルのデータをメモリブロックに読み込む */
	ReadFile(hFile, lpBuf, GetFileSize(hFile, NULL), &dwLoadSize, NULL);

	CloseHandle(hFile);

	/* メモリブロックのロック解除 */
	GlobalUnlock(hBuf);

	/* メモリブロックからIStreamを作成 */
	CreateStreamOnHGlobal(hBuf, TRUE, &isFile);

	/* IStreamを返す */
	return isFile;

}