Step 3. データの解析

プログラムを作る最大の目的はここにあります。しかし、もちろん個々に解析する内容は異なるでしょうから一般的な説明は困難です。ここでは、解析を実行するにあたって必要な一通りの作業をごく簡単にまとめます。例として行なうのは表示されたデータのy値の合計を計算し表示するといったとてもシンプルなものです。

1. メニューの追加

ここらあたりはどこの解説書にもありますのでもっとかっこいいものを作ることもできますが、ここではメニューバーに「データ解析」を追加することだけやります。

まず、左ウインドウのResorce とかかれた札をクリックし、step1リソースが表示されたらここもクリックし、Menuディレクトリをクリックし、さらにIDR_MAINFRAMEをクリックします。ついでですのでメニューの整理をしましょう。ファイルのところは「開く」「上書き保存」「アプリケーションの終了」だけ残してあとは削除します。「上書き保存」は「データファイルの保存」などに名称変更します。「編集」「ヘルプ」などの使わない項目は削除して「データ解析」メニューを付加します。「データ解析」メニューのプルダウンメニューにキャプション「データの和を求める」を加え、IDをID_SumData などとします。


2. OnSumData関数の設置

今度は左ウインドウのFileの札をクリックし、****View.cppを選択します。 メニューバーの(すべてのクラスメンバ)というところをクリックするとおそらく一番下に今作った ID_SumData がありますのでこれを選択します。その隣の枠からcommand を選択してクリックします。そうするとデフォルトの関数名として OnSumData でよいか尋ねられますのでOKをクリックします。これで OnSumData関数の準備が整いましたのでこれを以下のように書きます。

void CStep1View::OnSumData() 
{
    // TODO: この位置にコマンド ハンドラ用のコードを追加してください
    SumData=0.0;

    for (int i=0; i<ndata; i++){
        
        if (x[i]>=Xmin && x[i]<=Xmax && y[i]>=Ymin && y[i]<=Ymax) {

            SumData=SumData+y[i];

        }

    }

    MSumData=1;
    
    RedrawWindow();

}


3. 変数の宣言と初期化

Step 1., 2. でさんざんやりましたので大丈夫だと思いますが上の OnSumData で使用する MSumData, SumData をヘッダファイルに宣言し、以下のように初期化しておきます。

CStep1View::CStep1View()
{
    // TODO: この場所に構築用のコードを追加してください。
    MRegion=0;
    Ci=0;
  //今回はここです。
    MSumData=0;
    SumData=0.0;
}


4. OnDraw 関数

解析処理(といってもここではただデータの足し算をやっただけですが)の結果をグラフ左上に表示するように OnDraw 関数を書き換えます。解析処理をしたときだけ(MSumData が1のとき)表示が出るようにしています。

void CStep1View::OnDraw(CDC* pDC)
{
    CStep1Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: この場所にネイティブ データ用の描画コードを追加します。

    int xt, yt;
    char name[20], *t1;


    for (int i=0; i<ndata; i++){
        
        if (x[i]>=Xmin && x[i]<=Xmax && y[i]>=Ymin && y[i]<=Ymax) {

            xt=(int)  550*(x[i]-Xmin)/(Xmax-Xmin)+100;
            yt=(int) -300*(y[i]-Ymin)/(Ymax-Ymin)+350;

            pDC->SetPixel(xt,yt,RGB(0,0,255));
        }

    }


//  pDC->Rectangle(100,50,650,350);
    if (ndata>0) {
        CBrush NewBrush;
        NewBrush.CreateSolidBrush(RGB(255,0,0));
        CBrush* OldBrush=pDC->SelectObject(&NewBrush);

        CRect DRect(100,50,650,350);
        pDC->FrameRect(DRect, &NewBrush);

        pDC->SelectObject(OldBrush);
        NewBrush.DeleteObject();

        pDC->TextOut(250,30, "VC++ for Chemist");

        t1 = gcvt(Xmin, 8, name);
        pDC->TextOut(100,360, t1);
        t1 = gcvt(Xmax, 8, name);
        pDC->TextOut(640,360, t1);

        pDC->SetTextColor(RGB(255,0,0));
        t1 = gcvt(Ymax, 8, name);
        pDC->TextOut(40,50, t1);
        t1 = gcvt(Ymin, 8, name);
        pDC->TextOut(40,330, t1);

        //データの総和はここから

        if (MSumData==1) {

            CPen NewPen;
            NewPen.CreatePen(PS_SOLID, 2, RGB(0,255,255));
            CPen* OldPen=pDC->SelectObject(&NewPen);

            pDC->Rectangle(20,20,150,40);

            pDC->SelectObject(OldPen);
            NewPen.DeleteObject();

            pDC->SetTextColor(RGB(0,0,0));
            pDC->TextOut(20,20, "SUM:");
            pDC->SetTextColor(RGB(0,255,0));
            t1 = gcvt(SumData, 8, name);
            pDC->TextOut(60,20, t1);
        }

    }

}


5. C 言語の関数

こんなことを書くと当たり前だといわれそうですが、C 言語で作った過去の遺産はそのまま使えるようです。****View.cpp のなかにこれらの関数を組み込んで使うことができます。サンプルでは最小二乗法のルーチンはニューメリカルレシピインシー(Numerical Recipes in C 技術評論社)で紹介されているマルカルト法をほぼそのままの形で使用しています。