/*--------------------------------------------------------

    Windows utility library for sample

    Copyright (C) 2008 SEGA Corporation Library R&D Dept.
    All Rights Reserved.

    Module  : Windows utility library for sample
    File    : smpWin.cpp
    Create  : 2008/06/13 (Ver.0.10.01)
    Modify  : 2008/09/12 (Ver.0.10.02)
				SMPWIN_TYPE_FOCUS_IN
				SMPWIN_TYPE_FOCUS_OUT
				を追加。
				メッセージがメッセージキューに溜まってしまう不具合を修正。
			  2009/01/13 (Ver.0.10.03)
			    IsWindowVisible(…)関数を追加。
				smpWinShowWindow()、smpWinUpdateWindow() 関数を追加。
    Version : 0.10.03
    Note    : 

--------------------------------------------------------*/

#define __SMPWIN_C__

/*--------------------
   組み込みファイル名
  --------------------*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif

#include <windows.h>
#include <windowsx.h>

#include "smpWin.h"

/*////////////////////////////////////////////////////////////////////////////*/
/**/
#define _smpWinKeyDown(ks,vk) (((ks)[vk]&0x80)!=0)

#define _smpWinHandle_WM_ENTERSIZEMOVE(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd)), 0L)

#define _smpWinHandle_WM_EXITSIZEMOVE(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd)), 0L)

#define _smpWinHandleButtonDown(hWnd, uMsg, wParam, lParam, fn) \
    ((fn)((hWnd), uMsg, FALSE, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam), (UINT)(wParam)), 0L)

#define _smpWinHandleButtonUp(hWnd, uMsg, wParam, lParam, fn) \
    ((fn)((hWnd), uMsg, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam), (UINT)(wParam)), 0L)

/**/
typedef
	struct{
		HWND				m_hWnd;	/* ウインドウハンドル */

		SMPWIN_IDLE_PROC	m_pIdleProc;
		SMPWIN_WIN_PROC		m_pWinProc;

		SMPWINEvent	m_event;
	}SMPWIN;

/**/
static SMPWIN *SmpWin = NULL;

/*////////////////////////////////////////////////////////////////////////////*/
/*------------------
   メモリを確保する
  ------------------*/
static SMPWIN *smpWinAllocate(void)
{
	SMPWIN *sw;
	sw = (SMPWIN*)malloc(sizeof(SMPWIN));

	sw->m_hWnd			= NULL;

	sw->m_pIdleProc		= NULL;
	sw->m_pWinProc		= NULL;

	{
		SMPWINEvent	*evt;
		evt = &sw->m_event;
		evt->m_type			= SMPWIN_TYPE_NONE;

		evt->m_winX			= 0;
		evt->m_winY			= 0;

		evt->m_width		= 0;
		evt->m_height		= 0;

		evt->m_mouseX		= 0;
		evt->m_mouseY		= 0;
		evt->m_mouseOldX	= 0;
		evt->m_mouseOldY	= 0;

		evt->m_state		= 0;
		evt->m_code			= 0;
	}
	return(sw);
}

/*------------------
   メモリを解放する
  ------------------*/
static void smpWinDispose(SMPWIN **sw)
{
	if(sw != NULL){
		if(*sw != NULL){
			free(*sw);
			*sw = NULL;
		}
	}
}

/*////////////////////////////////////////////////////////////////////////////*/

/*----------------------------------
   ウィンドウをアクティブにして表示
  ----------------------------------*/
int smpWinShowWindow(void)
{
	if(SmpWin == NULL) return(-1);
	return(ShowWindow(SmpWin->m_hWnd, SW_SHOWNORMAL));
}

/*------------------
   ウインドウの更新
  ------------------*/
int smpWinUpdateWindow(void)
{
	if(SmpWin == NULL) return(-1);
	return(UpdateWindow(SmpWin->m_hWnd));
}

/*------------------------
   メインループを終了する
  ------------------------*/
void smpWinMainLoopQuit(void)
{
	PostQuitMessage(0);
}

/*----------------------------
   SMPWINのメッセージ処理関数
  ----------------------------*/
static void smpWinProcEvent(const SMPWINEvent *evt)
{
	if(SmpWin->m_pWinProc != NULL){
		SmpWin->m_pWinProc(evt->m_type, (void*)evt);
	}
}

