//////////////////////////////////////////
// BCFEditorProc.h
// Copyright (c) 06/23/2002 by BCCSkelton
//////////////////////////////////////////
//☆元々は空であった関数に、以下のように処理を記述します。

/////////////////////////////////
//主ウィンドウCMyWndの関数の定義
//ウィンドウメッセージ関数
/////////////////////////////////
bool CMyWnd::OnMDIFrameCreate(WPARAM wParam, LPARAM lParam) {

	//コモンコントロールの初期化
	InitCommonControls();

	//ツールバー登録−Init(hWnd, hIinstance, ID, Style)−ツールチップを付ける
	TBar.Init(m_hWnd, m_hInstance, TOOLBAR, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS);
	//ツールバーボタン用ビットマップ追加
	TBar.AddBmp();
	//ツールバーボタン追加
	//☆ボタン数を増やすときはマニュアルになります。
	TBBUTTON tbb[24];
	ZeroMemory(tbb, sizeof(tbb));
	tbb[0].iBitmap = STD_FILENEW;
	tbb[0].fsState = TBSTATE_ENABLED;
	tbb[0].fsStyle = TBSTYLE_BUTTON;
	tbb[0].idCommand = IDM_NEW;
	tbb[1].iBitmap = STD_FILEOPEN;
	tbb[1].fsState = TBSTATE_ENABLED;
	tbb[1].fsStyle = TBSTYLE_BUTTON;
	tbb[1].idCommand = IDM_OPEN;
	tbb[2].iBitmap = STD_FILESAVE;
	tbb[2].fsStyle = TBSTYLE_BUTTON;
	tbb[2].idCommand = IDM_SAVE;
	tbb[3].iBitmap = STD_PROPERTIES;
	tbb[3].fsState = TBSTATE_ENABLED;
	tbb[3].fsStyle = TBSTYLE_BUTTON;
	tbb[3].idCommand = IDM_SETPRINT;
	tbb[4].iBitmap = STD_PRINT;
	tbb[4].fsStyle = TBSTYLE_BUTTON;
	tbb[4].idCommand = IDM_PRINT;
	tbb[5].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[6].iBitmap = STD_UNDO;
	tbb[6].fsStyle = TBSTYLE_BUTTON;
	tbb[6].idCommand = IDM_UNDO;
	tbb[7].iBitmap = STD_REDOW;
	tbb[7].fsStyle = TBSTYLE_BUTTON;
	tbb[7].idCommand = IDM_REDO;
	tbb[8].iBitmap = STD_CUT;
	tbb[8].fsStyle = TBSTYLE_BUTTON;
	tbb[8].idCommand = IDM_CUT;
	tbb[9].iBitmap = STD_COPY;
	tbb[9].fsStyle = TBSTYLE_BUTTON;
	tbb[9].idCommand = IDM_COPY;
	tbb[10].iBitmap = STD_PASTE;
	tbb[10].fsStyle = TBSTYLE_BUTTON;
	tbb[10].idCommand = IDM_PASTE;
	tbb[11].iBitmap = STD_FIND;
	tbb[11].fsStyle = TBSTYLE_BUTTON;
	tbb[11].idCommand = IDM_FIND;
	tbb[12].iBitmap = STD_REPLACE;
	tbb[12].fsStyle = TBSTYLE_BUTTON;
	tbb[12].idCommand = IDM_REPLACE;
	tbb[13].fsStyle = TBSTYLE_SEP; 	//セパレーター

	//☆カスタムビットマップは以下のように追加します。
	//カスタムビットマップの追加
	TBar.AddBmp(m_hInstance, "IDB_CUSTOM", 8);

	tbb[14].iBitmap = TBar.m_id;
	tbb[14].fsStyle = TBSTYLE_BUTTON;
	tbb[14].idCommand = IDM_JUMP;
	tbb[15].iBitmap = TBar.m_id + 1;
	tbb[15].fsStyle = TBSTYLE_BUTTON;
	tbb[15].idCommand = IDM_DIALOGON;
	tbb[16].iBitmap = TBar.m_id + 2;
	tbb[16].fsStyle = TBSTYLE_BUTTON;
	tbb[16].idCommand = IDM_DIALOGOFF;
	tbb[17].iBitmap = TBar.m_id + 3;
	tbb[17].fsStyle = TBSTYLE_BUTTON;
	tbb[17].idCommand = IDM_SET;
	tbb[18].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[19].iBitmap = TBar.m_id + 4;
	tbb[19].fsStyle = TBSTYLE_BUTTON;
	tbb[19].idCommand = IDM_SKELTON;
	tbb[20].iBitmap = TBar.m_id + 5;
	tbb[20].fsStyle = TBSTYLE_BUTTON;
	tbb[20].idCommand = IDM_MAKE;
	tbb[21].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[22].iBitmap = TBar.m_id + 6;
	tbb[22].fsState = TBSTATE_ENABLED;
	tbb[22].fsStyle = TBSTYLE_BUTTON;
	tbb[22].idCommand = IDM_BCCSKELTON;
	tbb[23].iBitmap = TBar.m_id + 7;
	tbb[23].fsState = TBSTATE_ENABLED;
	tbb[23].fsStyle = TBSTYLE_BUTTON;
	tbb[23].idCommand = IDM_VER;
	TBar.AddButtons(24, tbb);

	//ステータスバー登録−Init(hWnd, hIinstance, ID, (以下省略可）Style)
	SBar.Init(m_hWnd, m_hInstance, STATUSBAR);
	//ステータスバー区画設定
	int sec[4] = {120, 210, 330, -1};
	SBar.SetSection(4, sec);
	//ステータスバー文字列設定
	SBar.SetText(0, "BCFEditor Version 2.1");

	//MDIClientを作成−CreateMDIClient関数（引数は子ウィンドウ情報を表示するサブメニュー）
	//☆4番目のサブメニューにMDI子ウィンドウ情報を表示します
	CreateMDIClient(3);

	//MDIフレームウィンドウのドラッグアンドドロップを許可する
	DragAcceptFiles(m_hWnd, TRUE);

	//BCFEditor.iniファイル読み込み（不能の場合、フォント、タブ、色は初期値設定）
	CSTR fn = arg.Path();
	fn = fn + "\\BCFEditor.ini";
	ini.SetName(fn.ToChar());
	lstrcpy(g_BCCMaker, ini.ReadStr("System", "BCCMaker"));
	if(!lstrcmp(g_BCCMaker, "Not Found"))
		MessageBox(m_hWnd, "BCCMakerのパスを読み込めませんでした。\nメニューの「編集−設定」で設定してください。",
				"読込不能報告", MB_OK | MB_ICONEXCLAMATION);
	lstrcpy(g_SkeltonWizard, ini.ReadStr("System", "SkeltonWizard"));
	if(!lstrcmp(g_SkeltonWizard, "Not Found"))
		MessageBox(m_hWnd, "SkeltonWizardのパスを読み込めませんでした。\nメニューの「編集−設定」で設定してください。",
				"読込不能報告", MB_OK | MB_ICONEXCLAMATION);
	lstrcpy(g_FontName, ini.ReadStr("RichEdit", "FontName"));
	if(!lstrcmp(g_FontName, "Not Found"))
		lstrcpy(g_FontName, "ＭＳ 明朝");
	g_FontSize = ini.ReadInt("RichEdit", "FontSize");
	if(!g_FontSize)
		g_FontSize = 10;
	g_TabNum = ini.ReadInt("RichEdit", "Tab");
	if(!g_TabNum)
		g_TabNum = 4;
	Edit.m_BackGround = ini.ReadInt("RichEdit", "BackGround");
	if(!Edit.m_BackGround)
		Edit.m_BackGround = 12632256;
	Edit.m_Directive = ini.ReadInt("RichEdit", "Directive");
	if(!Edit.m_Directive)
		Edit.m_Directive = 4194432;
	Edit.m_Constant = ini.ReadInt("RichEdit", "Constant");
	if(!Edit.m_Constant)
		Edit.m_Constant = 16711680;
	Edit.m_Reserve = ini.ReadInt("RichEdit", "Reserve");
	if(!Edit.m_Reserve)
		Edit.m_Reserve = 255;
	Edit.m_Comment = ini.ReadInt("RichEdit", "Comment");
	if(!Edit.m_Comment)
		Edit.m_Comment = 8388608;
	Edit.m_String = ini.ReadInt("RichEdit", "String");
	if(!Edit.m_String)
		Edit.m_String = 32768;
	Edit.m_BCCSkelton = ini.ReadInt("RichEdit", "BCCSkelton");
	if(!Edit.m_BCCSkelton)
		Edit.m_BCCSkelton = 65535;

	//リッチエディットEditの初期設定
	Edit.SetFont(g_FontSize, g_FontName);
	Edit.SendMsg(EM_SETUNDOLIMIT, 500, 0);	//UNDOの最大数を100→500に増やす

	//メニューハンドルの取得
	g_hPopup = GetSubMenu(GetMenu(m_hWnd), 1);

	return TRUE;
}

