///////////////////////////////////////////
//簡易Win32SDK利用ライブラリー−BCCSkelton
///////////////////////////////////////////
#define		STRICT
#include	<windows.h>
#include	<windowsx.h>
#include	<commctrl.h>
#include	<shlobj.h>

//ウィンドウ用定数
#define	TOOLBAR				3000			//ツールバーのID
#define	STATUSBAR			3001			//ステータスバーのID
#define	ID_MDI_CLIENT		4000			//MDIClientのID
#define	ID_MDI_FIRSTCHILD	5000			//MDI子ウィンドウの最初のID

#include	".\BCCSkelton\CSTR.h"
#include	".\BCCSkelton\CANVAS.h"
#include	".\BCCSkelton\CBMP.h"
#include	".\BCCSkelton\CFONT.h"
#include	".\BCCSkelton\CMNDLG.h"
#include	".\BCCSkelton\CFILE.h"
#include	".\BCCSkelton\CWND.h"
#include	".\BCCSkelton\CSDI.h"
#include	".\BCCSkelton\CMDI.h"
#include	".\BCCSkelton\CDLG.h"
#include	".\BCCSkelton\CCTRL.h"
#include	".\BCCSkelton\CTBAR.h"
#include	".\BCCSkelton\CSBAR.h"
#include	".\BCCSkelton\CRBAR.h"
#include	".\BCCSkelton\CREDIT.h"
#include	".\BCCSkelton\CTHREAD.h"
#include	".\BCCSkelton\CPICBOX.h"
#include	".\BCCSkelton\CIMGLIST.h"
#include	".\BCCSkelton\CINI.h"
#include	".\BCCSkelton\CARG.h"
#include	".\BCCSkelton\CTIMER.h"
#include	".\BCCSkelton\CTAB.h"
#include	".\BCCSkelton\CTREEVIEW.h"
#include	".\BCCSkelton\CLISTVIEW.h"
#include	".\BCCSkelton\CCMDEDIT.h"
#include	".\BCCSkelton\CHISTORY.h"
#include	".\BCCSkelton\CLISTBOX.h"
//#include	".\BCCSkelton\CVOICE.h"
#include	".\BCCSkelton\CCLIPBOARD.h"
#include	".\BCCSkelton\CEXTCHK.h"
#include	".\BCCSkelton\CTTIP.h"

/////////////////////////////////
//ウィンドウコールバック関数マクロ
/////////////////////////////////
//SDIウィンドウ用（一つだけしか作れない）
#define	SDIPROC	SDIWndProc

#define	BEGIN_SDIMSG(_P_)	LRESULT CALLBACK SDIWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
	bool Done = FALSE;\
	if(Msg == WM_CREATE) {\
		_P_.SetHandle(hWnd);\
		_P_.SetInstance((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE));\
	}\

//SDIメッセージループの終了用マクロ・書式＝END_WNDMSGのみ
#define	END_WNDMSG	if(Msg == WM_DESTROY) {Done = TRUE;	PostQuitMessage(0);}\
	if(Done)	return 0L;\
	else	return DefWindowProc(hWnd, Msg, wParam, lParam);\
}\

//MDIウィンドウ用（一つだけしか作れない）
#define	MDIPROC	MDIWndProc
#define	MDICHILDPROC	MDIChildWndProc

#define	BEGIN_MDIMSG(_P_)	LRESULT CALLBACK MDIWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
	bool Done = FALSE;\
	if(Msg == WM_CREATE) {\
		_P_.SetHandle(hWnd);\
		_P_.SetInstance((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE));\
		if(!(_P_.OnMDIFrameCreate(wParam, lParam)))\
			return -1;\
	}\

#define	BEGIN_MDICHILDMSG(_P_)	LRESULT CALLBACK MDIChildWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
	bool Done = FALSE;\
	_P_.m_hFocusedChild = hWnd;\
	if(Msg == WM_CREATE) {\
		if(_P_.OnMDIChildCreate(wParam, lParam));\
		else	return -1;\
	}\
	if(Msg == WM_MDIACTIVATE) {\
		if(_P_.OnMDIActivate(wParam, lParam))\
			Done = TRUE;\
	}\

