//////////////////////////////////////////
// DumpProc.h
// Copyright (c) 03/04/2021 by BCCSkelton
//////////////////////////////////////////

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

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

	//ステータスバー登録−SetHandle(hWnd))
	SBar.SetHandle(GetDlgItem(m_hWnd, IDC_STATUSBAR));
	//ステータスバー区画設定
	int sec[1] = {-1};
	SBar.SetSection(1, sec);
	//ステータスバー文字列設定
	SBar.SetText(0, "ファイル名−「ファイル」ボタンで選択");

	//ビットマップをボタンに張り付ける
	m_hBmp[0] = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDI_TOP), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
	SendItemMsg(IDC_TOP, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBmp[0]);
	m_hBmp[1] = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDI_BEFORE), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
	SendItemMsg(IDC_BEFORE, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBmp[1]);
	m_hBmp[2] = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDI_NEXT), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
	SendItemMsg(IDC_NEXT, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBmp[2]);
	m_hBmp[3] = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDI_BOTTOM), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
	SendItemMsg(IDC_BOTTOM, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBmp[3]);
	//IDC_TOP、IDC_BEFOREとIDC_NEXT、IDC_BOTTOMボタンを無効にする
	ChangeTopStatus(FALSE);
	ChangeBottomStatus(FALSE);

	//IDC_PAGEの文字数を6(5桁)に設定
	SendItemMsg(IDC_PAGE, EM_LIMITTEXT, 6, 0);

	//ドラッグアンドドロップの受付開始
	DragAcceptFiles(m_hWnd, TRUE);

	//ボタンとエディットボックスにツールチップを付ける
	if(!SetToolTip(m_hWnd, IDC_FILE, "Dumpするファイルを選択します"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_FILE）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDC_EDIT, "Dumpデータ表示エリア"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_EDIT）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDC_TOP, "ファイルの先頭に行きます"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_TOP）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDC_BEFORE, "１ページ戻ります"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_BEFORE）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDC_PAGE, "中央のページです"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_PAGE）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDC_NEXT, "１ページ進みます"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_NEXT）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDC_BOTTOM, "ファイルの後尾に行きます"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDC_BOTTOM）", "エラー", MB_OK | MB_ICONERROR);
	if(!SetToolTip(m_hWnd, IDOK, "終了します"))
		MessageBox(m_hWnd, "ツールチップを付けられませんでした（IDOK）", "エラー", MB_OK | MB_ICONERROR);

	//ファイルドロップによる起動
	if(g_ByFile)
		OnFile();

	return TRUE;
}

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

	SBar.AutoSize();
	return TRUE;
}

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

	if(MessageBox(m_hWnd, "終了しますか", "終了確認",
					MB_YESNO | MB_ICONINFORMATION) == IDYES) {
		//ボタンのビットマップを解放する
		DeleteObject(m_hBmp[0]);
		DeleteObject(m_hBmp[1]);
		DeleteObject(m_hBmp[2]);
		DeleteObject(m_hBmp[3]);
		//処理をするとDestroyWindow、PostQuitMessageが呼ばれる
		return TRUE;
	}
	else
		//そうでなければウィンドウではDefWindowProc関数をreturn、ダイアログではreturn FALSEとなる。
		return FALSE;
}

