コールバックの呼ばれるタイミングがSetWindowLongの呼び出しタイミングとは違うので
temporalだとうまくブロックを渡せないのかな?

それならGWL_USERDATAにProcやMethodをdlwrapしてSetWindowLongで格納、
stdcallのbindのブロック内でGWL_USERDATAからGetWindowLongして
dlunwrapしてcallするのがよいのでは?

...
WND_PROC2 = bind("LRESULT WindowProc(HWND, UINT, WPARAM, LPARAM)", :stdcall){|hwnd, msg, wp, lp|
DL.dlunwrap(GetWindowLong(hwnd, GWL_USERDATA)).call(hwnd, msg, wp, lp)
}
...
Win32.SetWindowLong(get_handle(), Win32::GWL_USERDATA, DL.dlwrap(method(:callback_func)))
@oldWndProc = Win32.SetWindowLong(get_handle(), Win32::GWL_WNDPROC, Win32::WND_PROC2)
...