1. 窗口
窗口是 Windows 应用程序中一个非常重要的元素,一个 Windows 应用程序至少要有一个窗口,称为主窗口。窗口是 Windows 应用程序与用户进行交互的接口。利用窗口可以接收用户的输入、以及显示输出。
窗口可以有一个父窗口, 有父窗口的窗口称为子窗口。
2.句柄
在 Windows 应用程序中, 窗口是通过窗口句柄( HWND) 来标识的。 我们要对某个窗口进行操作, 首先就要得到这个窗口的句柄。
句柄( HANDLE) 是 Windows 程序中一个重要的概念, 使用也非常频繁。 在 Windows 程序中, 有各种各样的资源( 窗口、 图标、光标,画刷等), 系统在创建这些资源时会为它们分配内存, 并返回标识这些资源的标识号, 即句柄。
3.Windows消息处理过程
Windows 是基于消息的程序设计,每一个 Windows 应用程序开始执行后, 系统都会为该程序创建一个消息队列, 这个消息队列用来存放该程序创建的窗口的消息。
然后应用程序通过一个消息循环不断地从消息队列中取出消息,并进行响应。
在这个处理过程中,操作系统也会给应用程序“ 发送消息”。所谓“ 发送消息”,实际上是操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程。
4.窗口入口函数–WinMain
函数定义:、
WINAPI代表_stdcall参数的传递顺序,从右到左依次入栈,并且在函数返回前清空堆栈
hInstance://应用程序实例句柄
hPrevInstance://上一个应用程序句柄,在win32环境下,参数一般为NULL不起作用
lpCmdLine://char* argv[];命令行输入操作
nShowCmd ://显示命令 最大化、最小化、正常
int WINAPI CALLBACK WinMain(
__in HINSTANCE hInstance,
__in_opt HINSTANCE hPrevInstance,
__in LPSTR lpCmdLine,
__in int nShowCmd )
1.声明WNDCLASS变量
WNDCLASS win;
win.cbClsExtra = 0; //类额外内存
win.cbWndExtra = 0;//窗口额外内存
win.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//窗口背景
win.hCursor = LoadCursor(NULL,IDC_ARROW); //光标样式
win.hIcon = LoadIcon(NULL,IDI_APPLICATION);//图标
win.hInstance = hInstance;//应用程序实例
win.lpfnWndProc = WindowProc;//窗口处理函数
win.lpszClassName = TEXT("MFC1");//窗口类名称
win.lpszMenuName = NULL;//菜单名
win.style = 0;//默认为0
2.注册
RegisterClass(&win);
3.窗口创建
HWND hwnd = CreateWindow(
win.lpszClassName,
TEXT("WINDOWS"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,NULL,
hInstance,NULL);
/*
lpClassName, 类名
lpWindowName,标题名
dwStyle, 风格通常是要用WS_OVERLAPPEDWINDOW
x, 坐标 有默认值
y,
nWidth, 宽高
nHeight,
hWndParent, 父窗口,没有填NULL
hMenu, 菜单NULL
hInstance, 实例句柄 hinstance
lpParam 附加值NULL
*/
4.显示、更新
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
5.取消息、翻译与分发
/* GetMessage函数形参
__out LPMSG lpMsg, 消息
__in_opt HWND hWnd, 捕获窗口 填NULL 代表捕获所有窗口
__in UINT wMsgFilterMin, 过滤最小和最大的过滤消息,一般写0
__in UINT wMsgFilterMax*/
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
/* GetMessage函数形参
__out LPMSG lpMsg, 消息
__in_opt HWND hWnd, 捕获窗口 填NULL 代表捕获所有窗口
__in UINT wMsgFilterMin, 过滤最小和最大的过滤消息,一般写0
__in UINT wMsgFilterMax*/
//if (GetMessage(&msg,NULL,0,0) == FALSE) //点×了就退出,获取消息为false值退出
//{
// break;
//}
//翻译消息:比如说组合键
TranslateMessage(&msg);
//不为false
//分发消息
DispatchMessage(&msg);
}
6.消息处理函数
//CALLBACK代表_stdcall参数的传递顺序,从右到左依次入栈,并且在函数返回前清空堆栈
LRESULT CALLBACK WindowProc(
HWND hwnd,//消息所属的窗口句柄
UINT uMsg,//具体的消息名称 WM_XXXX 消息名
WPARAM wParam,//键盘附加消息
LPARAM lParam//鼠标附加消息
)
{
switch(uMsg)
{
case WM_CLOSE:
//所有以XXXwindow为结尾的方法,都不会进入到消息队列中,而是直接执行,直接窗口过程
DestroyWindow(hwnd);//并不是结束进程,知识简单的关闭窗口,发送另个消息WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);//发送一个退出消息,到下面的getmessae函数中退出,结束进程
break;
case WM_LBUTTONDOWN://鼠标左键按下
{
MessageBox(hwnd,TEXT("aaa"),TEXT("鼠标左键按下"),MB_OK);
break;
}
case WM_KEYDOWN://键盘
MessageBox(hwnd,TEXT("键盘按下"),TEXT("键盘按下"),MB_OK);
break;
case WM_PAINT://绘图
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
TextOut(hdc,100,100,TEXT("HELLO"),strlen("HELLO"));
EndPaint(hwnd,&ps);
break;
}