/*--------------------------
   ウインドウ削除のイベント
  --------------------------*/
static int smpWinOnDestroy(HWND hWnd)
{
	SMPWINEvent *evt;
	evt = &SmpWin->m_event;
	evt->m_type = SMPWIN_TYPE_DESTROY;
	/**/
	smpWinProcEvent(evt);
	return(0);
}

/*----------------------------------------
   キーボードフォーカスを得た時のイベント
  ----------------------------------------*/
static int smpWinOnFocusIn(HWND hWnd, HWND hWndOldFocus)
{
	{
		SMPWINEvent *evt;
		evt = &SmpWin->m_event;
		evt->m_type  = SMPWIN_TYPE_FOCUS_IN;
		/**/
		smpWinProcEvent(evt);
	}
	return(0);
}

/*------------------------------------------
   キーボードフォーカスを失った時のイベント
  ------------------------------------------*/
static int smpWinOnFocusOut(HWND hWnd, HWND hWndNewFocus)
{
	{
		SMPWINEvent *evt;
		evt = &SmpWin->m_event;
		evt->m_type  = SMPWIN_TYPE_FOCUS_OUT;
		/**/
		smpWinProcEvent(evt);
	}
	return(0);
}

/*-------------------------------------
   ウィンドウ移動のイベント
   引数
     x, y : クライアントの左上隅の座標
  -------------------------------------*/
#define _smpWinOnMove(type) \
	RECT rect; \
	int  wx, wy; \
	GetWindowRect(hWnd, &rect); \
	wx = rect.left; \
	wy = rect.top; \
	GetClientRect(hWnd, &rect); \
	{ \
		SMPWINEvent *evt; \
		evt = &SmpWin->m_event; \
		evt->m_type   = type; \
		evt->m_winX   = wx; \
		evt->m_winY   = wy; \
		evt->m_width  = rect.right - rect.left; \
		evt->m_height = rect.bottom - rect.top; \
		/**/ \
		smpWinProcEvent(evt); \
	} \
	return(0);

static int smpWinOnMove(HWND hWnd, int x, int y)
{
	_smpWinOnMove(SMPWIN_TYPE_MOVE);
}

/*-------------------------------------
   ウィンドウサイズ変更のイベント
   引数
     cx, cy : クライアント領域の大きさ
  -------------------------------------*/
static int smpWinOnSize(HWND hWnd, UINT state, int cx, int cy)
{
	RECT rect;
	GetWindowRect(hWnd, &rect);
	{
		SMPWINEvent *evt;
		evt = &SmpWin->m_event;
		evt->m_type   = SMPWIN_TYPE_SIZE;
		switch(state){
			case SIZE_RESTORED:  evt->m_state = SMPWIN_SIZE_RESTORED;  break;
			case SIZE_MINIMIZED: evt->m_state = SMPWIN_SIZE_MINIMIZED; break;
			case SIZE_MAXIMIZED: evt->m_state = SMPWIN_SIZE_MAXIMIZED; break;
			default:
				evt->m_state = -1;
				break;
		}
		evt->m_winX   = rect.left;
		evt->m_winY   = rect.top;
		evt->m_width  = cx;
		evt->m_height = cy;
		/**/
		smpWinProcEvent(evt);
	}
	return(0);
}

/*----------------------------------------------------------------------
   ウィンドウの移動又はサイズ変更の処理が開始したときに呼ばれるイベント
  ----------------------------------------------------------------------*/
static int smpWinOnEnterSizeMove(HWND hWnd)
{
	_smpWinOnMove(SMPWIN_TYPE_ENTERSIZEMOVE);
}

/*----------------------------------------------------------------------
   ウィンドウの移動又はサイズ変更の処理が終了したときに呼ばれるイベント
  ----------------------------------------------------------------------*/
static int smpWinOnExitSizeMove(HWND hWnd)
{
	_smpWinOnMove(SMPWIN_TYPE_EXITSIZEMOVE);
}

/*------------------
   キーの状態を返す
  ------------------*/
