您的位置:首页 > 其它

Thunk技术封装好的win32项目窗口类

2014-09-27 18:52 302 查看
转载请注明出处:http://blog.csdn.net/hhhhhhhhhhkkkkkkkkkk/article/details/39613887

由于windows API写窗口有点麻烦而单调,而普通的类成员函数不能用作回调函数,所以在这里发一个用Thunk技术封装好的窗口类,方便调试。里面有部分封装的事件接口,可以根据需要自行扩展。

class MainWindow
{
public:
HWND m_hWnd;
private:
#pragma pack(push,1)
struct THUNK
{
DWORD m_mov; // = 0x042444C7
DWORD m_this; // = this
BYTE m_jmp; // = 0xe9
DWORD m_relproc; // = relative distance
}*thunk;
#pragma pack(pop)
public:
MainWindow() :m_hWnd(NULL){}
~MainWindow()
{
VirtualFree(thunk, sizeof(THUNK), MEM_RELEASE);
}
bool Create()
{
WNDCLASSEX wcex;
LPCTSTR lpszClassName = _T("ClassName");
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MainWindow::TempWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALL));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MY);
wcex.lpszClassName = lpszClassName;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassEx(&wcex);
thunk = (THUNK *)VirtualAlloc(NULL, sizeof(THUNK), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
thunk->m_mov = 0x042444c7;
thunk->m_jmp = 0xe9;
//CreateWindow的最后一个参数为this指针
CreateWindow(lpszClassName, NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), this);
if (m_hWnd == NULL)return false;
ShowWindow(m_hWnd, SW_SHOW);
UpdateWindow(m_hWnd);
///////
MSG msg;
HACCEL hAccelTable = LoadAccelerators(GetModuleHandle(NULL), MAKEINTRESOURCE(IDC_MY));
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return TRUE;
}
protected:
//辅助回调函数
static LRESULT CALLBACK TempWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_CREATE)//此处使用WM_NCCREATE消息也可以
{
//提取出对象指针
MainWindow *w = NULL;
w = (MainWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
w->m_hWnd = hWnd;
WNDPROC pWndProc = (WNDPROC)w->thunk;
w->thunk->m_this = (DWORD)w;

//计算跳转位置
w->thunk->m_relproc = (DWORD)&MainWindow::StaticWndProc - ((DWORD)w->thunk + sizeof(THUNK));

SetWindowLong(hWnd, GWL_WNDPROC, (LONG)pWndProc);
return pWndProc(hWnd, message, wParam, lParam);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return ((MainWindow *)hWnd)->WndProc(message, wParam, lParam);
}
protected:
//主回调函数
virtual LRESULT CALLBACK WndProc(UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE:
OnCreate();
break;
case WM_MOUSEMOVE:
OnMouseMove(LOWORD(lParam), HIWORD(lParam));
break;
case WM_LBUTTONDOWN:
OnLButtonDown(LOWORD(lParam), HIWORD(lParam));
break;
case WM_LBUTTONUP:
OnLButtonUp(LOWORD(lParam), HIWORD(lParam));
break;
case WM_TIMER:
OnTimer();
break;
case WM_PAINT:
hdc = BeginPaint(m_hWnd, &ps);
OnPaint(hdc);
EndPaint(m_hWnd, &ps);
break;
case WM_SIZE:
GetClientRect(m_hWnd, &rect);
OnSize(rect);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(m_hWnd, message, wParam, lParam);
break;
}
return TRUE;
}
public:
virtual void OnCreate()
{

}
virtual void OnMouseMove(int mouseX, int mouseY)
{

}
virtual void OnLButtonDown(int mouseX, int mouseY)
{

}
virtual void OnLButtonUp(int mouseX, int mouseY)
{

}
virtual void OnTimer()
{

}
virtual void OnPaint(HDC&hdc)
{

}
virtual void OnSize(RECT&rect)
{

}

};


调用方式:

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{

MainWindow window;
window.Create();
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  thunk win32 windows api