70,020
社区成员




#pragma once
// CGlWnd
typedef LRESULT (CALLBACK* GLWindowProc)(HWND, UINT, WPARAM, LPARAM);
#pragma pack(push, 1)
struct sWndProc
{
BYTE op_movecx;
DWORD_PTR val_ecx;
BYTE op_call;
DWORD_PTR val_address;
};
#pragma pack(pop)
class CGlWnd
{
public:
CGlWnd();
virtual ~CGlWnd();
private:
HWND m_hWnd;
HGLRC m_hGLRC;
HDC m_hGLDC;
sWndProc m_WndProc;
public:
BOOL CreateGLWindow(LPCTSTR lpszWindowName, DWORD dwStyle, const CRect& rect, HWND hParent);
void DestoryGLWindow(GLvoid);
private:
GLvoid ResizeGLScene(GLsizei nWidth, GLsizei nHeight);
GLuint InitGL(GLvoid);
GLuint DrawGLScene(GLvoid);
GLvoid ShowGLWindow(GLuint nCmdShow);
GLWindowProc GetWndPrcEntry();
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
CGlWnd::CGlWnd()
: m_hWnd(NULL)
, m_hGLDC(NULL)
, m_hGLRC(NULL)
{
m_WndProc.op_movecx = 0xB9;
m_WndProc.val_ecx = (DWORD_PTR)this;
m_WndProc.op_call = 0xE9;
DWORD_PTR off = 0;
_asm
{
mov eax, CGlWnd::WndProc;
mov DWORD PTR [off], eax
}
m_WndProc.val_address =
off - ( (DWORD_PTR)(&m_WndProc.val_address) + sizeof(DWORD_PTR) );
}
GLWindowProc CGlWnd::GetWndPrcEntry()
{
return (GLWindowProc)&m_WndProc;
}
LRESULT CGlWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
BOOL CGlWnd::CreateGLWindow(LPCTSTR lpszWindowName, DWORD dwStyle, const CRect& rect, HWND hParent)
{
m_hInstance = ::GetModuleHandle(NULL);
WNDCLASS glwc;
glwc.cbClsExtra = 0;
//glwc.cbSize = sizeof(WNDCLASSEX);
glwc.cbWndExtra = 0;
glwc.hbrBackground = NULL;
glwc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
glwc.hIcon = ::LoadIcon(NULL, IDI_WINLOGO);
//glwc.hIconSm = NULL;
glwc.hInstance = ::GetModuleHandle(NULL);
glwc.lpfnWndProc = GetWndPrcEntry();
glwc.lpszClassName = _T("GLWindow");
glwc.lpszMenuName = NULL;
glwc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
if (!::RegisterClass(&glwc))
{
TRACE("注册OpenGL窗口类失败!\n");
return FALSE;
}
m_hWnd = ::CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, glwc.lpszClassName, lpszWindowName, WS_OVERLAPPEDWINDOW,
rect.left, rect.top, rect.Width(), rect.Height(), NULL, NULL, glwc.hInstance, NULL);