bool CMyWnd::OnMDIChildCreate(WPARAM wParam, LPARAM lParam) {

	//リッチエディットコントロールを作成する
	if(!Edit.Create("", WS_CHILD | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
				WS_HSCROLL | ES_NOHIDESEL | ES_MULTILINE | ES_WANTRETURN,
				WS_EX_CLIENTEDGE, FocusedChild(), IDC_CHILD_CONTROL)) {
		MessageBox(m_hWnd, "RichEdit Controlが作れません", "エラー", MB_OK);
		return FALSE;
	}
	else {
		//2003年の新CREDTクラスでは別途設定する
		Edit.SetWYSWYG();
		//☆リッチエディットコントロールからの特定通知（例：ENM_MOUSEEVENTS）を開始
		Edit.FilterMsg(ENM_MOUSEEVENTS | ENM_CHANGE | ENM_SELCHANGE);
		Edit.SetCol(Edit.m_BackGround, FALSE);
	}
	return TRUE;
}

bool CMyWnd::OnMDIActivate(WPARAM wParam, LPARAM lParam) {

	bool EnableFlag;
	if(FocusedChild() == (HWND)lParam){	//MDIChildウィンドウがアクティブなら
		EnableFlag = TRUE;				//使用不可になっていたメニュー、ツールバーボタンを使用可にする
		Edit.m_hWnd = GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL);
		//ファイルサイズ（"xxxxxxxxxxxバイト" + NULL）のステータスバー表示
		char FileName[MAX_PATH];
		wsprintf(FileName, "%dバイト", Edit.GetSize());
		SBar.SetText(1, FileName);
		//キャレット位置（"(6桁)+行：(6桁)+桁" + NULL）のステータスバー表示
		wsprintf(FileName, "%d行：%d桁", Edit.GetPos()->y + 1, Edit.GetPos()->x + 1);
		SBar.SetText(2, FileName);
		//タイトルバーのファイル名をステータスバーへ表示
		SendMessage(FocusedChild(), WM_GETTEXT, MAX_PATH, (LPARAM)FileName);
		SBar.SetText(3, FileName);
		SBar.SendMsg(SB_SETTIPTEXT, 3, (LPARAM)FileName);	//ToolTipをつける
	}
	else {
		EnableFlag = FALSE;				//そうでなければ使用不可にする
		SBar.SetText(1, "");			//ステータスバーをブランクにする
		SBar.SetText(2, "");			//ステータスバーをブランクにする
		SBar.SetText(3, "");			//ステータスバーをブランクにする
	}
	ChangeMenuStatus(EnableFlag);
	return TRUE;
}

