WndProc 与win32程序消息循环
2012-04-22 18:20
337 查看
我在上一篇文章中说过WinMain()函数没有WndProc()函数重要,实际情况确实如此,程序员主要花心思的地方就在WndProc()中。
在WndProc()函数中,首先是定义了几个变量。分别为HDC,PAINTSTRUCT,RECT类型。要讲他们的话又要扯到GDI,所以还是把他们留在后面,只需知道是定义了几个变量即可。
关键的地方到了,switch ...case,学过c语言的同学是不是感到很亲切。它出现在这当然是为了判断了。括号里的message是哪里来的,仔细看你就会发现是一个传递过来的形参。message自然是消息了,我再重新说一下上一片文章中的消息驱动机制。windows操作系统接收到你传递过来的消息,比如说按了键盘上某个键,然后把这个消息传递给需要的程序。这就是 消息--事件。操作系统怎么得到消息不是我们考虑的问题,那是微软的工程师需要考虑的。我们需要知道消息在哪传递给了我们的程序,又是在哪被处理而产生了一个事件。
让我们看看消息循环的代码,在WinMain()中。
while(GetMessage(&msg,NULL,0,0))//消息循环
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
它主要是三个函数构成的。GetMessage,通过拼写都知道它是从操作系统那得到消息的函数。这里我又要说一下消息队列的概念,系统在运作时产生的消息是非常多的。操作系统会把消息放到一个叫做消息队列中的结构中去。消息队列好像是一条传送带,系统把消息放的上面,消息会逐步往下移动,程序就像是工人一样守在传送带旁,看着过来的消息是不是自己需要的,如果不是就继续等待,如果是就拿起来处理。但这种消息你的程序还是看不懂的,因为它是一串数字,这时就要靠TranslateMessage把它翻译了,翻译的结果就是WM_PAINT之类的形式,实际上就是给数字一个好记的代号而已。WM_是前缀,实际上是windows
message的缩写,后面的PAINT是绘图的意思,自然是需要绘图时产生的消息。需要注意的是WM_DESTROY消息,它发出的事件PostQuitMessage(0);直接翻译过来是广播退出消息,什么意思呢?就是退出消息循环。消息循环如果GetMessage返回的值为真的话会一直进行,PostQuitMessage(0);就是让GetMessage返回的值为假,这和c语言里没什么两样。
DispatchMessage(&msg);曾提到过是把消息传递给WndProc,不过这就有个问题,它是怎么知道把消息给谁的,这世界上是没有无缘故的事的,编程亦是如此。让我们在仔细看看WinMain(),看看哪有提到WndProc。找到了,是注册窗口类时提到的
wndclass.lpfnWndProc=WndProc;对,这是个指向窗口过程函数的指针,也决定了DispatchMessage把消息传递给谁。这么一看,WndProc并不是什么神秘的“系统规定”,完全可以改个名字。事实的确如此,但WndProc如此常用,以至于大部分人都以为这是一种规定,我们也就没有改的必要了。
消息就顺着
系统---消息队列----消息循环---WndProc的顺序进入了WndProc函数,我想大家都已经知道它会然后处理消息。把传来的消息与case中的选项进行比对,这就有了一个问题,如果这个消息在case中没有呢?在c语言中我们会用default,在windows编程时,我们用return DefWindowProc(hwnd,message,wParam,lParam);,意思是把消息交给系统处理。
好了,这次就到这里。这节主要是想让大家理清消息的传递。WndProc很简单,程序员要干的,是在switch...case中加入自己要处理的消息,并编写处理消息的函数。这些以后讲吧
在WndProc()函数中,首先是定义了几个变量。分别为HDC,PAINTSTRUCT,RECT类型。要讲他们的话又要扯到GDI,所以还是把他们留在后面,只需知道是定义了几个变量即可。
关键的地方到了,switch ...case,学过c语言的同学是不是感到很亲切。它出现在这当然是为了判断了。括号里的message是哪里来的,仔细看你就会发现是一个传递过来的形参。message自然是消息了,我再重新说一下上一片文章中的消息驱动机制。windows操作系统接收到你传递过来的消息,比如说按了键盘上某个键,然后把这个消息传递给需要的程序。这就是 消息--事件。操作系统怎么得到消息不是我们考虑的问题,那是微软的工程师需要考虑的。我们需要知道消息在哪传递给了我们的程序,又是在哪被处理而产生了一个事件。
让我们看看消息循环的代码,在WinMain()中。
while(GetMessage(&msg,NULL,0,0))//消息循环
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
它主要是三个函数构成的。GetMessage,通过拼写都知道它是从操作系统那得到消息的函数。这里我又要说一下消息队列的概念,系统在运作时产生的消息是非常多的。操作系统会把消息放到一个叫做消息队列中的结构中去。消息队列好像是一条传送带,系统把消息放的上面,消息会逐步往下移动,程序就像是工人一样守在传送带旁,看着过来的消息是不是自己需要的,如果不是就继续等待,如果是就拿起来处理。但这种消息你的程序还是看不懂的,因为它是一串数字,这时就要靠TranslateMessage把它翻译了,翻译的结果就是WM_PAINT之类的形式,实际上就是给数字一个好记的代号而已。WM_是前缀,实际上是windows
message的缩写,后面的PAINT是绘图的意思,自然是需要绘图时产生的消息。需要注意的是WM_DESTROY消息,它发出的事件PostQuitMessage(0);直接翻译过来是广播退出消息,什么意思呢?就是退出消息循环。消息循环如果GetMessage返回的值为真的话会一直进行,PostQuitMessage(0);就是让GetMessage返回的值为假,这和c语言里没什么两样。
DispatchMessage(&msg);曾提到过是把消息传递给WndProc,不过这就有个问题,它是怎么知道把消息给谁的,这世界上是没有无缘故的事的,编程亦是如此。让我们在仔细看看WinMain(),看看哪有提到WndProc。找到了,是注册窗口类时提到的
wndclass.lpfnWndProc=WndProc;对,这是个指向窗口过程函数的指针,也决定了DispatchMessage把消息传递给谁。这么一看,WndProc并不是什么神秘的“系统规定”,完全可以改个名字。事实的确如此,但WndProc如此常用,以至于大部分人都以为这是一种规定,我们也就没有改的必要了。
消息就顺着
系统---消息队列----消息循环---WndProc的顺序进入了WndProc函数,我想大家都已经知道它会然后处理消息。把传来的消息与case中的选项进行比对,这就有了一个问题,如果这个消息在case中没有呢?在c语言中我们会用default,在windows编程时,我们用return DefWindowProc(hwnd,message,wParam,lParam);,意思是把消息交给系统处理。
好了,这次就到这里。这节主要是想让大家理清消息的传递。WndProc很简单,程序员要干的,是在switch...case中加入自己要处理的消息,并编写处理消息的函数。这些以后讲吧
相关文章推荐
- 关于win32编程中消息循环和WndProc()窗口过程函
- MFC 消息循环模拟Win32程序
- QT源码之QT创建窗口程序、消息循环和WinMain函数
- QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
- Win32消息循环机制等【转载】http://blog.csdn.net/u013777351/article/details/49522219
- Win32程序启动时的头几个消息
- Win32 SDK 编程开始, 创建窗口, 消息的处理, 消息循环
- win32 消息循环疑惑
- Win32 SDK 编程开始, 创建窗口, 消息的处理, 消息循环
- window程序一个线程中可以有几个消息队列?和几个消息循环
- 一个简单的Windows程序及消息循环机制
- Win32消息循环机制等【转载】
- Win32程序中为什么不能响应WM_KEYDOWN消息
- window程序一个线程中可以有几个消息队列?和几个消息循环
- 控制台程序的 定时器 和 消息循环
- [WPF] Felix 的线程学习笔记(一)——从Win32的消息循环说起
- 用消息在Win32控制台程序多线程间进行通讯
- Windows消息循环(win32)与MFC消息映射,Duilib消息机制
- (win32)句柄,消息循环
- 编写一段程序,从标准输入读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次是使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有人任何单词是重复出现的。