#include <windows.h>
#include <TCHAR.h>
typedef LRESULT (CALLBACK *PWNDPROC)(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
template <class ToType, class FromType>
void GetMemberFuncAddr_VC6(ToType &addr,FromType f)
{
union
{
FromType _f;
ToType _t;
}ut;
ut._f = f;
addr = ut._t;
}
#pragma pack(push,1)
struct Thunk
{
BYTE m_mov;
DWORD m_pThis;
BYTE m_jmp;
DWORD m_relproc;
template<typename PTHIS, typename PFUN>
void init(PTHIS pThis, PFUN pFun)
{
DWORD FuncAddr;
GetMemberFuncAddr_VC6(FuncAddr, pFun);
m_mov = 0xb9;
m_pThis = (UINT_PTR)pThis;
m_jmp = 0xe9;
m_relproc = (UINT_PTR)((INT_PTR)FuncAddr - (INT_PTR)this-sizeof(Thunk));
::FlushInstructionCache(::GetCurrentProcess(), this, sizeof(Thunk));
}
};
#pragma pack(pop)
class CMyWnd
{
public:
CMyWnd(){}
~CMyWnd(){}
public:
virtual void OnCreate()
{
MessageBox(NULL, _T("WM_CREATE"), _T("WM_CREATE"), MB_OK);
}
virtual void OnDestroy()
{
DestroyWindow(m_hWnd);
}
virtual void OnClose()
{
PostQuitMessage(0);
}
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
OnCreate();
break;
case WM_CLOSE:
OnClose();
break;
case WM_DESTROY:
OnDestroy();
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
PWNDPROC CreateWndProc()
{
m_thunk.init(this, &CMyWnd::WndProc);
return (PWNDPROC)(&m_thunk);
}
void Create(HINSTANCE hInstance)
{
WNDCLASSEX wc;
ZeroMemory(&wc,sizeof(wc));
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = CreateWndProc();
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = _T("MyWnd");
wc.hInstance = hInstance;
RegisterClassEx(&wc);
m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("MyWnd"), _T("MyWnd"), WS_OVERLAPPEDWINDOW, 100, 100, 600, 400, NULL, NULL, hInstance, NULL);
ShowWindow(m_hWnd,SW_SHOWNORMAL);
UpdateWindow(m_hWnd);
MSG msg;
while(GetMessage(&msg, NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
private:
Thunk m_thunk;
HWND m_hWnd;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
CMyWnd myWnd;
myWnd.Create(hInstance);
return 0;
}
#include <TCHAR.h>
typedef LRESULT (CALLBACK *PWNDPROC)(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
template <class ToType, class FromType>
void GetMemberFuncAddr_VC6(ToType &addr,FromType f)
{
union
{
FromType _f;
ToType _t;
}ut;
ut._f = f;
addr = ut._t;
}
#pragma pack(push,1)
struct Thunk
{
BYTE m_mov;
DWORD m_pThis;
BYTE m_jmp;
DWORD m_relproc;
template<typename PTHIS, typename PFUN>
void init(PTHIS pThis, PFUN pFun)
{
DWORD FuncAddr;
GetMemberFuncAddr_VC6(FuncAddr, pFun);
m_mov = 0xb9;
m_pThis = (UINT_PTR)pThis;
m_jmp = 0xe9;
m_relproc = (UINT_PTR)((INT_PTR)FuncAddr - (INT_PTR)this-sizeof(Thunk));
::FlushInstructionCache(::GetCurrentProcess(), this, sizeof(Thunk));
}
};
#pragma pack(pop)
class CMyWnd
{
public:
CMyWnd(){}
~CMyWnd(){}
public:
virtual void OnCreate()
{
MessageBox(NULL, _T("WM_CREATE"), _T("WM_CREATE"), MB_OK);
}
virtual void OnDestroy()
{
DestroyWindow(m_hWnd);
}
virtual void OnClose()
{
PostQuitMessage(0);
}
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
OnCreate();
break;
case WM_CLOSE:
OnClose();
break;
case WM_DESTROY:
OnDestroy();
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
PWNDPROC CreateWndProc()
{
m_thunk.init(this, &CMyWnd::WndProc);
return (PWNDPROC)(&m_thunk);
}
void Create(HINSTANCE hInstance)
{
WNDCLASSEX wc;
ZeroMemory(&wc,sizeof(wc));
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = CreateWndProc();
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = _T("MyWnd");
wc.hInstance = hInstance;
RegisterClassEx(&wc);
m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("MyWnd"), _T("MyWnd"), WS_OVERLAPPEDWINDOW, 100, 100, 600, 400, NULL, NULL, hInstance, NULL);
ShowWindow(m_hWnd,SW_SHOWNORMAL);
UpdateWindow(m_hWnd);
MSG msg;
while(GetMessage(&msg, NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
private:
Thunk m_thunk;
HWND m_hWnd;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
CMyWnd myWnd;
myWnd.Create(hInstance);
return 0;
}