bool CMyWnd::OnSetFocus(WPARAM wParam, LPARAM lParam) {

	//リッチエディットコントロールにフォーカスを移す
	SetFocus(GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL));
	return TRUE;
}

bool CMyWnd::OnFindReplace(LPARAM lParam) {

	Edit.FindReplace(lParam);	//検索・置換処理
}

bool CMyWnd::OnMDIFrameSize(WPARAM wParam, LPARAM lParam) {

	MDIClientAutoSize(SBar.GetHandle(), TBar.GetHandle());
	TBar.AutoSize();
	SBar.AutoSize();
	//データファイル付きで起動された場合の対応
	if(ByFile) {
		for(int i = 1; i < arg.c(); i++) {
			lstrcpy(g_FileName, arg.v(i));
			OnOpen();
		}
		ByFile = FALSE;
 	}
	return TRUE;
}

bool CMyWnd::OnMDIChildSize(WPARAM wParam, LPARAM lParam) {

	//リッチエディットコントロールのサイズをMDI子ウィンドウのクライアント領域にあわす
	MoveWindow((HWND)GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL), 0, 0,
				LOWORD(lParam), HIWORD(lParam), TRUE);
	return TRUE;
}

bool CMyWnd::OnNotify(WPARAM wParam, LPARAM lParam) {

	//ツールバーのツールチップ処理
	if(((LPNMHDR)lParam)->code == TTN_NEEDTEXT) {
		switch(((LPTOOLTIPTEXT)lParam)->hdr.idFrom) {
			case IDM_NEW:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_00);
				break;
			case IDM_OPEN:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_01);
				break;
			case IDM_SAVE:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_02);
				break;
			case IDM_SETPRINT:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_03);
				break;
			case IDM_PRINT:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_04);
				break;
			case IDM_UNDO:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_05);
				break;
			case IDM_REDO:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_06);
				break;
			case IDM_CUT:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_07);
				break;
			case IDM_COPY:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_08);
				break;
			case IDM_PASTE:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_09);
				break;
			case IDM_FIND:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_10);
				break;
			case IDM_REPLACE:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_11);
				break;
			case IDM_JUMP:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_12);
				break;
			case IDM_DIALOGON:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_13);
				break;
			case IDM_DIALOGOFF:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_14);
				break;
			case IDM_SET:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_15);
				break;
			case IDM_SKELTON:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_16);
				break;
			case IDM_MAKE:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_17);
				break;
			case IDM_BCCSKELTON:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_18);
				break;
			case IDM_VER:
				((LPTOOLTIPTEXT)lParam)->lpszText = MAKEINTRESOURCE(String_18);
				break;
			return TRUE;
		}
	}
	//リッチエディット処理
	else if(((LPTOOLTIPTEXT)lParam)->hdr.idFrom == IDC_CHILD_CONTROL) {
		switch(((NMHDR*)lParam)->code) {
		//キャレット位置の変更時
		case EN_SELCHANGE:
			if(!g_BusyCol) {
				//バイト数表示
				char str[19];	//"(6桁)+行：(6桁)+桁" + NULL, //"xxxxxxxxxxxバイト" + NULL
				wsprintf(str, "%dバイト", Edit.GetSize());
				SBar.SetText(1, str);
				//行数、桁数表示
				wsprintf(str, "%d行：%d桁", Edit.GetPos()->y + 1, Edit.GetPos()->x + 1);
				SBar.SetText(2, str);
			}
			break;
		//リッチエディットコントロールのマウス通知（MSGFILTER構造体）
		case EN_MSGFILTER:
			if(((MSGFILTER*)lParam)->msg == WM_RBUTTONUP) {
				//ウインドウの位置情報を取得
				RECT rec;
				GetWindowRect(m_hWnd, &rec);
				//ポップアップメニューの表示場所を設定
				POINT pt;
				GetCursorPos(&pt);
				//ポップアップメニューの表示
				TrackPopupMenu(g_hPopup, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, m_hWnd, &rec);
			}
			break;
		default:
			return FALSE;
		}
		return TRUE;
	}
	else
		return FALSE;
}

