2D游戏编程1--windows编程模型
一.创建一个windows程序步骤
1.创建一个windows类
2.创建一个事件处理程序
3.注册windows类
4.用之前创建的windows类创建一个窗口
5.创建一个主事件循环
二.存储windows类信息的数据结构:
typedef struct _WNDCLASSEX { UINT cbSize; // size of this structure UINT style; // style flags WNDPROC lpfnWndProc; // function pointer to handler int cbClsExtra; // extra class info int cbWndExtra; // extra window info HANDLE hInstance; // the instance of the application HICON hIcon; // the main icon HCURSOR hCursor; // the cursor for the window HBRUSH hbrBackground; // the background brush to paint the window LPCTSTR lpszMenuName; // the name of the menu to attach LPCTSTR lpszClassName; // the name of the class itself HICON hIconSm; // the handle of the small icon } WNDCLASSEX
cbSize=sizeof(WNDCLASSEX);
style值:
winclass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLICKS;
CS_HREDRAW
Redraws the entire window if a movement or size adjustment changes the width of the window.CS_VREDRAW
Redraws the entire window if a movement or size adjustment changes the height of the window.CS_OWNDC
Allocates a unique device context for each window in the class (more on this later in the chapter).CS_DBLCLKS
Sends a double-click message to the window procedure when the user double-clicks the mouse while the cursor is in a window belonging to the class.CS_PARENTDC
Sets the clipping region of the child window to that of the parent window so that the child can draw on the parent.CS_SAVEBITS
Saves the client image in a window so you don't have to redraw it every time the window is obscured, moved, etc. However, this takes up more memory and is slower that doing it yourself.CS_NOCLOSE
Disables the Close command on the system menu.Note: The most commonly used flags are highlighted.
lpfnWndProc窗口事件处理函数指针:
完整定义:
WNDCLASSEX winclass; // this will hold the class we create
// first fill in the window class structure
inclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = "WINCLASS1";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
三.注册windows类
RegisterClassEx(&winclass);
四.创建窗口
HWND CreateWindowEx(
DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu, or child-window identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam); // pointer to window-creation data
HWND hwnd; // window handle // create the window, bail if problem if (!(hwnd = CreateWindowEx(NULL, // extended style "WINCLASS1", // class "Your Basic Window", // title WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0,0, // initial x,y 400,400, // initial width, height NULL, // handle to parent NULL, // handle to menu hinstance, // instance of this application NULL))) // extra creation parms return(0);
Once the window has been created, it may or may not be visible. However, in this case, we added the style flag WS_VISIBLE, which does this automatically. If this flag isn't added, use the following function call to manually display the window:
// this shows the window ShowWindow(hwnd, ncmdshow);
五.事件处理程序
WinProc原型:
LRESULT CALLBACK WindowProc(
HWND hwnd, // window handle of sender
UINT msg, // the message id
WPARAM wparam, // further defines message
LPARAM lparam); // further defines message
实例:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // this is the main message handler of the system PAINTSTRUCT ps; // used in WM_PAINT HDC hdc; // handle to a device context // what is the message switch(msg) { case WM_CREATE: { // do initialization stuff here // return success return(0); } break; case WM_COMMAND: { switch(LOWORD(wparam)) { // handle the FILE menu case MENU_FILE_ID_OPEN: { // do work here } break; case MENU_FILE_ID_CLOSE: { // do work here } break; case MENU_FILE_ID_SAVE: { // do work here } break; case MENU_FILE_ID_EXIT: { // do work here } break; // handle the HELP menu case MENU_HELP_ABOUT: { // do work here } break; default: break; } // end switch wparam } break; // end WM_COMMAND case WM_PAINT: { // simply validate the window hdc = BeginPaint(hwnd,&ps); // you would do all your painting here EndPaint(hwnd,&ps); // return success return(0); } break; case WM_DESTROY: { // kill the application, this sends a WM_QUIT message PostQuitMessage(0); // return success return(0); } break; default:break; } // end switch // process any messages that we didn't take care of return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc
六.主事件循环
// enter main event loop
while(GetMessage(&msg,NULL,0,0))
{
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end while
事件循环处理消息机制流程图: