`
jiagou
  • 浏览: 2532958 次
文章分类
社区版块
存档分类
最新评论

消息机制

 
阅读更多
下面有一段伪代码演示如何在窗口过程中处理消息    
LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM)
{
	switch(uMessageType)//使用SWITCH语句将各种消息分开
		{
			case(WM_PAINT):
				doYourWindow(...);//在窗口需要重新绘制时进行输出
				break;
            case(WM_LBUTTONDOWN):
				doYourWork(...);//在鼠标左键被按下时进行处理
	            break;
            default:
				callDefaultWndProc(...);//对于其它情况就让系统自己处理 
       }
}

看着上面的伪代码理解下面的文字

1、消息的组成:
  一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)组成。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
2、谁将收到消息:
  一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。
3、未处理的消息到那里去了:
  M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
4、窗口句柄:
说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。

什么是消息机制

系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。

消息队列

Windows是以消息驱动的操作系统,Windows 消息提供了应用程序与Windows系统之间进行通讯的手段。   
Windows 中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程序队列,用来存放该程序可能创建的各种窗口的消息。应用程序中含有一段称作“消息循环”的代码,用来从消息队列中检索这些消息并把它们分发到相应的窗口函数中。

消息循环

Windows为当前执行的每个Windows程序维护一个「消息队列」。在发生输入事件之后,Windows将事件转换为一个「消息」并将消息放入程序的消息队列中。程序通过执行一块称之为「消息循环」的程序代码从消息队列中取出消息:

消息循环代码是应用程序中主函数WinMain ( )中类似如下的程序段:

	while(GetMessage(&msg,NULL,0,0))  //从消息队列中取得消息  
	{   
		TranslateMessage(&msg);  //检索并生成字符消息WM_CHAR   
		DispatchMessage(&msg);   //将消息发送给相应的窗口函数  
	}   
	//msg变量是型态为MSG的结构,型态MSG在WINUSER.H中定义如下:   
	typedef struct tagMSG   
	{   
		HWND hwnd ;   
		UINT message ;   
		WPARAM wParam ;   
		LPARAM lParam ;   
		DWORD time ; 		
		POINT pt ;   
	} MSG, * PMSG ; 

由此可见,所谓“消息循环”,实际是程序循环。

Windows 应用程序创建的每个窗口都在系统核心注册一个相应的窗口函数,窗口函数程序代码形式上是一个巨大的switch 语句,用以处理由消息循环发送到该窗口的消息,窗口函数由Windows 采用消息驱动的形式直接调用,而不是由应用程序显示调用的,窗口函数处理完消息后又将控制权返回给Windows。


SendMessage()与PostMessage()的区别:  
它们两者是用于向应用程序发送消息的。
PostMessagex()将消息直接加入到应用程序的消息队列中,不等程序返回就退出;而SendMessage()则刚好相反,应用程序处理完此消息后,它才返回。我想下图能够比较好的体现这两个函数的关系:   


peekmessage和getmessage的区别: 
1.GetMessage将等到有合适的消息时才返回,而PeekMessage只是撇一下消息队列。   
2.GetMessage会将消息从队列中删除,而PeekMessage可以设置最后一个参数wRemoveMsg来决定是否将消息保留在队列中。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics