//////////////////////////////////////
//  CDLGクラスヘッダー（定義ファイル）
//////////////////////////////////////

class CDLG
{
protected:
	HANDLE	m_hMutex;
	char	m_UniqName[MAX_PATH];

public:	//メンバー変数
	HWND		m_hWnd;				//本ダイアログのハンドル
	HWND		m_hParent;			//親のハンドル
	HINSTANCE	m_hInstance;		//親のインスタンス
	HACCEL		m_Accel;			//Acceleratorの有無
	MSG			m_Msg;				//ウィンドウメッセージ

public:	//メンバー関数
	CDLG();									//デフォールトコンストラクター
	CDLG(char*);							//UniqueName付コンストラクター
	~CDLG();								//デストラクター
	HWND GetHandle() {return m_hWnd;}		//ダイアログハンドルを返す
	void SetHandle(HWND h) {m_hWnd = h;}	//モダルダイアログのハンドル設定
	HINSTANCE GetInstance() {return m_hInstance;}	//インスタンスを返す
	void SetInstance(HINSTANCE hInst) {m_hInstance = hInst;}	//インスタンス設定
	int DoModal(HWND, LPCTSTR, DLGPROC,
				HINSTANCE);					//モーダルダイアログを開く
	bool EndModal(int);						//モーダルダイアログを閉める
	bool Create(HWND, LPCTSTR, DLGPROC);	//モードレスダイアログを開く（親のインスタンス）
	bool Create(HWND, HINSTANCE, LPCTSTR,
					DLGPROC);				//モードレスダイアログを開く
	bool Destroy();							//モードレスダイアログを閉める
	bool IsCDLGMsg(MSG*);					//IsDialogMessage関数のCDLG版
	LRESULT SendMsg(UINT, WPARAM, LPARAM);	//ダイアログへのメッセージ
	LRESULT SendItemMsg(int, UINT,
						WPARAM, LPARAM);	//ダイアログコントロールへのメッセージ
	virtual	bool OnInit(WPARAM, LPARAM);	//WM_INITDIALOG
	virtual	bool OnNotify(WPARAM, LPARAM);	//WM_NOTIFY
	virtual	bool OnClose(WPARAM, LPARAM);	//WM_CLOSE
	bool InclAccel(LPCTSTR);				//Modeless Dialog用アクセラレーターロード関数
	UINT Loop();							//Modeless Dialog用メッセージループ
	bool IsOnlyOne();						//２重起動防止関数
};

//デフォールトコンストラクター
CDLG::CDLG() {
	m_hWnd = m_hParent = 0;
	m_Accel = 0;
	*m_UniqName = NULL;
}

//UniqueName付コンストラクター
CDLG::CDLG(char* UName) {
	m_hWnd = m_hParent = 0;
	m_Accel = 0;
	wsprintf(m_UniqName, "%d", UName);
}

//デストラクター
CDLG::~CDLG() {

	if(m_hMutex)
		CloseHandle(m_hMutex);
}

//モーダルダイアログを開く
int CDLG::DoModal(HWND hParent, LPCTSTR DlgName, DLGPROC Proc,
				  HINSTANCE hInstance = 0) {

	if(m_hWnd) 	return FALSE;
	//親ウィンドウのハンドルを記録
	m_hParent = hParent;
	//親ウィンドウのインスタンスを取得して記録
	if(hInstance)
		m_hInstance = hInstance;	
	else
		m_hInstance = (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE);
	//ダイアログを開く
	int ret = DialogBox(m_hInstance, DlgName, hParent, Proc);
	if(ret == -1)
		return FALSE;
	return ret;
}

//モーダルダイアログを閉める
bool CDLG::EndModal(int i) {

	EndDialog(m_hWnd, i);
	m_hWnd = 0;		//未使用状態にする
	return TRUE;
}

