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窗口事件处理函数指针:

image

完整定义:

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

事件循环处理消息机制流程图:

image

原文地址:https://www.cnblogs.com/seebro/p/3315531.html