今天有朋友提的意见让我感触很深,说写BLOG要多一些‘有趣’多一些funny,回头看看我写的东西,大部分都给人严肃、枯燥的感觉,我在这里免费拿了一个BLOG,而这个BLOG却不完全属于我,他属于千千万万在使用网络的学者!所以,我有责任,而这个责任就是不浪费读者的时间。不说废话了,同样今天继续写的将是Win32程序设计中的Windows消息机制。消息就是一个用户对电脑的‘请求’。我想放点音乐,我就对电脑大声喊:“Hey!伙计,放点音乐吧!”,结果显然是我将被冷落。我不能这样发‘请求’,我应该用电脑懂的语言,再用‘友好’的方式请求。我只能选择按鼠标或者敲键盘,于是消息便从这里产生了。消息的原来形式是你手指的‘动能’,结果导致了某些特定电信号,电信号再到达计算机电路系统,系统再将信号反应到操作系统,操作系统再将信号变成消息形式发到线程,到线程的消息再进入消息队列排队,最终到达消息处理函数,此时电脑就明白你的请求是什么意思了,再通过消息处理函数工作。与其说消息是发到电脑,还不如说是发到了线程,如果没有线程在那里‘听’,你发再多的消息,也不会有反应。线程要怎么‘听’,还得从GUI入口函数说起。一个GUI用户程序的入口函数将不是main(),而是WinMain(),原形是:int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){}APIENTRY是__stdcall的宏,意思是用Windows标准调用方式,hInstance是本身的实例句柄,lpCmdLine是命令行参数。光一个WinMain()是不会等待消息的(‘听’),我可以加入一个::MessageBox();简单的弹一个窗口出来,然后默默的结束。问题是我们需要先建一个窗体出来,建主窗体的过程比较复杂,详细的情况参看书本。过程大致是,先设置窗体句柄的参数,然后建立窗体,然后注册窗体,最后更新窗体。完了之后这个窗体就会‘挂’在桌面上,‘等待’用户发消息。事实上,‘等待’还需要‘消息循环’,如果WinMain()进程一旦结束,那窗体挂着也没用,消息还没到达就自己退出了。所以必须让主线程‘挂’起来,同时‘等待’消息的到达。接下来就进入‘无限’的‘消息循环’:代码像这样:MSG msg;while(::GetMessage(&msg,NULL,0,0)){ ::TranslateMessage(&msg); ::DispatchMessage(&msg);}这里的无限循环,不是说这段代码将一直运行,事实上::GetMessage()将使这个线程挂起,只有当消息到来时再被再次激活。::DispatchMessage()将把消息发送到消息处理函数,或者叫窗口函数,它是窗口建立的时候指定的,形如:LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);第二个参数就是消息,可以理解为大的消息,后面两个参数是附带的消息参数,而第一个是所属的窗口句柄。无限的消息循环使主线程一直在等待消息的到达,然后再通知消息处理函数,直到得到一个WM_QUIT消息返回0才结束程序。另外有两个发送消息的API函数:::SendMessage();参数同消息处理函数的参数。::PostMessage();前者是直接的调用消息处理函数,同时自己挂起,等待消息处理的结束,再继续运行。而后者是直接向句柄所在消息队列中发一个消息,同时继续运行。

评论