■
C++でウインドウ作成する際に必ず出てくる、WNDCLASSEXのlpfnWndProcはC++のメンバ関数との相性がひどく悪い。BOOSTを使ってもお手上げで、どう転んでもリンクしない。
WNDCLASSEX wcs;
wcs.lpfnWndProc = (WNDPROC)... <-- ここにC++クラスのstaticでないメンバ関数をつなげたい(長年の夢)が、できない。(全世界のエンジニアが一度は悩むネタ)
MFCはうまくつなげてるように見せかけているだけ。しかし、ATLはそこにマジックをかけている。
// static関数
LRESULT CALLBACK CWnd::DefWndproc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
CWnd* p = (CWnd*)hWnd; // マジック!
LRESULT r = 1;
p->ProcessWindowMessage( p->m_hWnd, msg, wParam, lParam, r, 0 ); // メンバ関数
if ( r == 0 )
return 0L;
return ::DefWindowProc( p->m_hWnd, msg, wParam, lParam );
}
OSから飛んでくるHWNDが実は、オブジェクトのポインタに取替られていて、メンバ関数へリンクできる。
このマジックのタネは、thunkというマシン語を使った理解しずらい仕組みにあるが、使用するのは簡単だ。理解するのは難解だが。