//MDI親メッセージループの終了用マクロ・書式＝END_MDIMSG(引数)
#define	END_MDIMSG(_P_)	if(Msg == WM_DESTROY) {\
		Done = TRUE;\
		PostQuitMessage(0);\
	}\
	if(Msg == WM_COMMAND && !Done) {\
		HWND hMDIChild = (HWND)SendMessage(_P_.m_hMDIClient, WM_MDIGETACTIVE, 0, 0);\
		if(hMDIChild)\
			SendMessage(hMDIChild, WM_COMMAND, wParam, lParam);\
	}\
	if(Msg == WM_COMMAND || Msg == WM_MENUCHAR || Msg == WM_SETFOCUS)\
		{Done = FALSE;}\
	if(Done)	return 0L;\
	else	return DefFrameProc(hWnd, _P_.m_hMDIClient, Msg, wParam, lParam);\
}\

//MDI子メッセージループの終了用マクロ・書式＝END_MDICHILDMSG
#define	END_MDICHILDMSG	if(Msg == WM_CHILDACTIVATE || Msg == WM_GETMINMAXINFO || Msg == WM_MENUCHAR || Msg == WM_MOVE || Msg == WM_SETFOCUS || Msg == WM_SIZE)\
	{Done = FALSE;}\
	if(Done)	return 0L;\
	else	return DefMDIChildProc(hWnd, Msg, wParam, lParam);\
}\

///////////////////////////////////
//ダイアログコールバック関数マクロ
///////////////////////////////////
//モーダルダイアログ書式＝BEGIN_MODALDLGMSG(CDLG変数)
//又MODALDLGPROC(CDLG変数)がコールバック関数
#define	BEGIN_MODALDLGMSG(_PROC_, _P_)	BOOL CALLBACK _PROC_(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
	bool Done = FALSE;\
	if(Msg == WM_INITDIALOG) {_P_.SetHandle(hWnd);	Done = (_P_.OnInit(wParam, lParam));}\
	if(Msg == WM_SYSCOMMAND && wParam == SC_CLOSE) {SendMessage(hWnd, WM_CLOSE, 0, 0);	Done = TRUE;}\
	if(Msg == WM_NOTIFY) Done = _P_.OnNotify(wParam, lParam);\
	if(Msg == WM_CLOSE) if((Done = _P_.OnClose(wParam, lParam))) _P_.EndModal(Done);\

//モードレスダイアログ書式＝BEGIN_MODELESSDLGMSG(CDLG変数)
//又MODELESSDLGPROC(CDLG変数)がコールバック関数
#define	BEGIN_MODELESSDLGMSG(_PROC_, _P_)	BOOL CALLBACK _PROC_(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
	bool Done = FALSE;\
	if(Msg == WM_INITDIALOG) {_P_.SetHandle(hWnd);	Done = (_P_.OnInit(wParam, lParam));}\
	if(Msg == WM_NOTIFY) Done = _P_.OnNotify(wParam, lParam);\
	if(Msg == WM_CLOSE) if((Done = _P_.OnClose(wParam, lParam)))	_P_.Destroy();\

//共通のメッセージテーブル終了マクロ書式＝END_DLGMSG
#define	END_DLGMSG	return Done;\
}\

//主要なウィンドウ・ダイアログメッセージ用マクロ
#define	ON_CREATE(_P_)	if(Msg == WM_CREATE) {if((Done = _P_.OnCreate(wParam, lParam)));	else	return -1;}
#define	ON_ACTIVATE(_P_)	if(Msg == WM_ACTIVATE)	Done = _P_.OnActivate(wParam, lParam);
#define	ON_ENABLE(_P_)	if(Msg == WM_ENABLE)	Done = _P_.OnEnable(wParam, lParam);
#define	ON_TIMER(_P_)	if(Msg == WM_TIMER)	Done = _P_.OnTimer(wParam, lParam);
#define	ON_SETFOCUS(_P_)	if(Msg == WM_SETFOCUS)	Done = _P_.OnSetFocus(wParam, lParam);
#define	ON_CHAR(_P_)	if(Msg == WM_CHAR)	Done = _P_.OnChar(wParam, lParam);
#define	ON_KEYUP(_P_)	if(Msg == WM_KEYUP)	Done = _P_.OnKeyUp(wParam, lParam);
#define	ON_KEYDOWN(_P_)	if(Msg == WM_KEYDOWN)	Done = _P_.OnKeyDown(wParam, lParam);
#define	ON_LBUTTONDOWN(_P_)	if(Msg == WM_LBUTTONDOWN)	Done = _P_.OnLButtonDown(wParam, lParam);
#define	ON_LBUTTONUP(_P_)	if(Msg == WM_LBUTTONUP)	Done = _P_.OnLButtonUp(wParam, lParam);
#define	ON_LBUTTONDBLCLK(_P_)	if(Msg == WM_LBUTTONDBLCLK)	Done = _P_.OnLButtonDblClk(wParam, lParam);
#define	ON_MBUTTONDOWN(_P_)	if(Msg == WM_MBUTTONDOWN)	Done = _P_.OnMButtonDown(wParam, lParam);
#define	ON_MBUTTONUP(_P_)	if(Msg == WM_MBUTTONUP)	Done = _P_.OnMButtonUp(wParam, lParam);
#define	ON_MBUTTONDBLCLK(_P_)	if(Msg == WM_MBUTTONDBLCLK)	Done = _P_.OnMButtonDblClk(wParam, lParam);
#define	ON_RBUTTONDOWN(_P_)	if(Msg == WM_RBUTTONDOWN)	Done = _P_.OnRButtonDown(wParam, lParam);
#define	ON_RBUTTONUP(_P_)	if(Msg == WM_RBUTTONUP)	Done = _P_.OnRButtonUp(wParam, lParam);
#define	ON_RBUTTONDBLCLK(_P_)	if(Msg == WM_RBUTTONDBLCLK)	Done = _P_.OnRButtonDblClk(wParam, lParam);
#define	ON_MOUSEMOVE(_P_)	if(Msg == WM_MOUSEMOVE)	Done = _P_.OnMouseMove(wParam, lParam);
#define	ON_NOTIFY(_P_)	if(Msg == WM_NOTIFY)	Done = _P_.OnNotify(wParam, lParam);
#define	ON_SIZE(_P_)	if(Msg == WM_SIZE)	Done = _P_.OnSize(wParam, lParam);
#define	ON_MDIFRAMESIZE(_P_)	if(Msg == WM_SIZE)	Done = _P_.OnMDIFrameSize(wParam, lParam);
#define	ON_MDICHILDSIZE(_P_)	if(Msg == WM_SIZE)	_P_.OnMDIChildSize(wParam, lParam);
#define	ON_MOVE(_P_)	if(Msg == WM_MOVE)	Done = _P_.OnMove(wParam, lParam);
#define	ON_HSCROLL(_P_)	if(Msg == WM_HSCROLL)	Done = _P_.OnHScroll(wParam, lParam);
#define	ON_VSCROLL(_P_)	if(Msg == WM_VSCROLL)	Done = _P_.OnVScroll(wParam, lParam);
#define	ON_PAINT(_P_)	if(Msg == WM_PAINT)	Done = _P_.OnPaint(wParam, lParam);
#define	ON_ERASEBKGND(_P_)	if(Msg == WM_ERASEBKGND)	Done = _P_.OnEraseBkgnd(wParam, lParam);
#define	ON_CLOSE(_P_)	if(Msg == WM_CLOSE) {if((Done = _P_.OnClose(wParam, lParam))) DestroyWindow(hWnd);	else return 0L;}
#define	ON_DESTROY(_P_)	if(Msg == WM_DESTROY) Done = _P_.OnDestroy(wParam, lParam);
//WM_COMMANDメッセージ用マクロ・書式＝ON_COMMAND(CWND変数, コントロールID, 派生の際に定義する関数名(括弧、引数付)
#define	ON_COMMAND(_P_, _ID_, _PROC_)	if(Msg == WM_COMMAND && LOWORD(wParam) == _ID_)	Done = (_P_._PROC_);
//その他メッセージ用マクロ・書式＝ON_(CWND変数, メッセージ, 派生の際に定義する関数名(括弧、引数付)
#define	ON_(_P_, _MSG_, _PROC_)	if(Msg == _MSG_)	Done = (_P_._PROC_);