static UINT smpWinGetKeyState(const BYTE *ks)
{
	UINT state=0;
	/**/
	if(_smpWinKeyDown(ks, VK_SHIFT))	state |= SMPWIN_STATE_SHIFTKEY;
	if(_smpWinKeyDown(ks, VK_CONTROL))	state |= SMPWIN_STATE_CONTROLKEY;
	if(_smpWinKeyDown(ks, VK_MENU))		state |= SMPWIN_STATE_ALTKEY;
	/**/
	if(_smpWinKeyDown(ks, VK_LBUTTON))	state |= SMPWIN_STATE_LEFTBUTTON;
	if(_smpWinKeyDown(ks, VK_MBUTTON))	state |= SMPWIN_STATE_MIDDLEBUTTON;
	if(_smpWinKeyDown(ks, VK_RBUTTON))	state |= SMPWIN_STATE_RIGHTBUTTON;
	return(state);
}

/*--------------------
   キーのコードを返す
  --------------------*/
static WORD smpWinGetKeyCode(const BYTE *ks, UINT vk)
{
	WORD buf[2];
	int  result;
	/* 初期化 */
	buf[0] = buf[1] = 0;
	/**/
	result = ToAscii(vk, 0, ks, buf, 0);
	switch(result){
		case 0:
			switch(vk){
				case VK_F1:		return(SMPWIN_KEY_F1);
				case VK_F2:		return(SMPWIN_KEY_F2);
				case VK_F3:		return(SMPWIN_KEY_F3);
				case VK_F4:		return(SMPWIN_KEY_F4);
				case VK_F5:		return(SMPWIN_KEY_F5);
				case VK_F6:		return(SMPWIN_KEY_F6);
				case VK_F7:		return(SMPWIN_KEY_F7);
				case VK_F8:		return(SMPWIN_KEY_F8);
				case VK_F9:		return(SMPWIN_KEY_F9);
				case VK_F10:	return(SMPWIN_KEY_F10);
				case VK_F11:	return(SMPWIN_KEY_F11);
				case VK_F12:	return(SMPWIN_KEY_F12);
				case VK_LEFT:	return(SMPWIN_KEY_LEFT);
				case VK_RIGHT:	return(SMPWIN_KEY_RIGHT);
				case VK_UP:		return(SMPWIN_KEY_UP);
				case VK_DOWN:	return(SMPWIN_KEY_DOWN);
				default:
					break;
			}
			break;
		case 1:	return(buf[0]);
		case 2:
		default:
			break;
	}
	return(0);
}

/*----------------
   キーのイベント
  ----------------*/
static int smpWinOnKey(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
{
	POINT pt;
	UINT  state;
	WORD  code;
	/* スクリーン座標のカーソル位置を得る */
	GetCursorPos( &pt );
	/* スクリーン座標系からウインドウの座標系に変換 */
	ScreenToClient((HWND)hWnd, &pt);
	{
		BYTE ks[256];
		/* 仮想キーの状態得る */
		GetKeyboardState(ks);
		/* キーの状態を得る */
		state = smpWinGetKeyState(ks);
		/* キーのコードを得る */
		code = smpWinGetKeyCode(ks, vk);
	}
	{
		SMPWINEvent *evt;
		evt = &SmpWin->m_event;
		if(fDown == TRUE) evt->m_type = SMPWIN_TYPE_KEY_DOWN;
		else              evt->m_type = SMPWIN_TYPE_KEY_UP;
		evt->m_mouseX  = pt.x;
		evt->m_mouseY  = pt.y;
		evt->m_state   = state;
		evt->m_code    = code;
		/**/
		smpWinProcEvent(evt);
	}
	return(0);
}

/*--------------------------------
   マウスのボタンダウンのイベント
  --------------------------------*/
static int smpWinOnButtonDown(HWND hWnd, UINT uMsg, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
	SMPWINEvent *evt;
	evt = &SmpWin->m_event;
	switch(uMsg){
		case WM_LBUTTONDOWN: evt->m_type = SMPWIN_TYPE_LEFTBUTTON_DOWN;   break;
		case WM_MBUTTONDOWN: evt->m_type = SMPWIN_TYPE_MIDDLEBUTTON_DOWN; break;
		case WM_RBUTTONDOWN: evt->m_type = SMPWIN_TYPE_RIGHTBUTTON_DOWN;  break;
		default :            evt->m_type = SMPWIN_TYPE_NONE;              break;
	}
	if(evt->m_type != SMPWIN_TYPE_NONE){
		BYTE ks[256];
		UINT state;
		/**/
		SetCapture( hWnd );
		/* 仮想キーの状態得る */
		GetKeyboardState(ks);
		/* キーの状態を得る */
		state = smpWinGetKeyState(ks);
		evt->m_mouseX  = x;
		evt->m_mouseY  = y;
		evt->m_state   = state;
		/**/
		smpWinProcEvent(evt);
		/**/
		evt->m_mouseOldX = evt->m_mouseX;
		evt->m_mouseOldY = evt->m_mouseY;
	}
	return(0);
}

/*-----------------------------------------------------------------------------------
   マウスのボタンアップのイベント
   メモ
     smpWinOnButtonDown にまとめることもできるが今後のことを考えてこのままにしておく
  -----------------------------------------------------------------------------------*/
static int smpWinOnButtonUp(HWND hWnd, UINT uMsg, int x, int y, UINT keyFlags)
{
	SMPWINEvent *evt;
	evt = &SmpWin->m_event;
	switch(uMsg){
		case WM_LBUTTONUP: evt->m_type = SMPWIN_TYPE_LEFTBUTTON_UP;   break;
		case WM_MBUTTONUP: evt->m_type = SMPWIN_TYPE_MIDDLEBUTTON_UP; break;
		case WM_RBUTTONUP: evt->m_type = SMPWIN_TYPE_RIGHTBUTTON_UP;  break;
		default :          evt->m_type = SMPWIN_TYPE_NONE;            break;
	}
	if(evt->m_type != SMPWIN_TYPE_NONE){
		BYTE ks[256];
		UINT state;
		/**/
		ReleaseCapture();
		/* 仮想キーの状態得る */
		GetKeyboardState(ks);
		/* キーの状態を得る */
		state = smpWinGetKeyState(ks);
		evt->m_mouseX  = x;
		evt->m_mouseY  = y;
		evt->m_state   = state;
		/**/
		smpWinProcEvent(evt);
		/**/
		evt->m_mouseOldX = evt->m_mouseX;
		evt->m_mouseOldY = evt->m_mouseY;
	}
	return(0);
}

/*--------------------------
   マウスホイールのイベント
  --------------------------*/
static int smpWinOnMouseWheel(HWND hWnd, int xPos, int yPos, int zDelta, UINT fwKeys)
{
	POINT pt;
	BYTE ks[256];
	UINT state;
	pt.x = xPos;
	pt.y = yPos;
	/* スクリーン座標系からウインドウの座標系に変換 */
	ScreenToClient((HWND)hWnd, &pt);
	/* 仮想キーの状態得る */
	GetKeyboardState(ks);
	/* キーの状態を得る */
	state = smpWinGetKeyState(ks);
	{
		SMPWINEvent *evt;
		evt = &SmpWin->m_event;
		evt->m_type  = SMPWIN_TYPE_MOUSE_WHEEL;
		evt->m_mouseX  = pt.x;
		evt->m_mouseY  = pt.y;
		evt->m_code    = zDelta;
		evt->m_state   = state;
		/**/
		smpWinProcEvent(evt);
	}
	return(0);
}

/*------------------------
   マウスの移動のイベント
  ------------------------*/
static int smpWinOnMouseMove(HWND hWnd, int x, int y, UINT keyFlags)
{
	BYTE ks[256];
	UINT state;
	/* 仮想キーの状態得る */
	GetKeyboardState(ks);
	/* キーの状態を得る */
	state = smpWinGetKeyState(ks);
	{
		SMPWINEvent *evt;
		evt = &SmpWin->m_event;
		evt->m_type  = SMPWIN_TYPE_MOUSE_MOVE;
		evt->m_mouseX  = x;
		evt->m_mouseY  = y;
		evt->m_state = state;
		/**/
		smpWinProcEvent(evt);
		/**/
		evt->m_mouseOldX = evt->m_mouseX;
		evt->m_mouseOldY = evt->m_mouseY;
	}
	return(0);
}

/*--------------------------------
   ウインドウのメッセージ処理関数
  --------------------------------*/
static LRESULT CALLBACK smpWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
		case WM_DESTROY:		HANDLE_WM_DESTROY( hWnd, wParam, lParam, smpWinOnDestroy );
								smpWinMainLoopQuit();
								return(0);

		case WM_SETFOCUS:		return(HANDLE_WM_SETFOCUS(hWnd, wParam, lParam, smpWinOnFocusIn));
		case WM_KILLFOCUS:		return(HANDLE_WM_KILLFOCUS(hWnd, wParam, lParam, smpWinOnFocusOut));

		case WM_MOVE:			return(HANDLE_WM_MOVE(hWnd, wParam, lParam, smpWinOnMove));

		case WM_SIZE:			return(HANDLE_WM_SIZE(hWnd, wParam, lParam, smpWinOnSize));

		case WM_ENTERSIZEMOVE:	return(_smpWinHandle_WM_ENTERSIZEMOVE( hWnd, wParam, lParam, smpWinOnEnterSizeMove));
		case WM_EXITSIZEMOVE:	return(_smpWinHandle_WM_EXITSIZEMOVE( hWnd, wParam, lParam, smpWinOnExitSizeMove));

		case WM_KEYDOWN:		return(HANDLE_WM_KEYDOWN(hWnd, wParam, lParam, smpWinOnKey));
		case WM_KEYUP: 			return(HANDLE_WM_KEYUP(hWnd, wParam, lParam, smpWinOnKey));
		case WM_SYSKEYDOWN:		return(HANDLE_WM_KEYDOWN(hWnd, wParam, lParam, smpWinOnKey));
		case WM_SYSKEYUP: 		return(HANDLE_WM_KEYUP(hWnd, wParam, lParam, smpWinOnKey));

		case WM_LBUTTONDOWN: 	return(_smpWinHandleButtonDown(hWnd, uMsg, wParam, lParam, smpWinOnButtonDown));
		case WM_MBUTTONDOWN: 	return(_smpWinHandleButtonDown(hWnd, uMsg, wParam, lParam, smpWinOnButtonDown));
		case WM_RBUTTONDOWN: 	return(_smpWinHandleButtonDown(hWnd, uMsg, wParam, lParam, smpWinOnButtonDown));

		case WM_LBUTTONUP:		return(_smpWinHandleButtonUp(hWnd, uMsg, wParam, lParam, smpWinOnButtonUp));
		case WM_MBUTTONUP:		return(_smpWinHandleButtonUp(hWnd, uMsg, wParam, lParam, smpWinOnButtonUp));
		case WM_RBUTTONUP:		return(_smpWinHandleButtonUp(hWnd, uMsg, wParam, lParam, smpWinOnButtonUp));

		case WM_MOUSEWHEEL:		return(HANDLE_WM_MOUSEWHEEL(hWnd, wParam, lParam, smpWinOnMouseWheel));

		case WM_MOUSEMOVE:		return(HANDLE_WM_MOUSEMOVE(hWnd, wParam, lParam, smpWinOnMouseMove));

		default:
			break;
	}

	return(DefWindowProc(hWnd, uMsg, wParam, lParam));
}

