///////////////////////////////////////
// MDIウィンドウクラスCMDI定義ファイル
///////////////////////////////////////

class CMDI : public CWND
{
protected:
	HANDLE	m_hMutex;
	char	m_UniqName[MAX_PATH];

public:		//メンバー変数
	HWND		m_hMDIClient;	//MDIクライエントのハンドル
	HWND		m_hFocusedChild;//フォーカスのあるMDI子ウィンドウのハンドル
	HWND		m_hDlg;			//IsDIalogMessage()使用時に使う
	MSG			m_Msg;			//ウィンドウメッセージ
	HACCEL		m_Accel;		//Acceleratorの有無

public:		//メンバー関数
	CMDI();		//CMDIのコンストラクター（１）
	CMDI(char*);		//CMDIのコンストラクター（２）
	~CMDI();
	bool CreateMDIClient(int);
	bool CreateMDIChild(LPCTSTR, LPCTSTR, int, int);
	HWND FocusedChild() {return m_hFocusedChild;}
	void MDIClientAutoSize(HWND, HWND);
	void MDIChildControlAutoSize(int, WPARAM, LPARAM);
	bool InclAccel(LPCTSTR);
	UINT Loop();
	virtual bool OnMDIFrameCreate(WPARAM, LPARAM);
	virtual bool OnMDIChildCreate(WPARAM, LPARAM);
	virtual bool OnMDIActivate(WPARAM, LPARAM);
	bool IsOnlyOne();			//２重起動防止関数
};

//CMDIのコンストラクター（１）
CMDI::CMDI() {

	m_hMDIClient = 0;
	m_UniqName[0] = 0;
}

//CMDIのコンストラクター（２）
CMDI::CMDI(char* UName) {

	m_hMDIClient = 0;
	wsprintf(m_UniqName, "%d", UName);
}

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

	if(m_hMutex)
		CloseHandle(m_hMutex);
}

//MDIClientウィンドウの作成
bool CMDI::CreateMDIClient(int WindowMenu) {

	//MDI子ウィンドウの情報を持つ構造体
	CLIENTCREATESTRUCT ccs;
	//MDI子ウィンドウが表示されるメニューハンドル
	ccs.hWindowMenu  = GetSubMenu(GetMenu(m_hWnd), WindowMenu);
	//OSが自動設定するMDI子ウィンドウの最初のハンドル（後は自動的に決まる）
	ccs.idFirstChild = ID_MDI_FIRSTCHILD;
	m_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "MDICLIENT", NULL,
					WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
					0, 0, 0, 0,
					m_hWnd, (HMENU)ID_MDI_CLIENT, m_hInstance, (LPVOID)&ccs);
	if (m_hMDIClient == NULL) {
		MessageBox(0, "MDIClientウィンドウを作成できませんでした", "エラー",
					MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
		return FALSE;
	}
	ShowWindow(m_hMDIClient, SW_SHOW);
	return TRUE;
}

//MDIChildの作成
bool CMDI::CreateMDIChild(LPCTSTR Class, LPCTSTR Name,
				int w = CW_USEDEFAULT, int h = CW_USEDEFAULT) {

	HWND hMDIChild = CreateMDIWindow(Class, Name, MDIS_ALLCHILDSTYLES,
								CW_USEDEFAULT, CW_USEDEFAULT, w, h,
								m_hMDIClient, m_hInstance, NULL);
	if(!hMDIChild) {
		MessageBox(m_hWnd, "MDI子ウィンドウを作れませんでした",
					"エラー", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}
	ShowWindow(hMDIChild, SW_SHOW);
	return TRUE;
}

//MDIClientのサイズをMDIFrameWindowに合わせる
void CMDI::MDIClientAutoSize(HWND hStatusBar = 0, HWND hToolBar = 0) {

	RECT rectFrameClient, rectStatus, rectTool;
	UINT uToolHeight, uStatusHeight, uClientAreaHeight;
	//MainFrameウィンドウのサイズを取得
	GetClientRect(m_hWnd, &rectFrameClient);
	uClientAreaHeight = rectFrameClient.bottom;
	//ツールバーの高さを取得
	if(hToolBar) {
		GetWindowRect(hToolBar, &rectTool);
		uToolHeight = rectTool.bottom - rectTool.top;
	}
	else
		uToolHeight = 0;
	//ステータスバーの高さを取得
	if(hStatusBar) {
		GetWindowRect(hStatusBar, &rectStatus);
		uStatusHeight = rectStatus.bottom - rectStatus.top;
	}
	else
		uStatusHeight = 0;
	//MDIClientのサイズをあわせる
	MoveWindow(m_hMDIClient, 0, uToolHeight, rectFrameClient.right, uClientAreaHeight - uStatusHeight - uToolHeight, TRUE);
}

//MDIChildのコントロールのサイズをMDIChildに合わせる
void CMDI::MDIChildControlAutoSize(int Item, WPARAM wParam, LPARAM lParam) {

	//最小化以外、コントロールをMDIChildのクライアントエリアに合わせる
	if(wParam != SIZE_MINIMIZED)
		//LOWORD(lParam)=幅, HIWORD(lParam)=高さ
		MoveWindow(GetDlgItem((HWND)SendMessage(m_hMDIClient, WM_MDIGETACTIVE, 0, 0), Item),
					0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
}

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

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

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

	while(GetMessage(&m_Msg, NULL, 0, 0) > 0) {	//エラーは-1が返る
		//モードレスダイアログがある場合
		if(!IsDialogMessage(m_hDlg, &m_Msg) &&
			//MDIのシステムメニューアクセラレータ処理
			!TranslateMDISysAccel(m_hMDIClient, &m_Msg) &&
			//アクセラレーター処理
			!TranslateAccelerator(m_hWnd, m_Accel, &m_Msg)) {
			TranslateMessage(&m_Msg);
			DispatchMessage(&m_Msg);
		}
	}
	return m_Msg.wParam;
}

////////////////////////////
// メッセージ対応関数(仮想）
////////////////////////////
//WM_CREATEメッセージ−親（MDIFrameWindow）と子（MDIChildWindow）で異なる
bool CMDI::OnMDIFrameCreate(WPARAM wParam, LPARAM lParam) {
	return TRUE;	//エラーの場合はFALSEにするとウィンドウが作られず、終了する
}

bool CMDI::OnMDIChildCreate(WPARAM wParam, LPARAM lParam) {
	return TRUE;	//エラーの場合はFALSEにするとウィンドウが作られず、終了する
}

bool CMDI::OnMDIActivate(WPARAM wParam, LPARAM lParam) {
	return TRUE;
}

bool CMDI::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;
}
