写出一个窗口
之前我们简单的认识了一下win32主函数,下面我们来讨论一下如何用这个主函数作为起点来写出一个win32窗口程
序。
int WINAPI WinMain(
HINSTANCEhInstance,// handle to current instance
HINSTANCEhPrevInstance,// handle to previous instance
LPSTRlpCmdLine,// command line
intnCmdShow // show state);
这个函数有四个参数,
①第一参数是应用程序实例句柄,应用程序实例句柄是啥?这里先简单理解为是一个标号,是操作系统为了区分系统中不同进程的,我觉得也可能是一个指针什么的。
②第二个参数是之前一个程序的实例句柄,也就是这个程序或者是窗口可能是被别的程序调用或者是其他窗口的子窗口。这个指针会指向那个调用者。
③第三个参数是命令行参数,可以输入一个命令,目前没啥用,不多讲了。
④第四个参数是窗口最开始显示的模式,一般不用我们把这个设置为0。
好了,开始写主函数的内容。下面的代码是写在主函数里的。
不行,这里我要先说一些事情。
创建一个窗口应用程序的基本步骤(有些是我自己的土话,可能缺少专业术语):
①创建窗口类,这里面有好多关于创建窗体样式,大小等参数
②注册窗口类,为啥有个注册的步骤,个人觉得可能你要调用系统什么资源了,或者创建窗口需要有个登记才能让你用
③然后就可以创建一个窗口了,根据你最开始窗口类里面那些参数,可以创建一个你想要的窗口。
④准备工作都做好了就开始显示窗口了
⑤最后是消息循环,你对窗口发送的消息由一个循环不断的接受并且处理
这回我们可以进入代码部分了,开始可能枯燥,很快这段就过去了。
WNDCLASS 这个是结构体,这个有啥用呢?我觉得就是把你要创建的窗口的参数都写进去,到时候让系统根据这个配
置单子给你创建一个窗口,这个就像你在电脑城装电脑的配置单子,我们看看这个单子需要填啥。
WNDCLASS window;
window.lpfnWndProc = WinProc; //回调函数指针
window.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW; //窗口样式
window.cbClsExtra = 0; //窗口类的附加内存,取0
window.cbWndExtra = 0; //窗口的附加内存,取0就行了
window.hInstance = hInstance; //包含窗口过程的程序的实例句柄。
window.hIcon = LoadIcon(NULL, IDI_APPLICATION); //程序的图标。默认
window.hCursor = LoadCursor(NULL, IDC_ARROW); //程序中的光标。默认
window.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); //程序的背景颜色
window.lpszMenuName = NULL; //菜单名字,没有,写空
window.lpszClassName = "GameCore"; //窗口类名
window.lpfnWndProc = WinProc; //回调函数指针
window.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW; //窗口样式
window.cbClsExtra = 0; //窗口类的附加内存,取0
window.cbWndExtra = 0; //窗口的附加内存,取0就行了
window.hInstance = hInstance; //包含窗口过程的程序的实例句柄。
window.hIcon = LoadIcon(NULL, IDI_APPLICATION); //程序的图标。默认
window.hCursor = LoadCursor(NULL, IDC_ARROW); //程序中的光标。默认
window.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); //程序的背景颜色
window.lpszMenuName = NULL; //菜单名字,没有,写空
window.lpszClassName = "GameCore"; //窗口类名
这是一段小代码,看看注释,应该没有什么大问题,建议最好有一个msdn,里面每个参数都有详细的解释。我们目前的目的只是写一个窗口,多余的我就不说了。这段代码就是填写一个窗口类。现在我们的配置单子填好了,去注册一下。
if (!RegisterClass(&window))
//对窗口类进行注册,这才能创建该类型的窗口
return -1;
return -1;
窗口注册完了,该创建窗口了,用如下的代码来创建我们的窗口
//创建窗口
HWND hWnd;
hWnd = CreateWindow("GameCore",
"Game",
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
NULL,
NULL,
hInstance,
NULL);
HWND hWnd;
hWnd = CreateWindow("GameCore",
"Game",
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
NULL,
NULL,
hInstance,
NULL);
这个HWND类型的变量以后我们可能会多次用到,那个是窗口句柄,、。现在我们已经创建了一个窗口,这个函数有好几个参数,我们暂时先不去管那个是什么,先看看一个窗口大概是怎么写出来的,然后我们在细说。
//显示窗口
ShowWindow(hWnd, SW_SHOWNORMAL);
ShowWindow(hWnd, SW_SHOWNORMAL);
然后显示窗口,到这里,大概窗口就出来了,然后是一个消息循环,就是窗口要不断接受我们给它的消息然后进行处理,
MSG msgs;
while (TRUE)
{
if (PeekMessage(&msgs, NULL, 0, 0, PM_REMOVE))
{
if (msgs.message == WM_QUIT)
break;
TranslateMessage(&msgs);
DispatchMessage(&msgs);
}
UnregisterClass("GameCore", window.hInstance); //程序准备结束,注销窗口类
while (TRUE)
{
if (PeekMessage(&msgs, NULL, 0, 0, PM_REMOVE))
{
if (msgs.message == WM_QUIT)
break;
TranslateMessage(&msgs);
DispatchMessage(&msgs);
}
UnregisterClass("GameCore", window.hInstance); //程序准备结束,注销窗口类
这是一个消息循环,现在我们还差一个执行消息的函数,也就是回掉函数。好啦,下回分解。