/*--------------------
   イベント処理ループ
  --------------------*/
int smpWinMainLoop(void)
{
	if(SmpWin == NULL) return(FALSE);
	if(SmpWin->m_hWnd == NULL) return(FALSE);

	if(IsWindowVisible(SmpWin->m_hWnd) == FALSE){
		/* ウィンドウをアクティブにして表示 */
		smpWinShowWindow();
		/* ウインドウの更新 */
		smpWinUpdateWindow();
	}
	{
		MSG Msg;
		Msg.message = 0;
		while(Msg.message != WM_QUIT){
			if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)){
				TranslateMessage(&Msg);
				DispatchMessage(&Msg);
			}
#if 0 /* 2008.09.12(メッセージがメッセージキューに溜まってしまう不具合を修正) */
			if(SmpWin->m_pIdleProc != NULL){
				SmpWin->m_pIdleProc();
			}
#else
			else{
				if(SmpWin->m_pIdleProc != NULL){
					SmpWin->m_pIdleProc();
				}
			}
#endif
		}
	}
	return(TRUE);
}

/*--------------------------------
   メッセージ処理関数をセットする
  --------------------------------*/
int smpWinSetWinProc(SMPWIN_WIN_PROC winProc)
{
	if(SmpWin == NULL) return(FALSE);
	SmpWin->m_pWinProc = winProc;
	return(TRUE);
}

/*------------------------------
   アイドル処理関数をセットする
  ------------------------------*/