bool CMyWnd::OnChildClose(HWND hWnd) {

	if(SendDlgItemMessage(hWnd, IDC_CHILD_CONTROL, EM_GETMODIFY, 0, 0))
		if(MessageBox(m_hWnd, "テキストが変更されています。保存しますか？", "保存確認",
					MB_YESNO | MB_ICONQUESTION) == IDYES)
			OnSave(hWnd);
	SBar.SetText(1, "");
	SBar.SetText(2, "");
	SBar.SetText(3, "");
	return FALSE;
}

bool CMyWnd::OnClose(WPARAM wParam, LPARAM lParam) {

	if(MessageBox(m_hWnd, "終了しますか", "終了確認",
					MB_YESNO | MB_ICONQUESTION) == IDYES) {
		//BCFEditor.iniファイル書き込み
		ini.WriteStr("System", "BCCMaker", g_BCCMaker);
		ini.WriteStr("System", "SkeltonWizard", g_SkeltonWizard);
		ini.WriteStr("RichEdit", "FontName", g_FontName);
		ini.WriteInt("RichEdit", "FontSize", g_FontSize);
		ini.WriteInt("RichEdit", "Tab", g_TabNum);
		ini.WriteInt("RichEdit", "BackGround", Edit.m_BackGround);
		ini.WriteInt("RichEdit", "Directive", Edit.m_Directive);
		ini.WriteInt("RichEdit", "Constant", Edit.m_Constant);
		ini.WriteInt("RichEdit", "Reserve", Edit.m_Reserve);
		ini.WriteInt("RichEdit", "Comment", Edit.m_Comment);
		ini.WriteInt("RichEdit", "String", Edit.m_String);
		ini.WriteInt("RichEdit", "BCCSkelton", Edit.m_BCCSkelton);
		//処理をするとDestroyWindow、PostQuitMessageが呼ばれる
		return TRUE;
	}
	else
		//そうでなければウィンドウではDefWindowProc関数をreturn、ダイアログではreturn FALSEとなる。
		return FALSE;
}

bool CMyWnd::OnChange(WPARAM wParam) {

	if(!g_BusyCol) {	//他でEdit.ColorWords()処理をしていなければ
		if(wParam == MAKEWPARAM(IDC_CHILD_CONTROL, EN_CHANGE)) {
			//トークン色付け処理
			g_BusyCol = TRUE;
			Edit.ColorWords();
			g_BusyCol = FALSE;
			SetFocus(GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL));
    	 }
	}
	return TRUE;
}

bool CMyWnd::OnDropFiles(WPARAM wParam) {

	//ドラッグアンドドロップされたファイルの数取得
	int num = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
	//ドラッグアンドドロップされたファイル名取得と処理
	ByFile = TRUE;
	for(int i = 0; i < num; i++) {
		DragQueryFile((HDROP)wParam, i, g_FileName, sizeof(g_FileName));
		OnOpen();
	}
	ByFile = FALSE;
	DragFinish((HDROP)wParam);
	return TRUE;
}

/////////////////////////////////
//主ウィンドウCMyWndの関数の定義
//メニュー項目、コントロール関数
/////////////////////////////////
bool CMyWnd::OnNew() {

	CreateMDIChild("MDIChildWnd", "[無題]");
	ChangeMenuStatus(TRUE);
	SBar.SetText(3, "[無題]");
	return TRUE;
}

