// mywin.cpp

#include "resource.h"
#include "mywin.h"

namespace mylib
{

HINSTANCE
CMyWin::m_hInstance;

TCHAR
CMyWin::m_szClassName[(CMyWin::MAX_LOAD_STRING+1)];

BOOL
CMyWin::Register(HINSTANCE hInstance)
{
	if(hInstance == 0)
		return FALSE;	// Invalid instance
	if(m_hInstance)
		return FALSE;	// Already called

	// Load the strings
	int nChar;
	nChar = LoadString(hInstance, IDS_MY_WINCLASS,
			m_szClassName, MAX_LOAD_STRING);
	m_szClassName[nChar] = 0;

	// Register the Window Class
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = sizeof(LONG_PTR);
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(0, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = 0;
	wcex.lpszClassName = m_szClassName;
	wcex.hIconSm = LoadIcon(0, IDI_APPLICATION);
	RegisterClassEx(&wcex);
	m_hInstance = hInstance;
	return TRUE;
}

LRESULT CALLBACK 
CMyWin::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	BOOL bDone = FALSE;
	short si;
	short sx;
	short sy;

	if(message == WM_CREATE)
	{
		// Associate the object to the window
		CREATESTRUCT* pcs = (CREATESTRUCT*)lParam;
		CMyWin* pObj = (CMyWin*)pcs->lpCreateParams;
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pObj);
		if(pObj)
			bDone = pObj->OnCreate();
	}
	else
	{
		CMyWin* pObj = (CMyWin*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
		switch(message)
		{
		case WM_PAINT:
			bDone = pObj->OnPaint();
			break;
		case WM_DESTROY:
			bDone = pObj->OnDestroy();
			break;
		case WM_SIZE:
			bDone = pObj->OnSize((UINT)wParam,
				(int)LOWORD(lParam), (int)HIWORD(lParam));
			break;
		case WM_HSCROLL:
			si = (short)HIWORD(wParam);
			bDone = pObj->OnHScroll((int)LOWORD(wParam),
				(int)si, (HWND)lParam);
			break;
		case WM_VSCROLL:
			si = (short)HIWORD(wParam);
			bDone = pObj->OnVScroll((int)LOWORD(wParam),
				(int)si, (HWND)lParam);
			break;
		case WM_MOUSEWHEEL:
			si = (short)HIWORD(wParam);
			sx = (short)LOWORD(lParam);
			sy = (short)HIWORD(lParam);
			bDone = pObj->OnMouseWheel((int)LOWORD(wParam),
				(int)si, (int)sx, (int)sy);
			break;
		default:
			break;
		}
	}
	if(!bDone)
		return DefWindowProc(hWnd, message, wParam, lParam);
	return 0;
}

CMyWin::CMyWin()
{
	m_hWnd = 0;
}

CMyWin::~CMyWin()
{
}

BOOL
CMyWin::OnCreate()
{
	return FALSE;
}

BOOL
CMyWin::OnDestroy()
{
	return FALSE;
}

BOOL
CMyWin::OnPaint()
{
	return FALSE;
}

BOOL
CMyWin::OnSize(UINT nType, int cx, int cy)
{
	return FALSE;
}

BOOL
CMyWin::OnHScroll(int nScrollCode, int nPos, HWND hwndScrollBar)
{
	return FALSE;
}

BOOL
CMyWin::OnVScroll(int nScrollCode, int nPos, HWND hwndScrollBar)
{
	return FALSE;
}

BOOL
CMyWin::OnMouseWheel(int fwKeys, int zDelta, int xPos, int yPos)
{
	return FALSE;
}

BOOL
CMyWin::Create(LPCTSTR szTitle, DWORD dwStyle,
	int x, int y, int nWidth, int nHeight,
	HWND hWndParent, HMENU hMenu)
{
	if(m_hWnd != 0)
		return FALSE;	// Already Createted
	m_hWnd = ::CreateWindow(m_szClassName, szTitle, dwStyle,
			x, y, nWidth, nHeight, hWndParent, hMenu,
			m_hInstance, this);
	if(m_hWnd == 0)
		return FALSE;
	return TRUE;
}

BOOL
CMyWin::Destroy()
{
	return ::DestroyWindow(m_hWnd);
}

BOOL
CMyWin::Show(int nCmdShow)
{
	return ::ShowWindow(m_hWnd, nCmdShow);
}

BOOL
CMyWin::Update()
{
	return ::UpdateWindow(m_hWnd);
}

HDC
CMyWin::GetDC()
{
	return ::GetDC(m_hWnd);
}

int
CMyWin::ReleaseDC(HDC hdc)
{
	return ::ReleaseDC(m_hWnd, hdc);
}

HDC
CMyWin::BeginPaint(PAINTSTRUCT* lpPaint)
{
	return ::BeginPaint(m_hWnd, lpPaint);
}

BOOL
CMyWin::EndPaint(const PAINTSTRUCT* lpPaint)
{
	return ::EndPaint(m_hWnd, lpPaint);
}

BOOL
CMyWin::GetClientRect(LPRECT lpRect)
{
	return ::GetClientRect(m_hWnd, lpRect);
}

BOOL
CMyWin::GetWindowRect(LPRECT lpRect)
{
	return ::GetWindowRect(m_hWnd, lpRect);
}

}	// namespace mylib