int smpWinSetIdleProc(SMPWIN_IDLE_PROC idleProc)
{
	if(SmpWin == NULL) return(FALSE);
	SmpWin->m_pIdleProc = idleProc;
	return(TRUE);
}

/*--------------------------
   ウインドウハンドルを返す
  --------------------------*/
void *smpWinGetWindowHandle(void)
{
	if(SmpWin == NULL) return(NULL);
	return(SmpWin->m_hWnd);
}

/*----------------------------------------------------------
   指定したクライアント領域にするためのウインドウ座標を返す
  ----------------------------------------------------------*/
static void smpWinAdjustWindow(DWORD dwStyle, int *pX, int *pY, int *pWidth, int *pHeight)
{
	RECT rc;
	rc.left   = *pX;
	rc.top    = *pY;
	rc.right  = rc.left + *pWidth;
	rc.bottom = rc.top  + *pHeight;
	AdjustWindowRectEx(&rc, dwStyle, FALSE, 0);
	if(rc.left < 0) *pX = 0;
	else            *pX = rc.left;
  	if(rc.top < 0)  *pY = 0;
	else            *pY = rc.top;
	*pWidth             = rc.right  - rc.left;
	*pHeight            = rc.bottom - rc.top;
}

/*-----------------------------------------------------------
   ウインドウを生成する
   引数
     title  : ウインドウのタイトルバーに表示されるタイトル名
     x      : ウインドウの左上端のＸ座標
     y      : ウインドウの左上端のＹ座標
     width  : ウインドウの幅
     height : ウインドウの高さ
  -----------------------------------------------------------*/
int smpWinCreateWindow(const char *title, int x, int y, int width, int height)
{
	if(SmpWin == NULL) return(FALSE);
	if(SmpWin->m_hWnd != NULL) return(FALSE);
	{
		WNDCLASSEX wc;
		if(!GetClassInfoEx(GetModuleHandle(NULL), "SMPWIN", &wc)) return(FALSE);
	}
	{
		DWORD dwStyle;
		/**/
		dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
		/**/
		smpWinAdjustWindow(dwStyle, &x, &y, &width, &height);
		/* ウインドウを生成する */
		SmpWin->m_hWnd = CreateWindow("SMPWIN", title, dwStyle, x, y, width, height, NULL, NULL, GetModuleHandle(NULL), NULL);
	}
	return(TRUE);
}

/*------
   終了
  ------*/
void smpWinEnd(void)
{
	if(SmpWin != NULL){
		if(SmpWin->m_hWnd != NULL){
			if(IsWindow(SmpWin->m_hWnd)){
				DestroyWindow(SmpWin->m_hWnd);
			}
		}
		smpWinDispose(&SmpWin);
	}
	/* ウインドウクラスの破棄 */
	UnregisterClass("SMPWIN", GetModuleHandle(NULL));
}

/*--------
   初期化
  --------*/
int smpWinInit(void)
{
	HINSTANCE  hInstance;
	WNDCLASSEX wc;

	if(SmpWin != NULL) return(FALSE);
	SmpWin = smpWinAllocate();

	hInstance = GetModuleHandle(NULL);
	/* ウインドウクラスの設定 */
	/* 初期化 */
	memset(&wc, 0, sizeof(WNDCLASSEX));
	wc.cbSize			= sizeof(wc);							/* 構造体のサイズ */
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	/* 水平方向と垂直方向のサイズ変更があったら再描画 */
																/* ウィンドウごとに独立したデバイスコンテキストを供給 */
	wc.lpfnWndProc		= smpWinProc;							/* メッセージ処理の関数 */
	wc.hInstance		= hInstance;							/* インスタンスの設定 */
	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);		/* アイコンの設定 */
	wc.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);		/* スモールアイコンの設定 */

	/*wc.hIcon=LoadIcon(hCurInst, MAKEINTRESOURCE(ID_MYICON));*/
	/*wc.hIconSm=LoadIcon(hCurInst, MAKEINTRESOURCE(ID_MYICON));*/

	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			/* カーソルの設定 */
	/*wc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);*/	/* 背景色の設定*/
	wc.lpszClassName	= "SMPWIN";								/* ウインドウクラス名の設定 */

	/* ウインドウクラスの登録 */
	RegisterClassEx(&wc);
	return(TRUE);
}
