前回、StaticWindowProcを追加したことで、CWindowクラスにウィンドウプロシージャをメンバとして組み込むことができた・・・。
ただ、スタティックなメンバであるため、複数のウィンドウオブジェクトが同時に処理をすると、それぞれ競合してしまう可能性がある・・・。
またスタティックメンバ関数は、継承してウィンドウプロシージャをオーバーライドすることができないため、派生のウィンドウオブジェクトではウィンドウプロシージャを名前を変えて定義する必要がある・・・。
そこで、メンバ関数としてDynamicWindowProcを用意し、StaticWindowProcから呼び出すようにする・・・。
そして、DynamicWindowProcでは、それぞれのメッセージ処理をする・・・。
まず、Window.hにて、
staticなStaticWindowProcと、virtualなDynamicWindowProc、これらを用意・・・。
DynamicWindowProcは、
まるでウィンドウプロシージャのようである・・・。
さて、StaticWindowProcはどうやってこのDynamicWindowProcを呼び出しているのだろうか?
StaticWindowProcでは、
まずCWindowオブジェクトポインタpWindowを用意し、NULLにセット・・・。
WM_CREATEは、この中で処理するメッセージとしてはちょっと特殊で、CreateStruct構造体のポインタをlParamから取得しておく・・・。
lpCreateParamsという要素に、実は生成するウィンドウのCWindowオブジェクトのポインタが入っているので、それを取り出してpWindowに格納している・・・。
これは、CWindowのCreateメンバ関数の中の、
ここの最後の引数のthis、これをLPVOIDにキャストして渡している・・・。
そうすると、先ほどのlpCreateParamsのところに、thisつまりCWindowオブジェクト自身のポインタを渡すことができるのである・・・。
なぜこんなことをするのかというと、CWindowオブジェクトのポインタpWindowとウィンドウハンドルhwndを1対1で紐付けたいからである・・・。
紐付けられれば、オブジェクトごとにウィンドウ操作ができ、それぞれの処理を独立させることができるからだ・・・。
(独立といっても、CWindow同士ならおなじCWindow::DynamicWindowProcを通る・・・。ただ、それぞれが違うオブジェクトインスタンスなので、処理が競合することはない。)
紐付けるために、
スタティックメンバオブジェクトとして、std::mapのm_mapWindowMapを用意・・・。
これWindow.cppにもいるので注意・・・。
このm_mapWindowMapに、
hwndとpWindowをペアにしてセットする・・・。
WM_CREATEの場合はそのあと、
pWindowがNULLではないので、pWindowからDynamicWindowProcを呼ぶ・・・。
WM_CREATE以外の場合は、lpCreateStructが渡されないので、
m_mapWindowMapからhwndをキーにして、pWindowを取り出す・・・。
このとき、hwndが無い場合は取り出さない・・・。ここ注意・・・。
pWindowがあったら、先ほどと同様にDynamicWindowProcを呼び、万が一なかったら、
普通のDefWindowProcを呼ぶ・・・。
こうやって、CWindowオブジェクトごとにDynamicWindowProcを呼ぶことができ、それぞれの処理を独立させることができる・・・。
実は、hwndとpWindowの関係を保存する方法として、std::mapを使う方法以外に、GetWindowLongのGWL_USERDATAを使う方法、SetProp/GetPropを使う方法があるのだが、どちらも構造上の問題があるため、今回はstd::mapで行う方法にした・・・。
これでウィンドウプロシージャごとオーバーライドできる・・・。
https://github.com/bg1bgst333/Test/blob/master/winapi/CWindow/DynamicWindowProc/src/DynamicWindowProc/DynamicWindowProc/WinMain.cpp
https://github.com/bg1bgst333/Test/blob/master/winapi/CWindow/DynamicWindowProc/src/DynamicWindowProc/DynamicWindowProc/Application.h
https://github.com/bg1bgst333/Test/blob/master/winapi/CWindow/DynamicWindowProc/src/DynamicWindowProc/DynamicWindowProc/Application.cpp
https://github.com/bg1bgst333/Test/blob/master/winapi/CWindow/DynamicWindowProc/src/DynamicWindowProc/DynamicWindowProc/Window.h
https://github.com/bg1bgst333/Test/blob/master/winapi/CWindow/DynamicWindowProc/src/DynamicWindowProc/DynamicWindowProc/Window.cpp