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というマシン語を使った理解しずらい仕組みにあるが、使用するのは簡単だ。理解するのは難解だが。
のCWndProcThunkを使えばいい。いつの間にか、x86以外でも使用できるようになってる。

元ネタはこっち
詳しい解説はこちら(英語)