bool CMyWnd::OnOpen() {

	char* cp;
	if(!ByFile) {
		cp = cmndlg.GetFileName(m_hWnd, "プロジェクトファイル(*.bdp)\0*.bdp\0C++関連ファイル(*.cpp, *.h, *.rc)\0*.cpp;*.h;*.rc\0すべてのファイル(*.*)\0*.*\0\0");
		if(cp)	lstrcpy(g_FileName, cp);	//cpがNULLでなければファイル名をg_FileNameへコピー
		else {
			MessageBox(m_hWnd, "操作はキャンセルされました", "メッセージ", MB_OK | MB_ICONERROR);
			return FALSE;
		}
	}
	if(strstr(g_FileName, ".bdp") || strstr(g_FileName, ".BDP")) {	//bdpファイルなら
		CINI bdp(g_FileName);	//bdp(ini)ファイル読書用クラス
		for(cp = g_FileName + lstrlen(g_FileName) - 1; cp > g_FileName; cp--)
			if(*cp == '\\') {
				*(cp + 1) = NULL;
				break;
			}				//FileNameをbdpファイルのパスにする
		CSTR buff, fn;
		int n = bdp.ReadInt("Project", "Count");	//[Project]のファイル数を取得
		for(int i = 1; i <= n; i++) {
			buff = "Filename";
			buff = buff + i;		//"Filename1"、"Filename2"...となっている
			fn = bdp.ReadStr("Project", buff.ToChar());
			fn.Next(buff);	//カンマ区切り文字列なので、最初のファイル名を取得する
			fn = g_FileName;
			fn = fn + "\\" + buff;
			//ファイルを読み込む
			CreateMDIChild("MDIChildWnd", fn.ToChar());
			Edit.LoadFile(fn.ToChar());
			ChangeMenuStatus(TRUE);
			SBar.SetText(3, fn.ToChar());
			//トークン色付け処理
			g_BusyCol = TRUE;
			Edit.ColorWords(TRUE);
			g_BusyCol = FALSE;
			SetFocus(GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL));
			//Res.hファイル登録、BCFHelperメニュー処理
			if(strstr(fn.ToChar(), "Res")) {	//"Res〜.h"ファイルなら
				bcfhelperdlg.Init(fn.ToChar());	//BCFHelperへファイル名を引き渡す
				//メニューハンドルの取得
				HMENU hMenu = GetSubMenu(GetMenu(m_hWnd), 1);
				//メニューバー
				EnableMenuItem(hMenu, 14, MF_BYPOSITION | MF_ENABLED);
				ChangeBCFHelperStatus(TRUE);
			}
		}
	}
	else {
		CreateMDIChild("MDIChildWnd", g_FileName);
		Edit.LoadFile(g_FileName);
		ChangeMenuStatus(TRUE);
		SBar.SetText(3, g_FileName);
		//トークン色付け処理
		g_BusyCol = TRUE;
		Edit.ColorWords(TRUE);
		g_BusyCol = FALSE;
		Edit.UndoClear();	//UNDOバッファを空にする
		SetFocus(GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL));
	}
	return TRUE;
}

bool CMyWnd::OnSave(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	char FileName[MAX_PATH];
	SendMessage(FocusedChild(), WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)FileName);
	if(!lstrcmp(FileName, "[無題]"))
		OnSaveas(hWnd);
	else
		Edit.SaveFile(FileName);
	return TRUE;
}

