窗口和句柄
窗口是Windows应用程序中一个非常重要的元素,一个Windows应用程序至少要有一个窗口,称为主窗口。窗口是屏幕上的一块矩形区域,是Windows应用程序与用户进行交互的接口。利用窗口可以接收用户的输入、以及显示输出。
一个应用程序窗口通常都包含标题栏、菜单栏、系统菜单、最小化框、最大化框、可调边框,有的还有滚动条。如下图:
句柄(HANDLE)是Windows程序中一个重要的概念,使用也非常频繁。在Windows程序中,有各种各样的资源(窗口、图标、光标,画刷等),系统在创建这些资源时会为它们分配内存,并返回标识这些资源的标识号,即句柄。在后面的内容中我们还会看到图标句柄(HICON)、光标句柄(HCURSOR)和画刷句柄(HBRUSH)
WinMain函数
当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain函数(实际是由插入到可执行文件中的启动代码调用的)。
WinMain是 Windows程序的入口点函数,与DOS程序的入口点函数main的作用相同,当WinMain函数结束或返回时,Windows应用程序结束。
windows编程模型
一个完整的Win32程序(#include<windows.h>),该程序实现的功能是创建一个窗口,并在该窗口中响应键盘及鼠标消息,程序的实现步骤为:
1)WinMain函数的定义
2)创建一个窗口。
3)进行消息循环。
4)编写窗口过程函数。
#include <windows.h> //底层实现窗口头文件
//6
LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hwnd);//触发WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
/*int xPos;
int yPos;*/
MessageBoxW(hwnd,TEXT("HEELO"),TEXT("鼠标按下"),MB_OK);
break;
default:
break;
}
//默认方式处理
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
//函数入口
//WINAPI 代表_stdcall 参数传递顺序从右往左依次入栈,并且在函数返回前自动清空堆栈内容
//WinMain 函数入口
//HINSTANCE hInstance 应用程序的实例句柄
//HINSTANCE hPrevInstance 前一个应用程序的实例句柄,在win32环境下,基本值NULL,不起作用
//LPSTR lpCmdLine 命令行参数
//int nShowCmd 窗口显示命令 最大化最小化
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
//实现底层窗口,6个步骤
//1、设计窗口类
//2、注册窗口类
//3、创建窗口类
//4、更新窗口
//5、通过循环取消息
//6、处理消息(窗口过程)
//1
WNDCLASS wc;
wc.cbClsExtra = 0;//类额外的内存,通常为0
wc.cbWndExtra = 0;//窗口额外的内存,通常为0
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标,如果第一个参数为null,代表使用系统提供的默认光标
wc.hIcon = LoadIcon(NULL, IDI_WARNING);//设置图标
wc.hInstance = hInstance; //当前实例句柄,winmain函数中形参即可
wc.lpfnWndProc = WindowProc;//窗口过程函数,回调函数
wc.lpszClassName = TEXT("WINDOW");//指定窗口类名
wc.lpszMenuName = NULL;//菜单名
wc.style = 0;//默认窗口风格
//2
RegisterClass(&wc);
//3
HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("TEXT WINDOW"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
//4
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//5
MSG msg;
while (1)
{
if (GetMessage(&msg, NULL, 0, 0) == FALSE) break;
//翻译消息
TranslateMessage(&msg);
//分发消息
DispatchMessage(&msg);
}
return 0;
}