Win32 事件_消息_消息处理函数

1.第一个图形界面

步骤一:创建Windows应用程序(win32 Application)
步骤二:在新建窗口中选择C++代码文件,创建一个新的cpp文件,在这里我们选择让编译器替我们创建入口函数
步骤三:在新的文件中添加:#include<Windows.h>
步骤四:设计窗口
//窗口的类名									
TCHAR className[] = "My First Window"; 									
									
// 创建窗口类的对象 									
WNDCLASS wndclass = {0};						//一定要先将所有值赋值			
wndclass.hbrBackground = (HBRUSH)COLOR_MENU;						//窗口的背景色			
wndclass.lpfnWndProc = WindowProc;						//窗口过程函数			
wndclass.lpszClassName = className;						//窗口类的名字			
wndclass.hInstance = hInstance;						//定义窗口类的应用程序的实例句柄			
									

注意:

这里的wndclass对象必须进行初始化,因为在赋值时,我们并没有将所有的成员都进行赋值,因此在我们为进行初始化的时候,其他成员的值就是堆栈的原始状态,并不符合系统对于窗口属性的格式!!

这里WNDCLASS是一个结构体类型

WNDCLASS结构包含由RegisterClass函数注册的窗口类属性。

这个结构已经被与RegisterClassEx函数一起使用的WNDCLASSEX结构所取代。

如果不需要设置与窗口类相关联的小图标,仍然可以使用WNDCLASS和RegisterClass。

步骤五:注册窗口类

这里使用RegisterClass(&wndclass)来进行注册

步骤六:创建窗口
// 创建窗口  							
HWND hwnd = CreateWindow(  							
	className,				//类名		
	TEXT("我的第一个窗口"),				//窗口标题		
	WS_OVERLAPPEDWINDOW,				//窗口外观样式 		
	10,				//相对于父窗口的X坐标		
	10,				//相对于父窗口的Y坐标		
	600,				//窗口的宽度  		
	300,				//窗口的高度  		
	NULL,				//父窗口句柄,为NULL  		
	NULL,				//菜单句柄,为NULL  		
	hInstance,				//当前应用程序的句柄  		
	NULL);				//附加数据一般为NULL		
							
if(hwnd == NULL)					//是否创建成功  		
	return 0;  						

在这里我们设置窗口的属性(一直疑惑为什么前面创建WNDCLASS结构体来设置窗口属性了,这里创建窗口的时候又有其他属性要设置,为什么不能放在一个结构体中直接定义一个自己的窗口呢)

步骤七:显示窗口
ShowWindow(hwnd, SW_SHOW);  

注意到现在出现了两个句柄

WNDCLASS结构体中的->hInstance中存储的是定义窗口类的应用程序的实例句柄

CreateWindow函数返回的是窗口类的实例句柄(HWND)

步骤八:消息循环
MSG msg;  			
while(GetMessage(&msg, NULL, 0, 0))  			
{  			
	TranslateMessage(&msg);  		
	DispatchMessage(&msg);  		
}  			

个人理解:在消息循环阶段,我们定义一个消息类结构体,在消息循环时,GetMessage函数会对消息进行加工处理

可以看到,这里函数中的参数都是输出参数

GetMessage函数返回值:

如果函数检索到的消息不是WM_QUIT,返回值是非零的。
如果函数获取WM_QUIT消息,返回值为0。
如果出现错误,则返回值为-1。例如,如果hWnd是无效的窗口句柄或lpMsg是无效的指针,则函数失败。要获取扩展的错误信息,请调用GetLastError。

步骤九:回调函数
/*									
窗口消息处理程序 窗口回调函数:									
									
1、窗口回调函数处理过的消息,必须传回0.									
									
2、窗口回调不处理的消息,由DefWindowProc来处理.									
*/									
									
