// About.cpp :
// バージョン情報ダイアログのプロシージャ

#include "stdafx.h"
#include "RNSF7.h"
#include "About.h"
#include "MainWindow.h"
#include "opendlg.h"
#include "refresh.h"
#include "MainListview.h"
#include "commfunc.h"

static LRESULT CALLBACK Version( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK Ccpu32( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
static volatile char *verstr = NULL; // リソースからプログラム名とバージョンを読み出して格納される
static volatile char *vercpr = NULL; // リソースから著作権情報を読み出して格納される
static bool betaflag = 0;
static DWORD releasenumber = 0;
static char szTitleMain[MAX_PATH];

// プログラム名を示す文字列を生成し、verstrに代入する
void make_verstr( void )
{
	if ( verstr == NULL ) {
		char exename[MAX_PATH*2];
		DWORD dwSize;
		char *verdata, *lpFileDescription, *lpFileVersion, *lpSpecialBuild, *lpLegalCopyright, *lpPrivateBuild;
		UINT len,a,b,c,d;
		char strtmp[1025];

		vercpr = (char *)malloc(260);

		if ( vercpr ) {
			if ( !GetModuleFileName(NULL, exename, _countof(exename)) ) {
				exename[0] = 0; // エラーだった場合は、exenameは無効にしておく
			}
			if (0 < (dwSize = GetFileVersionInfoSize(exename, 0))) {
				verdata = (char *)malloc( dwSize+2 );
				if ( GetFileVersionInfo(exename,0,dwSize,verdata) ) {
					if ( VerQueryValue(verdata,"\\StringFileInfo\\041104b0\\FileVersion",(LPVOID *)&lpFileVersion,&len) ) {
						if ( !VerQueryValue(verdata,"\\StringFileInfo\\041104b0\\FileDescription",(LPVOID *)&lpFileDescription,&len) )
							lpFileDescription = "";
						if ( !VerQueryValue(verdata,"\\StringFileInfo\\041104b0\\SpecialBuild",(LPVOID *)&lpSpecialBuild,&len) )
							lpSpecialBuild = "";
						if ( !VerQueryValue(verdata,"\\StringFileInfo\\041104b0\\LegalCopyright",(LPVOID *)&lpLegalCopyright,&len) )
							lpLegalCopyright = "";
						if ( !VerQueryValue(verdata,"\\StringFileInfo\\041104b0\\PrivateBuild",(LPVOID *)&lpPrivateBuild,&len) )
							lpPrivateBuild = "";

						// ダイアログに書き込こむバージョン情報を生成
						sscanf_s(lpFileVersion, "%u.%u.%u.%u",&a,&b,&c,&d);
						wsprintf((LPSTR)vercpr, "%s\nAll rights reserved.", lpLegalCopyright);

						// β版等の特定
						if ( _stricmp(lpSpecialBuild, "beta") == 0 ) {
							lpSpecialBuild = "β";
						}
						else if ( _stricmp(lpSpecialBuild, "alpha") == 0 ) {
							lpSpecialBuild = "α";
						}

						// アプリケーション名をダイアログに書き込む
						wsprintf(strtmp, "%s version %u.%u%u.%02u%s [%s](%s)", lpFileDescription, a, b, c, d, lpSpecialBuild, lpPrivateBuild,
#ifdef _WIN64
							"x64"
#else  /*_WIN64*/
							"x86"
#endif /*_WIN64*/
							);
						verstr = _strdup(strtmp);
						releasenumber = a*10000 + b*1000 + c*100 + d;

						betaflag = ( strcmp(lpSpecialBuild, "β") == 0 || _stricmp(lpSpecialBuild, "Final Beta") == 0 || _stricmp(lpSpecialBuild, "Release Candidate") == 0 || strcmp(lpSpecialBuild, "α") == 0 || _stricmp(lpSpecialBuild, "Public Preview") == 0 || _stricmp(lpSpecialBuild, "Test Release") == 0 || strcmp(lpSpecialBuild, "Preview Release") == 0 );
						lstrcpy(szTitleMain, lpFileDescription);
					}
				}
				safefree(verdata);
			}
		}
	}
}

UINT getReleaseNumber( void )
{
	make_verstr();
	return releasenumber;
}

// バージョン情報を表示する
void CallAboutWindow( HWND hWnd )
{
	make_verstr();

	C32ABOUTBOX c32ab;

	ZeroMemory(&c32ab, sizeof(c32ab));
	c32ab.hInst = hInst;
	c32ab.hWnd = hWnd;
	c32ab.pszTitle = szTitleMain;
	c32ab.pszUrl = "http://www.inasoft.org/";
	c32ab.pszEmail = "tyabuki@inasoft.org";
	c32ab.pszKifuURL = "http://www.inasoft.org/kifu.html";
	c32ab.pszFeedbackURL = _T("http://www.inasoft.org/ifa.php?RNSF7");
	c32ab.pszInformation = betaflag
				? "　これは開発中のバージョンですので注意してご利用下さい。再配布・雑誌収録等はご遠慮下さい。バグなどを発見された場合は直ちに作者へご連絡下さい。\r\n　このプログラムはWindowsの環境設定を変更することを主な目的としています。元に戻せるかどうか不安な方は、重要なデータやレジストリのバックアップを取ってからご使用下さい。バックアップは専用のツールやWindows付属のツールを使うか、メインウインドウの「ツール」メニューから呼び出します。\r\n　このプログラムはフリーソフトです。営利・非営利目的に関わらず無償で使用できますが、このプログラムを使用した際に何か障害が発生しても、当方では一切責任を負いませんのであらかじめご了承下さい。\r\n　このプログラムは現在、開発途中のバージョンです。(媒体を問わず)紹介は自由に行えますが、(媒体を問わず)再配布・雑誌付属メディアなどへの収録をしてはいけません。紹介の際に事前に許可を得る必要はありません。また、紹介する際にアイコンや実行時画面を用いてもかまいません。本ソフトウェアの著作権上の規定は、日本国の法律に準拠することとします。その他の詳細な情報につきましては、付属のドキュメントを参照するか、メールにてお問い合わせ下さい。\r\n\r\n●その他の著作権情報\r\n\r\n　"SOFTWARENAME"「オプション」(Rnsf7.rsc)の一部：\r\n　　関連付け処理の追加と変更 - 2003/05/06 Taka\r\n\r\n　「タスク」(mstask.rsc)、「HTMLエディタの設定」(EditSetting.rsc)：\r\n　　オリジナルスクリプトの提供 - 2005/05/29 Sinwa\r\n\r\n　オープニングの画像：\r\n　　(C) 2003-2012 Wada Akina( http://www.buntetsu.net/ )\r\n\r\n※Windows、Windows NTは米国Microsoft Corporationの米国およびその他の国における登録商標です。\r\n※その他、表示される会社名・製品名などは、一般に各社の登録商標もしくは商標です。"
				: "　このプログラムはWindowsの環境設定を変更することを主な目的としています。元に戻せるかどうか不安な方は、重要なデータやレジストリのバックアップを取ってからご使用下さい。バックアップは専用のツールやWindows付属のツールを使うか、メインウインドウの「ツール」メニューから呼び出します。\r\n　このプログラムはフリーソフトです。営利・非営利目的に関わらず無償で使用できますが、このプログラムを使用した際に何か障害が発生しても、当方では一切責任を負いませんのであらかじめご了承下さい。\r\n　このプログラムの紹介・再配布は(媒体を問わず)自由に行うことができます。再配布(転載・収録を含む)の際に事前に許可を得る必要はありません。また、紹介する際にアイコンや実行時画面を用いてもかまいません。本ソフトウェアの著作権上の規定は、日本国の法律に準拠することとします。その他の詳細な情報につきましては、ヘルプを参照して下さい。\r\n\r\n●その他の著作権情報\r\n\r\n　"SOFTWARENAME"「オプション」(Rnsf7.rsc)の一部：\r\n　　関連付け処理の追加と変更 - 2003/05/06 Taka\r\n\r\n　「タスク」(mstask.rsc)、「HTMLエディタの設定」(EditSetting.rsc)：\r\n　　オリジナルスクリプトの提供 - 2005/05/29 Sinwa\r\n\r\n　オープニングの画像：\r\n　　(C) 2003-2012 Wada Akina( http://www.buntetsu.net/ )\r\n\r\n※Windows、Windows NTは米国Microsoft Corporationの米国およびその他の国における登録商標です。\r\n※その他、表示される会社名・製品名などは、一般に各社の登録商標もしくは商標です。";
	c32ab.modeJP = 1; // 日本語固定
	c32ab.numIconRes = IDI_RNSF7;
	c32ab.ccpudlg_call = (CCPUDLG_CALL)CallCcpuWindow;

	ccpu32_ShowAboutBox(&c32ab);
}

// CCPUを表示する
void WINAPI CallCcpuWindow( HWND hWnd )
{
	make_verstr();
	DialogBox(hInst, (LPCTSTR)IDD_CCPU32, hWnd, (DLGPROC)Ccpu32);
}

static const struct DEFTOOLTIP ccputooltips[] = {
	{IDC_BUTTON_SAVE, "上に表示されている情報をテキストファイルに保存します"},
	{IDC_BUTTON_COPY, "上に表示されている情報をクリップボードへコピーします"},
	{IDCANCEL, "このダイアログを閉じます"},
	{IDHELP,   "このダイアログに関するヘルプを表示します"},
	{0,0}};

// ダイアログのアンカー等に関する情報
static const DLGITEM dlgitems[] = {
	{IDC_STATIC1,     ANCHOR_TOPLEFT},
	{IDC_EDIT1,       ANCHOR_CENTER},
	{IDC_BUTTON_SAVE, ANCHOR_BOTTOMLEFT},
	{IDC_BUTTON_COPY, ANCHOR_BOTTOMLEFT},
	{IDCANCEL,        ANCHOR_BOTTOMRIGHT},
	{IDHELP,          ANCHOR_BOTTOMRIGHT},
	{0,0}
};

// 編集ボックスのサブクラス化用ウィンドウプロシージャ
static WNDPROC re_OldEditProc;

// サンプルウィンドウ内の編集ボックスのサブクラス化用ウィンドウプロシージャ
static LRESULT CALLBACK re_NewEditProc(HWND hEdit, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch( message ) {
		case WM_CHAR: // 全選択のための Ctrl+A 受け取りのため
			if( (int)wParam == 1 ) {
				SendMessage( hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1 );  
				return 0; // デフォルトのプロシージャを呼ばずにそのまま終了
			}
			break;
	}

	// デフォルトのプロシージャをコール
	return CallWindowProc(re_OldEditProc, hEdit, message, wParam, lParam);
}

static LRESULT CALLBACK Ccpu32( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	static SIZEDLG *sizedlg;
	HGLOBAL hMem;

	switch( message ) {
		case WM_INITDIALOG:
			{ // ダイアログ中のフォントを可変サイズに変える
				HFONT	hFont = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
				char   *macinfo;

				SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
				SendDlgItemMessage(hDlg, IDC_BUTTON_SAVE, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
				SendDlgItemMessage(hDlg, IDC_BUTTON_COPY, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
				SendDlgItemMessage(hDlg, IDCANCEL, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
				SendDlgItemMessage(hDlg, IDHELP, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
				makeToolTip(hDlg, ccputooltips);

				SendMessage( hMainWindow, R7MW_STATUS_BAR, 0, (LPARAM)"環境の調査をしています。キーボードやマウスには手を触れず、しばらくお待ち下さい..." );

				// CCPU32.LIBの呼び出し
				hMem = ccpu32_GetEnvironment((LPSTR)verstr, 0);
				macinfo = (char *)GlobalLock( hMem );
				SetDlgItemText(hDlg,IDC_EDIT1,macinfo);
				GlobalUnlock( hMem ); macinfo = NULL;
				safegfree(hMem);

				SendMessage( hMainWindow, R7MW_STATUS_BAR, 0, (LPARAM)0 );

				// アイコンの設定
				SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, (LPCSTR)IDI_CCPU) );

				// ダイアログのコントロールのアンカーを登録
				sizedlg = new SIZEDLG(hDlg, dlgitems);

				// サブクラス化
				HWND hEdit = GetDlgItem(hDlg, IDC_EDIT1);
				re_OldEditProc = (WNDPROC)GetWindowLongPtr( hEdit, GWLP_WNDPROC );
				SetWindowLongPtr( hEdit, GWLP_WNDPROC, (LONG_PTR)re_NewEditProc );

				return TRUE;
			}

		case WM_HELP:
			callhelp2(hDlg, "HLP000044.html");
			return TRUE;

		case WM_DESTROY:
			// リサイズのための情報を破棄
			delete sizedlg;
			return TRUE;

		case WM_SIZE:
			// リサイズ
			sizedlg->Resize(1);
			return TRUE;

		case WM_GETMINMAXINFO:
			// ダイアログの最小サイズを定義
			sizedlg->GetMinMaxInfo(lParam);
			return TRUE;

		case WM_COMMAND:
			switch ( LOWORD(wParam) ) {
				case IDCANCEL:
					EndDialog(hDlg, 0);
					return TRUE;

				case IDHELP:
					callhelp2(hDlg, "HLP000044.html");
					return TRUE;

				case IDC_BUTTON_SAVE: // ファイルへ保存
					{
						char fname[MAX_PATH*2]="";
						HANDLE hfile;
						DWORD wr;

						if ( saveDialog(hDlg, "テキストファイル(*.txt)\0*.txt\0すべてのファイル(*.*)\0*.*\0\0", fname, _countof(fname), "環境情報の表示結果をファイルへ保存", "txt" ) ) {
							if (INVALID_HANDLE_VALUE  == (hfile = CreateFile(fname, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)))
								MessageBox(hDlg, "ファイルを開けません。", "環境情報の表示", MB_OK | MB_ICONSTOP);
							else {
								char *macinfo = (char *)malloc( wr = GetWindowTextLength(GetDlgItem(hDlg, IDC_EDIT1))+1 );
								if ( macinfo ) {
									GetDlgItemText(hDlg, IDC_EDIT1, macinfo, wr);
									WriteFile(hfile,macinfo,lstrlen(macinfo), &wr, NULL);
									CloseHandle(hfile);
									safefree(macinfo);
									MessageBox( hDlg, "表示内容をファイルへ保存しました。", "環境情報の表示", MB_OK | MB_ICONINFORMATION );
								}
								else {
									CloseHandle(hfile);
									DeleteFile(fname);
									MessageBox(hDlg, "作業用のメモリが足りません。", "環境情報の表示", MB_OK | MB_ICONSTOP);
								}
							}
						}
						return TRUE;
					}

				case IDC_BUTTON_COPY: // クリップボードへコピー
					if( OpenClipboard(NULL) ) {
						char *pPtr;
						int gsize = GetWindowTextLength(GetDlgItem(hDlg, IDC_EDIT1))+1;
						HGLOBAL hMem = GlobalAlloc(GHND,gsize);

						if (hMem) {
							pPtr = (char *)::GlobalLock(hMem);
							if (pPtr) {
								GetDlgItemText(hDlg,IDC_EDIT1,pPtr,gsize);
								GlobalUnlock(hMem);
								if (EmptyClipboard()) {
									HANDLE hRet=SetClipboardData(CF_TEXT,hMem);
									if (hRet == NULL) {
										safegfree(hMem);
									}
									MessageBox(hDlg, hRet?"クリップボードへコピーしました。":"クリップボードへのコピーに失敗しました。", "環境情報の表示", MB_OK | MB_ICONINFORMATION);
								}
								else {
									MessageBox(hDlg, "クリップボードを空にできません。", "環境情報の表示", MB_OK | MB_ICONINFORMATION);
									safegfree(hMem);
								}
							}
							else {
								MessageBox(hDlg, "GlobalLock失敗。", "環境情報の表示", MB_OK | MB_ICONINFORMATION);
								safegfree(hMem);
							}
						}
						else {
							MessageBox(hDlg, "作業用のメモリが足りません。", "環境情報の表示", MB_OK | MB_ICONSTOP);
						}
						CloseClipboard();
					}
					else {
						MessageBox(hDlg, "クリップボードを開けません。", "環境情報の表示", MB_OK | MB_ICONSTOP);
					}
					return TRUE;
			}
			break;
	}
    return FALSE;
}