//ダイアログベースの場合はこれが必要
bool CMyWnd::OnDestroy(WPARAM wPram, LPARAM lParam) {

	PostQuitMessage(0);
	return TRUE;
}

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

	//典型的なドラッグアンドドロップ処理
	static char lpszFn[MAX_PATH];
	HDROP hDrop = (HDROP)wParam; 					//HDROPを取得
	DragQueryFile(hDrop, 0, lpszFn, MAX_PATH);		//ファイル名を取得
	m_FileName = lpszFn;
	g_ByFile = TRUE;
	OnFile();
	DragFinish(hDrop);								//終了処理
	return TRUE;
}

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

	//ファイル選択（ドラッグアンドドロップでは省略）
	if(g_ByFile)
		g_ByFile = FALSE;
	else
		m_FileName = cmndlg.GetFileName(m_hWnd, "すべてのファイル(*.*)\0*.*\0\0", TRUE);
	if(!m_FileName) {
		MessageBox(m_hWnd, "ファイル選択がキャンセルされました", "キャンセル", MB_OK | MB_ICONSTOP);
		return FALSE;
	}
	//ステータスバーにファイル名表示
	SBar.SetText(0, m_FileName);
	SBar.SendMsg(SB_SETTIPTEXT, 0, (LPARAM)m_FileName);	//ToolTipをつける
	//ファイル読み込みと初期化処理
	m_File.LoadFile(m_FileName);						//ファイルを読み込む
	m_File.GoTop();										//ファイルの先頭へ
	m_Page = 0;											//最初のページ
	m_LastPage = m_File.m_FileSize / PAGE;				//Fileバイト数をPAGE単位とする
	//最初のページを表示する
	SetPage(m_Page);
	//最初のデータの表示
	ShowData(m_Page);
	//最初のボタン状態の設定
	ChangeTopStatus(FALSE);
	ChangeBottomStatus(TRUE);

	return TRUE;
}

bool CMyWnd::OnTop() {

	m_Page = 0;			//最初のページ
	SetPage(m_Page);	//ページを表示する
	ShowData(m_Page);	//データを表示する
	//IDC_TOPとIDC_BEFOREボタンを無効にする
	ChangeTopStatus(FALSE);
	//IDC_NEXTとIDC_BOTTOMボタン
	if(m_LastPage)	//1ページだけでなければ有効にする
		//IDC_NEXTとIDC_BOTTOMボタン状態を変更する
		ChangeBottomStatus(TRUE);
	else 			//1ページだけならボタンを無効にする
		ChangeBottomStatus(FALSE);

	return TRUE;

}

bool CMyWnd::OnBefore() {
                        	
	if(!m_Page) {			//既に最初のページであれば
		//IDC_TOPとIDC_BEFOREボタンを無効にする
		ChangeTopStatus(FALSE);
		return FALSE;	 	//何もしないで戻る
	}
	else {
		m_Page--;			//そうでなければページを一つ戻し
		SetPage(m_Page);	//ページを表示する
	 	ShowData(m_Page);	//データを表示する
		//IDC_NEXTとIDC_BOTTOMボタンを有効にする
		ChangeBottomStatus(TRUE);
    	if(!m_Page)			//最初のページであれば
		//IDC_TOPとIDC_BEFOREボタンを無効にする
		ChangeTopStatus(FALSE);
		return TRUE;
	}
}

bool CMyWnd::OnNext() {

	if(m_Page == m_LastPage) {	//既に最後のページであれば
		//IDC_NEXTとIDC_BOTTOMボタンを無効にする
		ChangeBottomStatus(FALSE);
		return FALSE;	  		//何もしないで戻る
	}
	else {
		m_Page++;			//そうでなければページを一つ進め
		SetPage(m_Page);	//ページを表示する
		ShowData(m_Page); 	//データを表示する
		//IDC_TOPとIDC_BEFOREボタンを有効にする
		ChangeTopStatus(TRUE);
		if(m_Page == m_LastPage)	//最後のページになれば
			//IDC_NEXTとIDC_BOTTOMボタンを無効にする
			ChangeBottomStatus(FALSE);
		return TRUE;
	}
}

bool CMyWnd::OnBottom() {

	m_Page = m_LastPage;	//最後のページ
	SetPage(m_Page);		//ページを表示する
	ShowData(m_Page);		//データを表示する
	//IDC_NEXTとIDC_BOTTOMボタンを無効にする
	ChangeBottomStatus(FALSE);
	//IDC_TOPとIDC_BEFOREボタ
	if(m_Page)		//1ページだけでなければ有効にする
		//IDC_TOPとIDC_BEFOREボタン状態を変更する
		ChangeTopStatus(TRUE);
	else 			//1ページだけならボタンを無効にする
		ChangeTopStatus(FALSE);

	return TRUE;
}