LRESULT CALLBACK WindowProc(  									
							IN  HWND hwnd,  		
							IN  UINT uMsg,  		
							IN  WPARAM wParam,  		
							IN  LPARAM lParam  		
							)  		
{  									
	switch(uMsg)								
	{								
		//窗口消息							
	case WM_CREATE: 								
		{							
			DbgPrintf("WM_CREATE %d %d\n",wParam,lParam);						
			CREATESTRUCT* createst = (CREATESTRUCT*)lParam;						
			DbgPrintf("CREATESTRUCT %s\n",createst->lpszClass);						
									
			return 0;						
		}							
	case WM_MOVE:								
		{							
			DbgPrintf("WM_MOVE %d %d\n",wParam,lParam);						
			POINTS points = MAKEPOINTS(lParam);						
			DbgPrintf("X Y %d %d\n",points.x,points.y);						
									
			return 0;						
		}							
	case WM_SIZE:								
		{							
			DbgPrintf("WM_SIZE %d %d\n",wParam,lParam);						
			int newWidth  = (int)(short) LOWORD(lParam);    						
			int newHeight  = (int)(short) HIWORD(lParam);   						
			DbgPrintf("WM_SIZE %d %d\n",newWidth,newHeight);						
									
			return 0;						
		}							
	case WM_DESTROY:								
		{							
			DbgPrintf("WM_DESTROY %d %d\n",wParam,lParam);						
			PostQuitMessage(0);						
									
			return 0;						
		}							
		//键盘消息							
	case WM_KEYUP:								
		{							
			DbgPrintf("WM_KEYUP %d %d\n",wParam,lParam);						
									
			return 0;						
		}							
	case WM_KEYDOWN:								
		{							
			DbgPrintf("WM_KEYDOWN %d %d\n",wParam,lParam);						
									
			return 0;						
		}							
		//鼠标消息							
	case WM_LBUTTONDOWN:								
		{							
			DbgPrintf("WM_LBUTTONDOWN %d %d\n",wParam,lParam);						
			POINTS points = MAKEPOINTS(lParam);						
			DbgPrintf("WM_LBUTTONDOWN %d %d\n",points.x,points.y);						
									
			return 0;						
		}							
	}								
	return DefWindowProc(hwnd,uMsg,wParam,lParam);								
}  									

注意:这里的回调函数并不能随意定义,必须按照操作系统定义的格式进行定义


2.什么是事件,什么是消息,什么是消息处理函数

事件 消息                
                
Windows中的事件是一个“动作”,这个动作可能是用户操作应用程序产生的,也可能是Windows自己产生的.                
                
而消息,就是用来描述这些“动作”的,比如:                
                
这个动作是什么时候产生的?                
                
哪个应用程序产生的?                
                
在什么位置产生的?                
                
等等。。。                
                
Windows为了能够准确的描述这些信息,提供了一个结构体:MSG,该结构体里面记录的事件的详细信息.                
                
typedef struct tagMSG {                
  HWND   hwnd;                 
  UINT   message;                 
  WPARAM wParam;                 
  LPARAM lParam;                 
  DWORD  time;                 
  POINT  pt;                 
} MSG, *PMSG;                 
                
说明:                
                
1、hwnd:                
个人理解为,hwnd是窗口的句柄                
表示消息所属的窗口                
                
一个消息一般都是与某个窗口相关联的                
                
在Windows中 HWND类型的变量通常用来标识窗口。                
                
2、message                
                
在Windows中,消息是由一个数值来表示的                
                
但是由于数值不便于记忆,所以Windows将消息对应的数值定义为WM_XXX宏(WM == Window Message)                
                
鼠标左键按下 WM_LBUTTONDOWN                键盘按下 WM_KEYDOWN
                
3、wParam 和 lParam                              

32位消息的特定附加信息,具体表示什么处决于message                 
                
4、time                
                
消息创建时的时间                 
                
5、消息创建时的鼠标位置                
 

消息处理函数就是回调函数

为什么叫回调函数?因为该函数并不是由我们来进行调用,而是系统将消息进行加工处理后,将消息分发给操作系统,系统再调用我们的消息处理函数进行处理操作

用户产生的事件通过MSG进行描述后,首先在系统队列中进行排队,通过分类后来到了属于各自的应用程序消息队列中再进行排队

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值