GLWindow
LRESULT CALLBACK GLWindow::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
The nonstatic window proc. This will handle all the messages and pass them off to the appropriate user defined method. The first thing we do is allow the user to handle the message, if handleMessage returns true, then we ignore the message. This is the main reason I needed to create the GLWindow class in the first place. I needed to intercept windows messages from a USB device and GLUT didn’t let me do this. The rest of the callbacks are obvious.
LRESULT CALLBACK
GLWindow::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// let user define their own message passing handler
// if true exit early, else let the defaults handle it
if(handleMessage(uMsg, wParam, lParam))
{
return 0;
}
switch(uMsg)
{
case WM_SYSCOMMAND: // Intercept System Commands
{
switch(wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break;
}
return 0;
// Window Create is taken care of in the static callback
case WM_CREATE: // Window Creation
return 0;
case WM_CLOSE: // Closing The Window
terminateApplication(); // Terminate The Application
return 0;
case WM_SIZE: // Size Action Has Taken Place
switch(wParam)
{
case SIZE_MINIMIZED: // Was Window Minimized?
isVisible = false; // Set isVisible To False
return 0;
case SIZE_MAXIMIZED: // Was Window Maximized?
isVisible = TRUE; // Set isVisible To True
reshape(LOWORD(lParam), HIWORD(lParam)); // Reshape Window - LoWord=Width, HiWord=Height
return 0;
case SIZE_RESTORED: // Was Window Restored?
isVisible = true; // Set isVisible To True
reshape(LOWORD(lParam), HIWORD(lParam)); // Reshape Window - LoWord=Width, HiWord=Height
return 0;
}
break;
case WM_KEYDOWN: // Update Keyboard Buffers For Keys Pressed
if((wParam >= 0) && (wParam < = 255)) // Is Key (wParam) In A Valid Range?
{
keys[wParam] = true; // Set The Selected Key (wParam) To True
return 0;
}
break;
case WM_KEYUP: // Update Keyboard Buffers For Keys Released
if((wParam >= 0) && (wParam < = 255)) // Is Key (wParam) In A Valid Range?
{
keys[wParam] = false; // Set The Selected Key (wParam) To False
return 0;
}
break;
// Handle mouse events
case WM_MOUSEMOVE:
onMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam);
break;
case WM_LBUTTONDOWN:
onLMouseDown();
break;
case WM_LBUTTONUP:
onLMouseUp();
break;
case WM_RBUTTONDOWN:
onRMouseDown();
break;
case WM_RBUTTONUP:
onRMouseUp();
break;
case WM_MBUTTONDOWN:
onMMouseDown();
break;
case WM_MBUTTONUP:
onMMouseUp();
break;
case WM_MOUSEWHEEL:
onMouseWheel(
GET_KEYSTATE_WPARAM(wParam),
(int)GET_WHEEL_DELTA_WPARAM(wParam),
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam));
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK GLWindow::staticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Static window proc. This is the actual window proc that get's the messages, and it actually handles the window create event. It grabs the this pointer that was sent in through CreateWindowEx earlier and then calls the non static window proc. This way, multiple objecst can have their own window proc's. Code taken from GameDev
static LRESULT CALLBACK staticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static GLWindow *pWindow = 0;
if(uMsg == WM_NCCREATE)
{
pWindow = (GLWindow *)((LPCREATESTRUCT)lParam)->lpCreateParams;
SetWindowLong(hWnd, GWL_USERDATA, (long)pWindow);
//If you process any messages that are sent before CreateWindowEx returns
//the HWND, you need something in the place of your HWND member.
pWindow->sethWnd(hWnd);
}
else
{
pWindow = (GLWindow *)GetWindowLong(hWnd, GWL_USERDATA);
}
if(pWindow)
{
return pWindow->windowProc(hWnd, uMsg, wParam, lParam);
}
else
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}