bool CMyWnd::OnSaveas(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	char* FileName = cmndlg.GetFileName(m_hWnd, "総てのファイル(*.*)\0*.*\0リッチテキストファイル(*.rtf)\0*.rtf\0\0", FALSE);
	if(!FileName) {
		MessageBox(m_hWnd, "操作はキャンセルされました", "メッセージ", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	else {
		Edit.SaveFile(FileName);
		SendMessage(FocusedChild(), WM_SETTEXT, 0, (LPARAM)FileName);
		SBar.SetText(3, FileName);
		return TRUE;
	}
}

bool CMyWnd::OnSetprint() {

	Edit.SetPrinter();
	return TRUE;
}

bool CMyWnd::OnPrint(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	char FileName[MAX_PATH];
	SendMessage(FocusedChild(), WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)FileName);
	Edit.Print(FileName);
	return TRUE;
}

bool CMyWnd::OnExit() {

	SendMessage(m_hWnd, WM_CLOSE, 0, 0);
	return TRUE;
}

bool CMyWnd::OnUndo(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	SendDlgItemMessage(FocusedChild(), IDC_CHILD_CONTROL, EM_UNDO, 0, 0);
	return TRUE;
}

bool CMyWnd::OnRedo(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	SendDlgItemMessage(FocusedChild(), IDC_CHILD_CONTROL, EM_REDO, 0, 0);
	return TRUE;
}

bool CMyWnd::OnCut(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	SendDlgItemMessage(FocusedChild(), IDC_CHILD_CONTROL, WM_CUT, 0, 0);
	return TRUE;
}

bool CMyWnd::OnCopy(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	SendDlgItemMessage(FocusedChild(), IDC_CHILD_CONTROL, WM_COPY, 0, 0);
	return TRUE;
}

bool CMyWnd::OnPaste(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	SendDlgItemMessage(FocusedChild(), IDC_CHILD_CONTROL, WM_PASTE, 0, 0);
	return TRUE;
}

bool CMyWnd::OnSelall(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	SendDlgItemMessage(FocusedChild(), IDC_CHILD_CONTROL, EM_SETSEL, 0, (LPARAM)-1);
	return TRUE;
}

bool CMyWnd::OnFind(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	m_hDlg = Edit.m_hFRDlg = FindText(Edit.SetFRDlg('F'));
	return TRUE;
}

bool CMyWnd::OnReplace(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	m_hDlg = Edit.m_hFRDlg = ReplaceText(Edit.SetFRDlg('R'));
	return TRUE;
}

bool CMyWnd::OnJump(HWND hWnd) {

	Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
	//行指定ダイアログで取得した行のチェックし、問題なければジャンプする
	int row = jumpdlg.DoModal(m_hWnd, "IDD_JUMP", jumpdlgProc) - 1;
	if(row >= 0) {
		Edit.Jump(row, FALSE);
		return TRUE;
	}
	else {
		MessageBox(m_hWnd, "不適切（1未満）な行数です", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
}

bool CMyWnd::OnDialogon() {

	//モードレスダイアログを作成Create(hParent, DlgName, DlgProc);
	if(!bcfhelperdlg.Create(m_hWnd, m_hInstance, "IDD_BCFHELPER", bcfhelperdlgProc)) {
		MessageBox(m_hWnd, "ダイアログが作成出来ませんでした。", "エラー",
				MB_OK | MB_ICONERROR);
		return FALSE;
	}
	else {
		//ダイアログのハンドルを登録し、メッセージループを区分
		m_hDlg = bcfhelperdlg.GetHandle();
		//ダイアログを親ウィンドウの右上に移動
		RECT rc;
		GetWindowRect(m_hDlg, &rc);
		int w = rc.right - rc.left;
		GetWindowRect(m_hWnd, &rc);
		SetWindowPos(m_hDlg, HWND_TOPMOST, rc.right - w, rc.top, 0, 0, SWP_NOSIZE);
		ChangeBCFHelperStatus(FALSE);
		return TRUE;
	}
}

bool CMyWnd::OnDialogoff() {

	//ダイアログを破棄
	bcfhelperdlg.Destroy();
	ChangeBCFHelperStatus(TRUE);
	return TRUE;
}

bool CMyWnd::OnSet() {

	setupdlg.DoModal(m_hWnd, "IDD_SETUP", setupdlgProc);
	//トークン色付け処理
	g_BusyCol = TRUE;
	Edit.ColorWords(TRUE);
	g_BusyCol = FALSE;
	SetFocus(GetDlgItem(FocusedChild(), IDC_CHILD_CONTROL));
	return TRUE;
}

bool CMyWnd::OnSkelton() {

	char FilePath[MAX_PATH], *cp;
	SBar.GetText(3, FilePath);
	for(cp = FilePath + lstrlen(FilePath); cp >= FilePath; cp--)
		if(*cp == '.') {
			*cp = NULL;
			break;
		}
	cp =  cmndlg.GetFileName(m_hWnd, "リソースファイル(*.rc)\0*.rc\0\0", TRUE, "rc", FilePath);
	if(!cp) {
		MessageBox(m_hWnd, "キャンセルされました", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	CSTR cmd = g_SkeltonWizard;
	cmd = cmd + " \"";
	cmd = cmd + cp + "\"";
	WinExec(cmd.ToChar(), SW_SHOWNORMAL);
	return TRUE;
}

bool CMyWnd::OnMake() {

	char FilePath[MAX_PATH], *cp;
	SBar.GetText(3, FilePath);
	for(cp = FilePath + lstrlen(FilePath); cp >= FilePath; cp--)
		if(*cp == '.') {
			*cp = NULL;
			break;
		}
	cp =  cmndlg.GetFileName(m_hWnd, "メイクファイル(*.mak)\0*.mak\0\0", TRUE, "mak", FilePath);
	if(!cp) {
		if(MessageBox(m_hWnd, "キャンセルされましたが、BCCMakerを使いますか？", "エラー", MB_YESNO | MB_ICONERROR) == IDYES) {
			WinExec(g_BCCMaker, SW_SHOWNORMAL);
			return TRUE;
		}
		else
			return FALSE;
	}
	CSTR cmd = g_BCCMaker;
	cmd = cmd + " \"";
	cmd = cmd + cp + "\"";
	WinExec(cmd.ToChar(), SW_SHOWNORMAL);
	return TRUE;
}

bool CMyWnd::OnTilehorz() {

	SendMessage(m_hMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
	return TRUE;
}

bool CMyWnd::OnTilevert() {

	SendMessage(m_hMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
	return TRUE;
}

bool CMyWnd::OnCascade() {

	SendMessage(m_hMDIClient, WM_MDICASCADE, 0, 0);
	return TRUE;
}

bool CMyWnd::OnArrange() {

	SendMessage(m_hMDIClient, WM_MDIICONARRANGE, 0, 0);
	return TRUE;
}

bool CMyWnd::OnBccskelton() {

	CSTR cmd = "hh \"";
	cmd = cmd + arg.Path() + "\\BCCSkelton.chm\"";
	WinExec(cmd.ToChar(), SW_SHOWNORMAL);
	return TRUE;
}

bool CMyWnd::OnShortCut() {

	MessageBox(m_hWnd,
	"Ctrl+N−新規作成\nCtrl+O−ファイルを開く\nCtrl+S−ファイルの保存\nCtrl+P−印刷\nCtrl+X−終了\n\n"\
	"Ctrl+U−元に戻す\nCtrl+T−切り取り\nCtrl+C−コピー\nCtrl+V−貼り付け\n\nCtrl+F−文字列の検索\n"\
	"Ctrl+R−文字列の置換\n\nF1−ショートカットキーの解説\nF2−バージョン情報",
	"ショートカットキーの解説", MB_OK | MB_ICONINFORMATION);
	return TRUE;
}

bool CMyWnd::OnVer() {

	versiondlg.DoModal(m_hWnd, "IDD_VERSION", versiondlgProc);
	return TRUE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
bool SETUPDLG::OnInit(WPARAM wParam, LPARAM lParam) {

	//BCCMakerのパス
	SendItemMsg(IDC_BCCMAKER, WM_SETTEXT, 0, (WPARAM)g_BCCMaker);
	//SkeltonWizardのパス
	SendItemMsg(IDC_BCCSKELTON, WM_SETTEXT, 0, (WPARAM)g_SkeltonWizard);
	//タブ設定
	SendItemMsg(IDC_TAB, EM_LIMITTEXT, (WPARAM)2, 0);	//タブの入力文字数制限
 	CSTR str = g_TabNum;
	SendItemMsg(IDC_TAB, WM_SETTEXT, 0, (WPARAM)str.ToChar());

	return TRUE;
}

bool SETUPDLG::OnOwnerdraw(WPARAM wParam, LPARAM lParam) {
	//wParam - ボタンのID、lParam -  DRAWITEMSTRUCT構造体へのポインター
	//((LPDRAWITEMSTRUCT)lParam)->hDC - ボタンのデバイスコントロールハンドル
	COLORREF col;
	switch(wParam) {
	case IDC_BKCOL:		//背景色
		col = Edit.m_BackGround;
		break;
	case IDC_CDIR:		//コンパイラーディレクティブ
		col = Edit.m_Directive;
		break;
	case IDC_CNST:		//定数
		col = Edit.m_Constant;
		break;
	case IDC_RSV:		//予約語
		col = Edit.m_Reserve;
		break;
	case IDC_CMT:		//コメント
		col = Edit.m_Comment;
		break;
	case IDC_STR:		//文字列
		col = Edit.m_String;
		break;
	case IDC_BCC:		//BCCSkeltonクラス名
		col = Edit.m_BCCSkelton;
		break;
	default:
		return FALSE;
	}
	if(m_Brush)	DeleteObject(m_Brush);	//既に作成済の場合は廃棄
	m_Brush = CreateSolidBrush(col);	//背景色ブラシ
	SelectObject(((LPDRAWITEMSTRUCT)lParam)->hDC, m_Brush);
	FillRect(((LPDRAWITEMSTRUCT)lParam)->hDC, &((LPDRAWITEMSTRUCT)lParam)->rcItem, m_Brush);
	return TRUE;
}

bool SETUPDLG::OnDestroy(WPARAM wParam, LPARAM lParam) {

	DeleteObject(m_Brush);	//作成した背景色ラベル用のブラシを解放する
	return TRUE;
}

bool SETUPDLG::OnIdok() {

	//タブ設定
	char tab[3];
	SendItemMsg(IDC_TAB, WM_GETTEXT, 3, (LPARAM)tab);
	Edit.Tab(g_TabNum = atoi(tab));
	//エディットコントロールの背景色設定
	Edit.SetCol(Edit.m_BackGround, FALSE);
	EndModal(TRUE);
	return TRUE;
}

bool SETUPDLG::OnMaker() {

	char* cp = cmndlg.GetFileName(m_hWnd, "BCCMaker\0BCCMaker.exe\0\0", TRUE);
	if(!cp) {
		MessageBox(m_hWnd, "選択されませんでした", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	lstrcpy(g_BCCMaker, cp);
	SendItemMsg(IDC_BCCMAKER, WM_SETTEXT, 0, (LPARAM)cp);
	return TRUE;
}

bool SETUPDLG::OnSkelton() {

	char* cp = cmndlg.GetFileName(m_hWnd, "SkeltonWizard\0SkeltonWizard.exe\0\0", TRUE);
	if(!cp) {
		MessageBox(m_hWnd, "選択されませんでした", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	lstrcpy(g_SkeltonWizard, cp);
	SendItemMsg(IDC_BCCSKELTON, WM_SETTEXT, 0, (LPARAM)cp);
	return TRUE;
}

bool SETUPDLG::OnFont() {

	//全文のフォント指定
	Edit.SetFont();
	//設定をグローバル変数に記録
	g_FontSize = Edit.m_hFont.m_FontSize;
	lstrcpy(g_FontName, Edit.m_hFont.m_FontName);
	return TRUE;
}

bool SETUPDLG::OnBackCol() {

	Edit.m_BackGround = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_BKCOL), NULL, TRUE);
	return TRUE;
}

bool SETUPDLG::OnDirective() {

	Edit.m_Directive = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_CDIR), NULL, TRUE);
	return TRUE;
}

bool SETUPDLG::OnConstant() {

	Edit.m_Constant = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_CNST), NULL, TRUE);
	return TRUE;
}

bool SETUPDLG::OnReserve() {

	Edit.m_Reserve = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_RSV), NULL, TRUE);
	return TRUE;
}

bool SETUPDLG::OnComment() {

	Edit.m_Comment = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_CMT), NULL, TRUE);
	return TRUE;
}

bool SETUPDLG::OnString() {

	Edit.m_String = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_STR), NULL, TRUE);
	return TRUE;
}

