win32编程 -- 消息机制(一)

你多少岁不重要,看起来像几岁才重要,不要把辛苦和怨气都挂在脸上,你想要最好的生活,就先让生活看到最好的你。。。。

----  网易云热评

 

一、程序执行机制

1、过程驱动 - 程序的执行过程是按照预定好的顺序执行。   

2、事件驱动 - 程序的执行是无序,用户可以根据需要随机触发相应的事件。

3、Win32窗口程序就是采用 事件驱动 方式执行,也就是 消息机制。

4、当系统通知窗口工作时,就采用消息的方式派发给窗口。

 

二、消息组成(windows平台下)

窗口句柄

消息ID 0-1023

消息的两个参数(两个附带信息) 

消息产生的时间 

消息产生时的鼠标位置

 

三、窗口处理函数和消息

1、每个窗口都必须具有窗口处理函数。

LRESULT CALLBACK WindowProc(       HWND hwnd,           //窗口句柄       UINT uMsg,           //消息ID       WPARAM wParam,       //消息参数       LPARAM lParam               //消息参数);

2、当系统通知窗口时,会调用窗口处理函数同时,将消息ID和消息参数传递给窗口处理函数。 

3、在窗口处理函数中,不处理的消息,使用默认窗口处理函数,例如DefWindowProc。

 

四、消息相关函数

1、GetMessage - 获取消息

BOOL GetMessage(       LPMSG lpMsg,  //存放获取到的消息BUFF       HWND hWnd,           //接收窗口句柄,如果是空,所有消息都管       UINT wMsgFilterMin,//获取消息的最小ID  0,如果是0,所有消息id都管       UINT wMsgFilterMax  //获取消息的最大ID 0);

lpMsg - 当获取到消息后,将消息的参数存放到MSG结构中。 

hWnd - 获取到hWnd所指定窗口的消息。 

wMsgFilterMin和wMsgFilterMax -只能获取到由它们指定的消息范围内的消息,如果都为0,表示没有范围。

2、TranslateMessage - 翻译消息。将按键消息,翻译成字符消息。    

BOOL TranslateMessage(       CONST MSG* lpMsg     //要翻译的消息地址)

检查消息是否是按键的消息,如果不是按键消息,不做任何处理,继续执行。 

3、DispatchMessage - 派发消息。将消息派发到该消息所属窗口的窗口处理函数上

LRESULT DispatchMessage(       CONST MSG* lpmsg     //要派发的消息);

 

五、windows常用消息

1、WM_DESTROY:窗口被销毁时的消息,无消息参数。常用于在窗口被销毁之前,做相应的善后处理,例如资源、内存等。

2、WM_SYSCOMMAND:系统命令消息,当点击窗口的最大化、最小化、关闭等命令时,收到这个消息。常用在窗口关闭时,提示用户处理。    

wParam:具体点击的位置,例如关闭SC_CLOSE等.      

lParam:鼠标位置           

LOWORD:低字,水平位置         

HIWORD:高字,垂直位置

3、WM_CREATE:在窗口创建成功还未显示之前,收到这个消息。常用于初始化窗口的参数、资源等等,包括创建子窗口等。        

WPARAM:不使用,LPARAM:是CREATESTRUCT结构的指针,保存了CreatWindowEx中的12个参数。 

4、WM_SIZE:在窗口的大小发生变化后,会收到WM_SIZE。常用于窗口大小变化后,调整窗口内各个部分的布局。

WPARAM:窗口大小变化的原因。    

LPARAM:变化窗口客户区的大小         

LOWORD:变化后的宽度         

HIWORD:变化后的高度

5、WM_QUIT:用于结束消息循环处理。

wParam:PostQuitMessage 函数传递的参数。

lParam:不使用,当GetMessage收到这个消息后,会返回FALSE, 结束while处理,退出消息循环。 

6、WM_PAINT:绘图消息 键盘消息 鼠标消息 定时器消息

7、相关代码

HINSTANCE g_hInstance = 0;//接收当前程序实例句柄HANDLE g_接受句柄 = 0;//接收标准输出句柄HWND g_编辑框句柄 = 0;//窗口创建前所做的事情void 创建前(HWND hWnd, LPARAM lParam){       CREATESTRUCT* pcs = (CREATESTRUCT*)lParam;       char* str = (char*)pcs->lpCreateParams;       MessageBox(hWnd,(LPCWSTR)str , L"哎呦", MB_OK);       }//DOS窗口void DOS窗口(HWND hWnd, LPARAM lParam){       int DOS高 = LOWORD(lParam);       int DOS宽 = HIWORD(lParam);       MoveWindow(g_编辑框句柄, 0, 0, DOS宽, DOS高, TRUE);//移动窗口,控件随窗口变化       wchar_t szText[256] = {};              swprintf_s(szText, L"宽:%d,高:%d\n", DOS宽, DOS高);       WriteConsole(g_接受句柄,szText, wcslen(szText)  ,NULL,NULL);}//窗口上摆放编辑框void 摆放控件(HWND hWnd){       g_编辑框句柄= CreateWindowEx(0,L"EDIT",L"",WS_CHILD|WS_VISIBLE|WS_BORDER,              0,0,500,500,hWnd,NULL,g_hInstance,NULL);       }//2、消息处理函数LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID,       WPARAM wParam, LPARAM lParam){       //7、处理消息       switch (msgID)       {       case WM_SIZE:              DOS窗口(hWnd,lParam);              break;       case WM_CREATE:              创建前(hWnd,lParam);              摆放控件(hWnd);              break;       case WM_SYSCOMMAND:              //MessageBox(hWnd,L"哎呦",L"不错哦",MB_OK);              if (wParam==SC_CLOSE)              {                     BOOL res= MessageBox(hWnd, L"要关闭么?", L"不错哦",  MB_YESNO);                     if (res==IDYES)                     {                           //不用写,自动处理                     }                     else                     {                           return 0;                     }              }              break;       case WM_DESTROY:              PostQuitMessage(0);//销毁窗口              break;       }       return DefWindowProc(hWnd, msgID, wParam, lParam);}//3、注册函数,第一个参数,窗口类名称,第二个参数,指向窗口处理函数的函数指针void Register(LPSTR lpClassName, WNDPROC winProc){       WNDCLASSEX wc = { 0 };       wc.cbSize = sizeof(wc);//结构体大小       wc.cbClsExtra = 0;//窗口类的申请缓存区,0表示不开启缓存       wc.cbWndExtra = 0;//窗口的申请缓存区,0表示不开启缓存       wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//背景颜色,一般白色       wc.hCursor = NULL;//设置光标。null表示默认       wc.hIcon = NULL;//默认左上角的图标       wc.hInstance = g_hInstance;//第一个参数实例句柄,可以找到进程在那块内存       wc.lpfnWndProc = winProc; //lp 一般都是指针,处理函数名或指针       wc.lpszClassName = (LPCWSTR)lpClassName;//窗口类名称,比如公司名字       wc.lpszMenuName = NULL;//没有菜单用null       wc.style = CS_HREDRAW | CS_VREDRAW;//窗口变化,会重绘,窗口类的一般风格       RegisterClassEx(&wc);}//4、创建窗口,(窗口类名称,窗口标题栏名称)HWND CreateMain(LPCWSTR lpClassName, LPCWSTR lpWindowName){       HWND hWnd = CreateWindowExW(0, lpClassName, lpWindowName,  WS_OVERLAPPEDWINDOW,              100, 100, 500, 500, NULL, NULL, g_hInstance, (LPVOID)L"附加数据");       return hWnd;}//5、显示窗口(窗口句柄)void Display(HWND hWnd){       ShowWindow(hWnd, SW_SHOW);//句柄,显示方式       UpdateWindow(hWnd);//调用一次刷新窗口}//6、消息循环void Message(){       MSG nMsg = { 0 };       while (GetMessage(&nMsg, nullptr, 0, 0))       {              TranslateMessage(&nMsg);              DispatchMessage(&nMsg);       }}//1、入口函数int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpCmdLine, int   nCmdShow){       g_hInstance = hInstance;              AllocConsole();//增加一个dos窗口       g_接受句柄 = GetStdHandle(STD_OUTPUT_HANDLE);              Register(LPSTR(L"主"), WndProc);       HWND hWnd = CreateMain(LPCWSTR(L"主"), LPCWSTR(L"主窗口"));       Display(hWnd);       Message();       return 0;}

8、运行结果

 

欢迎关注公众号:顺便编点程

Win32编程基本概念 1、消息驱动 在介绍Windows消息驱动概念之前,我们首先来回顾面向过程的程序结构:main()程序有明显的开始、中间过程和结束点,程序是围绕这个过程编写好相关的子过程,再把这些子过程串联在起。程序编好以后,该过程也就确定了,程序必须按照规定好的顺序执行:是否需要用户的输入、输入什么、程序取得用户输入以后做什么处理,处理完毕将结果显示给用户。该过程旦确定,程序的执行过程也是固定的,用户不能干预。 而Windows编程所采用设计思想是:消息驱动,又叫做事件驱动。在这种程序结构中,程序没有明显的开始、结束,程序流程的控制由各种随机发生、不确定、没有预先设定顺序的事件的发生来触发。是个不断产生消息和处理消息的过程。 也就是说程序运行开始处于等待消息状态,取得消息以后,就对该消息做出相应的处理,完成处理以后又进入等待消息的状态。这种程序结构与Windows操作系统结合非常紧密,最明显点就是消息的管理是由操作系统完成的。应用程序从操作系统获得消息有两种方式:种就是应用程序调用Windows提供的消息获取函数;另外种就是回调函数,由操作系统自己调用。 这种消息驱动机制,有点像银行的柜台业务:早上八点,银行开门(Windows应用程序开始运行),每个营业员(Windwows线程)回到自己的柜台开始办公。如果有顾客来办理相关业务(相当于Windows消息),那么对应的业务员就进行处理。顾客来办理业务的时间以及业务类型都是随机的,如果某时刻没有顾客办理业务并且没有到下班时间(Windows应用程序退出)的话,那么相关的业务员进入等待状态。所有的业务员不断重复该过程,直到下班(Windows应用程序退出)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web安全工具库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值