Windows应用程序初始框架详细注解

来源:互联网 发布:网络管理维护 编辑:程序博客网 时间:2024/06/06 16:30

该程序包含了WinMain函数、WNDCLASS结构、CreateWindow函数、tagMSG结构、MessageBox函数等的解析,参考:Introduction to 3D Game Programming with DirectX 11附录1,MSDN。

程序流程:

1. 初始化窗口类并注册;

2. 创建窗口;

3. 执行消息循环,如果有消息,调用WndProc函数,否则转4;

4. 图形渲染,游戏逻辑等。

#include <windows.h>/** 创建主窗口句柄:在windows编程中,经常用句柄(handle)来引用由windows内部维护的对象。* 很多API的调用需要传递该参数。*/HWND mainWnd = 0;bool initWndApp(HINSTANCE hInstance, int show);int run();LRESULT CALLBACKWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);/** hInstance:当前应用程序实例的句柄,可能有多个应用程序同时运行* hPreInstance:该参数不在Win32编程中使用* pCmdLine:命令行参数字符串* nShowCmd:指定应用程序的显示方式,*SW_SHOW:按当前大小和位置,*SW_SHOWMAXIMIZED:最大化,*SW_SHOWMINIMIZED:最小化*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR pCmdLine, int nShowCmd){if ( !initWndApp(hInstance, nShowCmd) ){return 0;}return run();}

WINAPI声明符强制参数从左边向右边传递,而默认的CDECL声明符使参数从右到左转移。

lpcmdline相当于C语言main函数的参数char **argv。比如在命令行带参数的运行test.exe:

test.exe hellow

lpcmdline = "hellow"

typedef struct _WNDCLASSEX {UINT cbSize;UINT style;WNDPROC lpfnWndProc;int cbClsExtra;int cbWndExtra;HANDLE hInstance;HICON hIcon;HCURSOR hCursor;HBRUSH hbrBackground;LPSTR lpszMenuName;LPSTR lpszClassName;HICON hIconSm;}WNDCLASS;

  • style: 指定类的风格,CS_HREDRAW和CS_VREDRAW的组合表示,窗口水平和垂直方向上大小改变时要重绘
  • cbSize:  结构体的大小
  • lpfnWndProc: 指向windows过程函数的指针,该函数与指定的WNDCLASS对象相关联
  • cbClsExtra, cbWndExtra:  可以额外使用的内存空间,
  • hIcon: 图标句柄
  • hCursor: 光标句柄
  • hbrBackground: 背景刷句柄
  • lpszMenuName: 指定窗口菜单
  • lpszClassName: 指定窗口类结构的名称,方便后面引用