bool SETUPDLG::OnBCCClass() {

	Edit.m_BCCSkelton = cmndlg.GetColor(m_hWnd);
	InvalidateRect(GetDlgItem(m_hWnd, IDC_BCC), NULL, TRUE);
	return TRUE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
bool JUMPDLG::OnIdok() {

	char ln[MAX_PATH];
	SendItemMsg(IDC_ROW, WM_GETTEXT, MAX_PATH, (LPARAM)ln);
	EndModal(atoi(ln));
	return TRUE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
bool VERSIONDLG::OnInit(WPARAM wParam, LPARAM lParam) {

	versiondlg.SendItemMsg(IDC_VERTXT, WM_SETTEXT,
					0, (LPARAM)"BCFEditor Ver 2.1\nCopyright by Y-Sama\nSeptember, 2020");
	return TRUE;
}

bool VERSIONDLG::OnIdok() {

	EndModal(TRUE);
	return TRUE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
//ウィンドウメッセージ関連
bool BCFHELPERDLG::OnInit(WPARAM wParam, LPARAM lParam) {

	//コンボボックスの初期設定
	SendItemMsg(IDC_COMBOBOX, CB_INSERTSTRING, 0, (LPARAM)"WMメッセージ");
	SendItemMsg(IDC_COMBOBOX, CB_INSERTSTRING, 1, (LPARAM)"メニュー、コントロール");

	return TRUE;
}

//コントロール関連
bool BCFHELPERDLG::OnCombobox(WPARAM wParam) {

	if(HIWORD(wParam) == CBN_SELCHANGE) {
		//現在のコンテンツを消去
		SendItemMsg(IDC_LISTBOX, LB_RESETCONTENT, 0, 0);
		//コンボボックスの選択番号を調べる
		switch(SendItemMsg(IDC_COMBOBOX, CB_GETCURSEL, 0, 0)) {
		case 0:	//WMメッセージ
			SetMsg();
			break;
		case 1:	//メニュー、コントロール(IDM, IDC)
			SetMenuCtrl();
			break;
		default:
			MessageBox(m_hWnd, "選択されていません", "エラー", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		return TRUE;
	}
	else
		return FALSE;
}

bool BCFHELPERDLG::OnIdok() {

	//変数定義
	int sel[3];
	char buff[MAX_PATH];
	char** msg;
	//コンボボックスの選択確認
	if((sel[0] = SendItemMsg(IDC_COMBOBOX, CB_GETCURSEL, 0, 0)) == CB_ERR) {
		MessageBox(m_hWnd, "コンボボックスが選択されていません", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	//挿入内容の確認
	if((sel[1] = SendItemMsg(IDC_LISTBOX, LB_GETCURSEL, 0, 0)) == LB_ERR) {
		MessageBox(m_hWnd, "メッセージまたはコントロールが選択されていません", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	//挿入内容の確認
	for(sel[2] = 0; sel[2] < 3; sel[2]++)
		if(SendItemMsg(IDC_RBTABLE + sel[2], BM_GETCHECK, 0, 0) == BST_CHECKED)
			break;
	switch(sel[0]) {
	case 0:	//WMメッセージ
		msg = SearchMsg(sel[1]);
		switch(sel[2]) {
		case 0:	//テーブル
			wsprintf(buff, "\t%s(%s)\n", msg[0], m_InstName.ToChar());
			break;
		case 1:	//関数宣言
			wsprintf(buff, "\tbool %s(WPARAM, LPARAM);\n", msg[1]);
			break;
		case 2:	//関数定義
			wsprintf(buff, "bool CMyWnd::%s(WPARAM wParam, LPARAM lParam) {\n\n\t//ここからコーディングしてください\n\treturn TRUE;\n}\n\n", msg[1]);
			break;
		default:
			MessageBox(m_hWnd, "「挿入内容」が選択されていません", "エラー", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		Clip.SetText(buff);
		SendMessage(Edit.m_hWnd, WM_PASTE, 0, 0);
		break;
	case 1:	//コントロール（msg[0] == 小文字のID）、メニュー（msg[0] == NULL）
		msg =  GetMenuCtrl(sel[1]);
		switch(sel[2]) {
		case 0:	//テーブル
			if(!msg[0])	//Menuの場合、msg[0]はヌルポインターが返る
				wsprintf(buff, "\tON_COMMAND(%s, %s, On%s())\n", m_InstName.ToChar(), msg[2], msg[1]);
			else
				wsprintf(buff, "\tON_COMMAND(%sdlg, %s, On%s())\n", msg[0], msg[2], msg[1]);
			break;
		case 1:	//関数宣言
			wsprintf(buff, "\tbool On%s();\n", msg[1]);
			break;
		case 2:	//関数定義
			if(!msg[0])	//Menuの場合、msg[0]はヌルポインターが返る
				wsprintf(buff, "bool CMyWnd::On%s() {\n\n\t//ここからコーディングしてください\n\treturn TRUE;\n}\n\n", msg[1]);
			else
				wsprintf(buff, "bool %s::On%s() {\n\n\t//ここからコーディングしてください\n\treturn TRUE;\n}\n\n", msg[0], msg[1]);
			break;
		default:
			MessageBox(m_hWnd, "「挿入内容」が選択されていません", "エラー", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		Clip.SetText(buff);
		SendMessage(Edit.m_hWnd, WM_PASTE, 0, 0);
		break;
	default:
		break;
	}
	return TRUE;
}

bool BCFHELPERDLG::OnIdcancel() {

	//ダイアログを破棄
	bcfhelperdlg.Destroy();
	//メニューバー、ツールバーの変更
	ChangeBCFHelperStatus(TRUE);
	return TRUE;
}