bool CMyWnd::OnIdok() {

	SendMsg(WM_CLOSE, 0, 0);
	return TRUE;
}

//ユーザー定義関数
bool CMyWnd::SetPage(int page) {

	char num[6];					//5桁まで対応可能
	wsprintf(num, "%d", page + 1);	//ページ数の文字化(1 → m_LastPage + 1）
	SendItemMsg(IDC_PAGE, WM_SETTEXT, 0, (LPARAM)num);	//IDC_PAGEへ表示

	return TRUE;
}

bool CMyWnd::ShowData(int page) {

	char str[MAX_PATH];	//一行書き込み文字列バッファ
	m_Buff = "";	//初期化
	for(int i = page * PAGE; i < (page + 1) * PAGE; i += 16) {
		if(i >= m_File.m_FileSize)		//最終ページ対応
			break;
		int n = 0, j = 0;
		n = wsprintf(str, "%04X ", i);	//アドレス
		j += n;
		for(int k = 0; k < 8; k++) {	//8バイト16進書き込み
			n = wsprintf(str + j, "%02X ", m_File.m_Ptr[i + k] & 0xFF);
			j += n;
		}
		n = wsprintf(str + j, ":");		//セパレーター
		j += n;
		for(int k = 8; k < 16; k++) {	//8バイト16進書き込み
			n = wsprintf(str + j, "%02X ", m_File.m_Ptr[i + k] & 0xFF);
			j += n;
		}
		n = wsprintf(str + j, ":");		//セパレーター
		j += n;
		for(int k = 0; k < 16; k++) {	//キャラクター表示
			n = wsprintf(str + j, "%c", isalnum(m_File.m_Ptr[i + k]) ? m_File.m_Ptr[i + k] : '.');
			j += n;
		}
		n = wsprintf(str + j, "\r\n");
		m_Buff = m_Buff + str;
	}
	SendItemMsg(IDC_EDIT, WM_SETTEXT, 0, (LPARAM)m_Buff.ToChar());

	return TRUE;
}

bool CMyWnd::ChangeTopStatus(bool stat) {

	//IDC_TOPとIDC_BEFOREボタン状態を変更する
	EnableWindow(GetDlgItem(m_hWnd, IDC_TOP), stat);
	EnableWindow(GetDlgItem(m_hWnd, IDC_BEFORE), stat);
	return TRUE;
}

bool CMyWnd::ChangeBottomStatus(bool stat) {

	//IDC_NEXTとIDC_BOTTOMボタン状態を変更する
	EnableWindow(GetDlgItem(m_hWnd, IDC_NEXT), stat);
	EnableWindow(GetDlgItem(m_hWnd, IDC_BOTTOM), stat);
	return TRUE;
}

bool CMyWnd::GoMiddle(WPARAM wParam) {

	//ファイルが選択されていない場合
	if(!m_FileName)
		return FALSE;
	//IDC_PAGEエディットコントロールにフォーカスがない場合
	if(HIWORD(wParam) != EN_SETFOCUS)
		return FALSE;
	//IDC_PAGEエディットコントロールにフォーカスが移った場合
	else
		m_Page = m_LastPage / 2;	//ページ中間へ進む
	if(m_Page == m_LastPage)		//m_LastPageが0なら
		ChangeBottomStatus(FALSE);	//IDC_NEXTとIDC_BOTTOMボタン無効化
	else {
		ChangeBottomStatus(TRUE);	//IDC_NEXTとIDC_BOTTOMボタン有効化
		if(m_Page)					//最初のページでなければ
			ChangeTopStatus(TRUE);	//IDC_TOPとIDC_BEFOREボタン有効化
		else						//最初のページなら
			ChangeTopStatus(FALSE);	//IDC_TOPとIDC_BEFOREボタン無効化
	}
	SetPage(m_Page);				//ページを表示する
	ShowData(m_Page); 				//データを表示する

	return TRUE;
}
