CUIからGUIへ(4)

ダイアログサンプル

ここまでで今回目的とするGUIアルゴリズムの一部が完成した。いままでやったことを組み合わせて、ソフトとして完成させてみよう。

ファイル選択ダイアログ編

1-1.VC6.0を起動し、新規作成から"MFC AppWizard (exe)"を選択し、プロジェクト名に適当な名前を入れて(ここではCRLF)OKを押す。
1-2."MFC AppWizard - ステップ1"でダイアログベースを選び終了を押す。
1-3.OKを押すとダイアログの編集画面になるので、"OKボタン", "キャンセルボタン", "TODO:..."を消す。
1-4.右のパレットからボタンを選び、新たにボタンを作成する。
1-5.作成したボタンを右クリックしてプロパティを選択。キャプションに"参照"と入力。
1-6.右のパレットからエディットボックスを選び、配置する。
1-7.手順1-4で作ったボタンをダブルクリック。メンバ関数名をOnBFileSelectに変更してOK。
1-8.OnBFileSelect()関数が作られるので、その関数の中に下のプログラムを書き込む。

void CCRLFDlg::OnBFileSelect() 
{
	CFileDialog    dlg(TRUE, NULL, NULL,
            OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_NOCHANGEDIR,
            "テキストファイル(*.txt)|*.txt|全てのファイル(*.*)|*.*||",
			this);

	//  ファイルダイアログの起動
	if (dlg.DoModal() == IDOK) {
		// エディットボックス(IDC_EDIT1)に得たパスをセット
		CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT1);
		pEdit->SetWindowText(dlg.GetPathName());
	}
}

ここまで出来たら一度ビルド(F7)してみて、動作を確かめてみてもいいかも。

改行コード変換編

2-1.ダイアログ編集画面に戻り、"変換"という名前でボタンを一つ追加。
2-2.追加したボタンをダブルクリックして、OnBTranceというメンバ関数を追加
2-3.関数の中に以下のプログラムを書き込む

void CCRLFDlg::OnBTrance() 
{
    char sFileName[MAX_PATH];
    char sBakupFileName[MAX_PATH];
    FILE *fpOut;
    FILE *fpIn;

    // 変換の前処理
    {
        // エディットボックスから名前を取得し、
        // 対象のファイル名とバックアップ用のファイル名を設定する
        CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT1);
        pEdit->GetWindowText(sFileName, MAX_PATH);
        sprintf(sBakupFileName, "%s.bak", sFileName);

        // オリジナルを退避
        if (CopyFile(sFileName, sBakupFileName, FALSE) == FALSE) {
            MessageBox("対象ファイル名が不正です", "警告",
                MB_OK|MB_ICONWARNING);
            return;
        }

        // 退避したほうを読み込みで開く
        fpIn = fopen(sBakupFileName, "rb");
        // オリジナルを上書きで開く
        fpOut = fopen(sFileName, "wb");
    }

    /*
        改行コードの変換処理(Windows用への変換のみ)
          win  \r\n
          unix \r
          mac  \n
    */
    {
        int tmp;
        while ((tmp = fgetc(fpIn)) != EOF) {
            switch (tmp) {
              case '\r':
                if ((tmp = fgetc(fpIn)) == '\n') {
                    fputs("\r\n", fpOut);
                } else {
                    fputs("\r\n", fpOut);
                    fputc(tmp, fpOut);
                }
                break;
              case '\n':
                fputs("\r\n", fpOut);
                break;

              default:
                fputc(tmp, fpOut);
            }
        }
    }   
    fclose(fpIn);
    fclose(fpOut);
    MessageBox("変換完了");
}

エラーチェックを若干省いたが、これで一応完成。Unix->Win, Mac->Win, Win->Winのコード変換が問題なく行えると思う。
知らない関数はGoogle先生に聞くのがよいかと。