bool initWndApp(HINSTANCE hInstance, int show){WNDCLASSEX wc;wc.cbSize = sizeof(WNDCLASSEX);wc.hInstance = hInstance;wc.lpfnWndProc = WndProc;wc.style = CS_HREDRAW | CS_VREDRAW;wc.cbClsExtra = 0;wc.cbWndExtra = 0;//使用默认的应用程序图标和光标wc.hIcon = LoadIcon(0,IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_CROSS);//调用win32函数GetStockObject()返回白色画刷句柄wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);wc.lpszMenuName = 0;wc.lpszClassName = L"BasicWndClass";//注册填好的WNDCLASS实例,以此创建窗口if ( !RegisterClass(&wc)) {MessageBox(0, L"RegisterClass Failed", 0, 0);return false;}mainWnd = CreateWindow(L"BasicWndClass", L"Win32Basic",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,0, 0, hInstance, 0);if (mainWnd == 0) {MessageBox(0, L"CreateWindow FAILED", 0, 0);return false;}ShowWindow(mainWnd, show);UpdateWindow(mainWnd);return true;}//HWND CreateWindow(//LPCTSTR lpClassName,//LPCTSTR lpWindowName,//DWORD dwStyle,//int x,//int y,//int nWidth,//int nHeight,//HWND hWndParent,//HMENU hMenu,//HANDLE hInstance,//LPVOID lpParam//);/** lpClassName:注册的WNDCLASS类的名称* lpWindowName:窗口名称,将显示在标题栏* dwStyle:定义窗口风格* x, y:窗口左上角坐标* nWidth, nHeight:窗口的宽和高,可指定为默认的CW_USEDEFAULT* hWndParent:父窗口句柄,没有为0* hMenu:菜单句柄,没有为0* hInstance:应用程序句柄* lpParam:指向用户定义类型的指针,如果需要用到WM_CREATE消息句柄。该消息在窗口创建时发出,*一般用于在创建窗口时进行一些初始化。*///typedef struct tagMSG{//HWND hwnd;//UNIT message;//WPARAM wParam;//LPARAM lParam;//DWORD time;//POINT pt;//}MSG;/** hwnd:用于接收消息的窗口句柄* message:消息标示,如:WM_QUIT* wParam, lParam:消息的额外信息* time:消息发出的时间* pt:消息发出时,鼠标光标在屏幕坐标系中的坐标(x,y)*/int run(){MSG msg = {0};BOOL bRet = 1;//while ( (bRet = GetMessage(&msg,0,0,0)) != 0 ) {////返回-1表示GetMessage出现错误////返回0 表示收到WM_QUIT消息,需要终止消息循环,////返回其他值时,先TranslateMessage,Windows会做一些键盘转换,////特别是将按键转换成字符消息;然后DispatchMessage将消息发送给////合适的窗口过程//if (bRet == -1) {//MessageBox(0, L"GetMessage FAILED", L"Error", MB_OK);//}else {//TranslateMessage(&msg);//DispatchMessage(&msg);//}//}// 当消息队列中没有消息时,GetMessage会将进程挂起,直到收到消息。// 对于游戏程序,我们并不想这样。在没有消息的时候我们需要做游戏相关的事。// PeekMessage在没有消息时会立即返回while (msg.message != WM_QUIT) {if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {TranslateMessage(&msg);DispatchMessage(&msg);}else {//do animation/game stuff}}return (int)msg.wParam;}

int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );

  • hWnd: 该消息父窗口的句柄,NULL表示该消息盒子父窗口为桌面
  • lpText: 在盒子中显示的信息
  • lpCaption:盒子的标题,如果是NULL,则默认为Error
  • uType: 指定盒子的内容和行为,
    MB_OK 表示会有一个OK键,类似的还有MB_OKCANCLE,MB_YESNO等
    MB_ICONEXCLAMATION 表示显示一个惊叹号图标,类似的有MB_ICONINFORMATION,MB_ICONQUESTION,MB_ICONSTOP,分别表示I图标,问号图标,终止符图标。MB_DEFBUTTONn 控制默认高亮的按钮,n=1-4
  • 返回值,例如,IDYES表示按下了YES按钮,该返回值可以用来测试用户按下的是哪个键。

//WndProc是一个回调函数,Windows将在程序的代码空间外调用该函数//用于处理收到的消息,如按键,鼠标点击等。/** hWnd:接受消息的窗口* msg:接受的消息,如:WM_QUIT* wParam, lParam:消息的额外信息*/LRESULT CALLBACKWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_CREATE:MessageBox(0, L"窗口创建成功!", L"Create", 0);return 0;case WM_LBUTTONDOWN:MessageBox(0, L"你好!", L"Hello", MB_OK);return 0;case WM_KEYDOWN://如果按下Escape键,DestroyWindow销毁主窗口//wParam参数保存着虚拟键码(Virtual key code)if (wParam == VK_ESCAPE){DestroyWindow(mainWnd);}return 0;case WM_CLOSE://关闭窗口时提示是否要退出if (MessageBox(0, L"确定要退出吗?", L"Exit",MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDYES){PostQuitMessage(0);}return 0;case WM_DESTROY://当窗口销毁时,发出WM_QUIT消息,退出消息循环PostQuitMessage(0);return 0;}//最后调用默认Windows过程函数,处理其他消息return DefWindowProc(hWnd, msg, wParam, lParam);}
  • WM_CREATE,当窗口第一次创建的时候传递该消息,以便进行一些初始化或资源分配。
  • WM_DESTROY,在关闭窗口时被发送。当然,这仅仅是关闭窗口,而不是终止应用程序。必须通过发送WM_QUIT消息,来终止消息循环,从而终止应用程序。


原创粉丝点击