//モードレスダイアログを開く（親のインスタンス）
bool CDLG::Create(HWND hParent, LPCTSTR DlgName, DLGPROC Proc) {

	if(m_hWnd)	return FALSE;
	//親ウィンドウのハンドルを記録
	m_hParent = hParent;
	//インスタンスを取得して記録
	m_hInstance = (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE);
	//ダイアログを開く
	m_hWnd = CreateDialog(m_hInstance, DlgName, m_hParent, Proc);
	if(!m_hWnd)
		return FALSE;
	ShowWindow(m_hWnd, SW_SHOWNORMAL);
	UpdateWindow(m_hWnd);
	return TRUE;
	//この後メッセージループへメッセージが来るので、本体プログラムの
	//メッセージループにif(!IsDialogMessage(hDlg, &Msg))を入れる
}

//モードレスダイアログを開く
bool CDLG::Create(HWND hParent, HINSTANCE hInstance, LPCTSTR DlgName, DLGPROC Proc) {

	if(m_hWnd)	return FALSE;
	//親ウィンドウのハンドルを記録
	m_hParent = hParent;
	//インスタンスを取得して記録
	m_hInstance = hInstance;
	//ダイアログを開く
	m_hWnd = CreateDialog(m_hInstance, DlgName, m_hParent, Proc);
	if(!m_hWnd)
		return FALSE;
	ShowWindow(m_hWnd, SW_SHOWNORMAL);
	UpdateWindow(m_hWnd);
	return TRUE;
	//この後メッセージループへメッセージが来るので、本体プログラムの
	//メッセージループにif(!IsDialogMessage(hDlg, &Msg))を入れる
}

//モードレスダイアログを閉める
bool CDLG::Destroy() {

	DestroyWindow(m_hWnd);
	m_hWnd = 0;		//未使用状態にする
	return TRUE;
}

//IsDialogMessage関数のCDLG版
bool CDLG::IsCDLGMsg(MSG* msg) {

	return IsDialogMessage(m_hWnd, msg);
}

//SendDlgItemMessage関数のCDLG版
LRESULT CDLG::SendMsg(UINT Msg, WPARAM wParam, LPARAM lParam) {

	return SendMessage(m_hWnd, Msg, wParam, lParam);
}

//SendDlgItemMessage関数のCDLG版
LRESULT CDLG::SendItemMsg(int ID, UINT Msg, WPARAM wParam, LPARAM lParam) {

	return SendDlgItemMessage(m_hWnd, ID, Msg, wParam, lParam);
}

//WM_INITDIALOG時処理（仮想関数）
bool CDLG::OnInit(WPARAM, LPARAM) {
	return TRUE;
}

//WM_NOTIFY時処理（仮想関数）
bool CDLG::OnNotify(WPARAM, LPARAM) {
	return TRUE;
}

//WM_CLOSE時処理(仮想関数）
bool CDLG::OnClose(WPARAM, LPARAM) {
	return TRUE;
}

//アクセラレーター
bool CDLG::InclAccel(LPCTSTR Name) {

	if(!(m_Accel = LoadAccelerators(m_hInstance, Name))) {
		MessageBox(NULL, "アクセラレーターの読込に失敗しました",
					"エラー", MB_OK);
		return FALSE;
	}
	return TRUE;
}

//メッセージループ
UINT CDLG::Loop() {

	while(GetMessage(&m_Msg, NULL, 0, 0) > 0) {	//エラーは-1が返る
		if(!TranslateAccelerator(m_hWnd, m_Accel, &m_Msg) &&
		!IsDialogMessage(m_hWnd, &m_Msg)) {
			TranslateMessage(&m_Msg);
			DispatchMessage(&m_Msg);
		}
	}
	return m_Msg.wParam;
}

bool CDLG::IsOnlyOne() {

	m_hMutex = CreateMutex(NULL, TRUE, m_UniqName);
	if (!m_hMutex) 	return FALSE;
	// もしGetLastError()が、ERROR_ALREADY_EXISTSなら、
	// すでにアプリケーションが起動している
	if (GetLastError() == ERROR_ALREADY_EXISTS) {
    //二重起動時の処理
    	return FALSE;
	}
	return TRUE;
}
