ダイアログのクラス化で仮想関数を用いて派生クラスにしているんです
ダイアログのクラス化で仮想関数を用いて派生クラスにしているんですが・・・
ダイアログを基本クラスで静的プロシージャと派生クラスでオーバーライドしてプロシージャを使いたい
のですが、どうしても自身のポインタが取得できません。
以下にソースを載せておきます。
class CBaseWnd
{
public:
// ポインタの設定
void SetPointer( HWND hWnd );
// ウィンドウプロシージャの呼び出し
static LRESULT CALLBACK CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
// ウィンドウプロシージャの実装
virtual LRESULT MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
};
[クラスの実装]
//===== ポインタの設定 =====//
void CBaseWnd::SetPointer( HWND hWnd )
{
SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );
}
//===== ウィンドウプロシージャの呼び出し =====//
LRESULT CALLBACK CBaseWnd::CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
//_プロパティリストからthisポインタを取得
//ここでポインタを取得することができないでいます。値が0です。
//先にSetWindowlongをやっても値が0のままです。
CBaseWnd* thisPtr = (CBaseWnd*)GetWindowLong( hWnd, GWL_USERDATA );
//_thisポインタが取得できなかった場合...
if( ! thisPtr )
{
//_ウィンドウの作成時の場合...
//ここでアクセス違反というエラーが起きる
if( message == WM_INITDIALOG )
thisPtr = (CBaseWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;
//_thisポインタが取得できた場合...
if( thisPtr )
{
//_プロパティリストにオブジェクトハンドル(thisポインタ)を設定する
thisPtr->SetPointer( hWnd );
}
}
//_thisポインタが取得できた場合...
if( thisPtr )
{
LRESULT lResult = thisPtr->MainProc( hWnd, message, wParam, lParam );
return lResult;
}
return DefWindowProc( hWnd, message, wParam, lParam );
}
//===== ウィンドウプロシージャの実装(継承可能) =====//
// ここでの記述はデフォルトの処理
//
LRESULT CBaseWnd::MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
//_ウィンドウが破棄された場合
case WM_DESTROY:
PostQuitMessage(0);
return 0;
//_デフォルトの場合
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
}
WM_INITDIALOGでダイアログの初期化中にポインタを取得しようとしますが、アクセス違反が起こり失敗します。
どなたか分かる方がいらっしゃったらご指摘お願いします。
お礼
回答ありがとうございます。 まさにその本を見て疑問が生じたので質問しました。 仮想関数を使わないコードに変更してみたら納得できました。 仮想関数を使ったほうがはるかにシンプルになりますね。 純粋仮想関数は、まぁその発展系ということで、良しとします。