Windows窗口的创建

要写游戏嘛,首先肯定要有个窗口,今天我会跟大家分析窗口的编写,以及分享一些我的错误经验,(*^__^*) 嘻嘻

在这里我们写的是Windows应用程序,所以要要建立的工程是Win32 Application,注意不是以前的Win32 Console Application。由于使用Windows API,建议大家下一个MSDN Library,用来查看各种Windows库函数。在Windows应用程序里我们的程序入口不是以前在学C/C++基础时写的main函数了,而是WinMain函数,下面贴出WinMain函数原型


int WINAPI WinMain( 

HINSTANCE hInstance, // handle to current instance

HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state

);

hInstance是应用程序实例句柄,标识当前运行的程序

hPrevInstance是上一个窗口的实例,目前暂时用不到,就先不说啦

lpCmdLine是一个指向应用程序命令行的指针,暂时也用不到

nCmdShow是窗口运行一开始的显示状态,比如:最大化、还原、最小化


下面就要在WinMain函数里写窗口,这要经历6个步骤,即设计窗口类(看下面其实是结构体,我也纳闷为什么微软的函数里要说是窗口类,这些不管了,意会就好了)、注册窗口类、创建窗口、更新窗口、显示窗口、消息循环响应

因为微软已经给我们写好了窗口类,所以所谓的设计窗口类就是初始化一个窗口类对象


typedef struct _WNDCLASSEX {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX; 

cbSize是指这个结构体的大小,用sizeof(WMDCLASSES)赋值

style是窗口的类型,一般选用CS_HREDRAW | CS_VREDRAW或者CS_CLASSDC赋值

lpfnWndProc指向窗口的回调函数,Windows编程是采用消息响应机制,所以需要一个回调函数来响应消息,让俺开心的是微软已经帮我们写好了回调函数的原型,如下:


LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);

hwnd是一个窗口句柄,以为一个进程对应好多好多个窗口,我们需要一个句柄来标识当前窗口

uMsg是系统接收的消息(前面已经说过Windows是消息响应机制)

wParam是第一个消息参数,一般用来存储键盘按下的消息

lParam是第二个消息参数,一般用来存储鼠标的位置

好了,我们继续回到WNDCLASSEX

cbClsExtra和cbWndExtra是注册窗口类需要的额外的空间,一般不需要,我们设置为0

hInstance没啥好说的,直接用WinMain参数里的hInstance赋值,表示当前应用程序句柄

hIcon是图标资源句柄,表示进程在任务栏里的图标,可以用LoadImage函数来载入图片资源

hCursor是鼠标句柄,可以用LoadImage来给鼠标换个图标

hbrBackground是个画刷句柄,设置窗口的背景颜色

lpszMenuName是菜单名字,我们暂时用不到,先设为NULL

lpszClassName是窗口类的名字

hIconSm是窗口做上角图标句柄,同样可以用LoadImage来载入图标资源


为窗口结构体的各个属性赋值完之后我们就要调用RegisterClassEx函数来注册窗口类了

注册完窗口类,接下来就是创建窗口句柄了(也就是创建窗口),用CreateWindow函数

然后呢就是调用ShowWindow和UpdateWndow函数来显示和更新窗口了

最后就是写一下查看消息队列的代码啦, 用PeekMessage函数,要注意PeekMessage和GetMessage的区别哦o(∩_∩)o 

一下区别摘自http://www.cnblogs.com/faceang/archive/2010/05/25/1743757.html

无论应用程序消息队列是否有消息,PeekMessage函数都立即返回,程序得以继续执行后面的语句(无消息则执行其它指令,有消息时一般要将消息派发出去,再执行其它

指令)。GetMessage函数只有在消息对立中有消息时返回,队列中无消息就会一直等,直至下一个消息出现时才返回。在等的这段时间,应用程序不能执行任何指令。


以下贴出建立窗口示例代码

#include<windows.h>

#define WINDOW_CLASS "Demo" //用宏来定义窗口类的名字
#define WINDOW_NAME "CreateWindow" //定义窗口实例的名字
#define WINDOW_WIDTH 640 //定义窗口的宽度
#define WINDOW_HEIGHT 480 //定义窗口的高度

HWND hWnd; //窗口实例句柄

//定义回调函数
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
//如果接收到用户点窗口右上角的x
case WM_CLOSE:
MessageBox(hWnd, "您点击了关闭图标,即将关闭窗口诶~~", "你好哇", MB_OK);
DestroyWindow(hWnd);
break;

//如果接收到销毁窗口的消息就调用PostQuitMessage来销毁窗口
case WM_DESTROY:
PostQuitMessage(0);
break;

//如果没有消息就调用系统默认的回调函数
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

return 0;
}

int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WNDCLASSEX wcex;

wcex.cbClsExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //如果使用微软提供鼠标图标,第一个参数要设为NULL
wcex.hIcon = NULL;
wcex.hIconSm = NULL;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WindowProc;
wcex.lpszClassName = WINDOW_CLASS;
wcex.lpszMenuName = NULL;
wcex.style = CS_CLASSDC;

RegisterClassEx(&wcex);

hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
350, 120, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

MSG msg; 
ZeroMemory(&msg, sizeof(msg));

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //捕获消息
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

}

UnregisterClass(WINDOW_CLASS, wcex.hInstance);  //注销窗口类

return 0;
}


注意return DefWindowProc(hwnd, uMsg, wParam, lParam);这句代码,里面的窗口句柄一定要用回调函数参数里的窗口句柄参数哦,虽然全局变量hWnd已赋值,但是不能用在这里啊,不信你试试,窗口是显不出来滴,好了,说到这里我也累了,各位小伙伴有兴趣的话可以根据msdn自己试试窗口类里的各个变量的不同赋值哦,见证奇迹的时候到了






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值