#pragma twice

KAB-studio > プログラミング > #pragma twice > 390 Version 18.03 ダイアログプロシージャを static メンバ関数にする

#pragma twice 390 Version 18.03 ダイアログプロシージャを static メンバ関数にする

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

 Version 18.03
ダイアログプロシージャを static メンバ関数にする

さて、前回説明したプログラムは API だけで作ってあるわけですが、こ
れをクラスで作っていきます
 MFC がそうだからできる、っていうのは分かるんだけど、なんかイメージ
掴めない……
そのための練習だしね。さて、まずヘッダーファイルを作成します。
メニューの【ファイル】-【新規作成】を選んでください
いつものだね
左の欄で【C/C++ ヘッダー ファイル】を選択して、ファイル名は Dialog.h 
にしてください
ほい
で、この中に以下のように書いてください

// Dialog.h

// Dialog クラス。
class CDialog
{
public:
    static BOOL CALLBACK DialogProc
    ( HWND p_hDlgWnd
    , UINT p_uiMessage
    , WPARAM p_wParam
    , LPARAM p_lParam
    );
};

 CDialog クラス作るんだね
この CDialog クラスが、ダイアログの基本クラスになります。このクラス
の DialogProc() メンバ関数が前回の DialogProc() 関数
つまり普通の関数を CDialog クラスのメンバ関数にするってことね
そういうこと。で、このメンバ関数が static メンバ関数っていう点に注
意して

      ↓これ
    static BOOL CALLBACK DialogProc

そか、確か普通の関数の代わりに static メンバ関数が使えるって言って
たね
 Version 16.28 ( No.355 )  で説明したように普通の関数、特に
コールバック関数の代わりにすることができるんです。
ダイアログプロシージャはコールバック関数でしょ
 Windows から呼び出される関数だもんね。だから static メンバ関数に
してるの?
そういうこと。こうすることで、メンバ関数でも外から呼び出してもらえ
るようになるわけです
なるほどねー
では次に、このクラスの本体、ソースファイルを作ります。メニューの
【ファイル】-【新規作成】を選んで、左の欄で【C++ ソース ファイル】を
選択して、ファイル名は Dialog.cpp にしてください
ほいと
で、この中に以下のように書き込んでください

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

// ダイアログプロシージャ。
BOOL CALLBACK CDialog::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 );

            return TRUE;
        }
    }
    return FALSE;
}

ほとんど DialogProc() 関数と同じ。違うのは、 CDialog クラスの
メンバ関数っていう点だけ

            これが加わった
                  ↓
BOOL CALLBACK CDialog::DialogProc

これだけでいいんだね
そう、それだけで static メンバ関数になります。詳しくは
Version 16.26 ( No.353 )  を参考にしてください
 DialogProc() メンバ関数の中身は同じだよね
うん、 DialogProc() 関数の時と同じ。ということは、 Main.cpp の
DialogProc() 関数が移動したということなので、以下のように修正します

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

// ここにあった DialogProc() 関数が、 CDialog クラスの
// メンバ関数になりました。

// WinMain() 。
int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    int iRet
        = DialogBox
            ( p_hInstance
            , MAKEINTRESOURCE( IDD_MAIN )
            , NULL
            , CDialog::DialogProc
            );

    return 0;
}

まず CDialog クラスを使う必要があるので Dialog.h ヘッダーファイルを
インクルードします

#include "Dialog.h"  ←この行が追加されました。

これでこのソースファイルから CDialog クラスを使うことができます。
次に DialogProc() 関数は CDialog クラスのメンバ関数にしたので削除し
ます

// ここにあった DialogProc() 関数が、 CDialog クラスの
// メンバ関数になりました。

最後に、 DialogBox() 関数の第4引数には、 DialogProc() 関数のアドレス
ではなく CDialog クラスの DialogProc() メンバ関数を渡すようにします

    int iRet
        = DialogBox
            ( p_hInstance
            , MAKEINTRESOURCE( IDD_MAIN )
            , NULL
            , CDialog::DialogProc  ←ここが変わりました。
            );

この使い方も Version 16.28 ( No.355 ) と同じね
そういうこと。つまり、ウィンドウプロシージャみたいなコールバック関数
をメンバ関数にしたい場合には、〈 static メンバ関数〉にすればいいわけ
です
そう考えると難しいことじゃないよね
うん、今回は正式な方法で、ってことでソースファイルやヘッダーファイル
を作ったから複雑になったかもしれないけど、それを別にすれば、単に普通の
関数を static メンバ関数にしただけだから
……それってメリットあるの?
う”、今回だけだとほとんどメリットないかも

/*
    Preview Next Story!
*/
むー、無駄教えられたー
でもこれは次回への布石だから
えー、ホントー? なんかタイトルがそれっぽくないけど
というわけで次回
< Version 18.04 ウィンドウの 32 ビット整数値 >
につづく!
それにこれと同じ方法で WinMain() も static メンバ関数にできるよ?
してどうするの?
うーん
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。