#pragma twice

KAB-studio > プログラミング > #pragma twice > 394 Version 18.07 ウィンドウプロシージャを純粋仮想関数にする、の続き

#pragma twice 394 Version 18.07 ウィンドウプロシージャを純粋仮想関数にする、の続き

前のページへ 表紙・目次へ 次のページへ

 Version 18.07
ウィンドウプロシージャを純粋仮想関数にする、の続き

前回は、ダイアログプロシージャを純粋仮想関数にするところまでしまし

なんかすごく中途半端なところで終わったんだけど
プログラム、半分しか紹介しなかったからね。前回のプログラムでは 
CDialog クラスに以下の修正をしました

・DialogProc() メンバ関数を純粋仮想関数に。
・デストラクタを追加。

 DialogProc() メンバ関数を純粋仮想関数にしたことでメンバ関数の
中身がなくなりました
中身がなくても呼べるんだから不思議よねぇ

// ダイアログプロシージャ(形式上)。
BOOL CALLBACK CDialog::DispatchDialogProc
    ( HWND p_hDlgWnd
    , UINT p_uiMessage
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
// 略

    // メンバ関数のダイアログプロシージャを呼び出します。
    return 
        pcDialog->DialogProc    ←純粋仮想関数を呼び出しています。
            ( p_hDlgWnd
            , p_uiMessage
            , p_wParam
            , p_lParam 
            );
}

 Version 17.16 ( No.371 ) で説明したように、純粋仮想関数は中身を
派生クラスに作って、そちらを呼び出します
つまり、この CDialog クラスだけじゃなくて、別に派生クラス作って継承
させるってわけね
そういうこと。そこで、 Version 18.03 ( No.390 ) と同じ方法で
ソースファイルとヘッダーファイルを追加してクラスを追加します。作成す
るファイルは以下の2つです

・NewCalcDialog.h
・NewCalcDialog.cpp

追加するクラスは CNewCalcDialog クラスね
というわけで、この2つのファイルに以下のプログラムを書いてくださ
い。まず NewCalcDialog.h から

// NewCalcDialog.h

// CNewCalcDialog クラス。
class CNewCalcDialog : public CDialog
{
public:
    // ダイアログプロシージャ。
    BOOL DialogProc
    ( HWND p_hDlgWnd
    , UINT p_uiMessage
    , WPARAM p_wParam
    , LPARAM p_lParam
    );
};

 CNewCalcDialog クラスね。お、ちゃんと CDialog クラスから継承して
る!
この CNewCalcDialog クラスは CDialog クラスの派生クラスで、
DialogProc() メンバ関数をオーバーライド、正確には実装しています
純粋仮想関数だった DialogProc() メンバ関数に中身作ったわけね
その DialogProc() メンバ関数の中身は NewCalcDialog.cpp ファイルに
書きます。それが以下のプログラム

// NewCalcDialog.cpp
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
#include "Dialog.h"
#include "NewCalcDialog.h"

// ダイアログプロシージャ。
BOOL CNewCalcDialog::DialogProc
    ( HWND p_hDlgWnd
    , UINT p_uiMessage
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
    if( p_uiMessage == WM_COMMAND )
    {
        if( LOWORD( p_wParam ) == IDOK )
        {
            // OK ボタンが押されました。
            EndDialog( p_hDlgWnd, IDOK );
            return TRUE;
        }
        else if( LOWORD( p_wParam ) == IDC_B_EQUAL )
        {
            // 各エディットボックスのウィンドウハンドル
            // を取得します。
            HWND hLeftWnd 
                = GetDlgItem( p_hDlgWnd, IDC_E_LEFT );
            HWND hRightWnd 
                = GetDlgItem( p_hDlgWnd, IDC_E_RIGHT );
            HWND hAnswerWnd 
                = GetDlgItem( p_hDlgWnd, IDC_E_ANSWER );

            // 各エディットボックス用文字列を用意します。
            char pchLeft[256];
            char pchRight[256];
            char pchAnswer[256];

            // IDC_E_LEFT と IDC_E_RIGHT の文字列を取得します。
            GetWindowText( hLeftWnd, pchLeft, 255 );
            GetWindowText( hRightWnd, pchRight, 255 );

            // それぞれ int 型に変換します。
            int iLeft = atoi( pchLeft );
            int iRight = atoi( pchRight );
            
            // 足した結果を pchAnswer に文字列変換します。
            sprintf( pchAnswer, "%d", iLeft + iRight );

            // それを IDC_E_ANSWER にセットします。
            SetWindowText( hAnswerWnd, pchAnswer );

            // ここで SetWindowLong() していた箇所は
            // 削除してください。

            return TRUE;
        }
    }
    return FALSE;
}

 DialogProc() メンバ関数の中身はこれまでと同じなのでそのままコピペ
しても構いません
ホントだ、そのまま派生クラスに移動したって感じね
最後に、 Main.cpp もちょこっと修正します

// Main.cpp
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
#include "Dialog.h"
#include "NewCalcDialog.h" // ←追加してください。

// WinMain() 。
int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    // CNewCalcDialog クラスでダイアログを作成します。
    CNewCalcDialog cDialog;    // ←クラス名を変更してください。
    cDialog.DoModal( p_hInstance, IDD_MAIN );

    return 0;
}

修正箇所は2ヶ所。まず NewCalcDialog.h ヘッダーファイルを
インクルードしてください。そのあと、 CDialog クラスの変数を宣言して
いた所を、 CNewCalcDialog クラスに変更してください
 CDialog クラスから CNewCalcDialog クラスに切り替えたわけね。それ
って CDialog クラスだと変数作れないから?
そう! 純粋仮想関数を持っている CDialog クラスは変数を作ることが
できないんです。だから CNewCalcDialog クラスに変更するわけです
なるほどねー
修正する所は以上です。ビルドして実行してみて
ほい。うん、同じように計算できるよ
そう、今回の修正はプログラムの構造を変えただけで、機能は変わってな
いから
……でも、じゃあ何のためにやったの?
その説明は次回に

/*
    Preview Next Story!
*/
んー、なんかファイル増えただけで意味なくない?
意味はちゃんとあるんです
ホントに? つかなんだかクラスが増えて頭こんがらがってきたんだけど
 MFC に比べればずっと少ないでしょ
え、 MFC に比べればそりゃねぇ……
というわけで次回
< Version 18.08 継承で機能を分けて再利用 >
につづく!
楽しくなると自分で MFC くらいクラス作るようになるから
嫌! それはすっごく嫌!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。