本站首页    管理页面    写新日志    退出

首页(46) 其它(20) VC++学习(17) 程序员(5) 音乐欣赏(3) 


Ashes to ashes Dust to dust
 
 ♀最新日志                                                        ♀最新回复                                  
[转]乐到我抽筋儿的几个极品笑话
PAYPAL的奇怪问题
第一次尝试
递归
明天交毕业设计中期报告了
等到googlepage了
GTalk和Gmail
修好了鼠标!
是不是中毒了?
有Windows Live Messen
回复:google打不开了
回复:《精通MFC》——第二章(III)
回复:《精通MFC》——第二章(III)
回复:《精通MFC》——第二章(III)
回复:理查得·克莱德曼 的经典钢琴曲
回复:理查得·克莱德曼 的经典钢琴曲
回复:理查得·克莱德曼 的经典钢琴曲
回复:修好了鼠标!
回复:理查得·克莱德曼 的经典钢琴曲
回复:理查得·克莱德曼 的经典钢琴曲
«September 2025»
123456
78910111213
14151617181920
21222324252627
282930
 
 

[VC++学习]《精通MFC》——第二章(IV)
读书笔记

  1         应用程序定义的通知        这种消息是由应用程序而不是在SDK头文件中定一的。应用程序利用这些消息来指示它所拥有的窗口完成特定的任务或同其他应用程序的窗口通信。        应用程序要为自定义消息赋予一个惟一的32位标记。必须保证该标记和已有的系统定一的消息的标志符不冲突,可以有两种方法实现:        确保值在0x0400(WM_USER)和0x7FFF之间。操作系统保留了0x0000到0x03FF(WM_USER - 1)之间的值,应用程序不能使用。        向RegisterWindowMessage传入一个消息字符串,获得一个介于0xC000和0xFFFF之间的系统范围内惟一的消息标志符:        UINT RegisterWindowMessage(               LPCTSTR  lpString      //消息字符串        );   2         消息参数        系统向窗口过程传递消息时会传递如下四个参数。这四个参数被称为消息参数:        hWnd:表示处理该消息的窗口,该窗口的窗口过程将被调用以处理消息。        Message:消息的惟一标志。        wParam:处理该消息所需要的参数。        lParam:处理该消息的额外参数。               wParam和lParam设定了处理该消息所需要的数据或数据的位置。其含义和值依赖于具体消息。如果消息不需要使用参数,需要将wParam和lParam设为NULL。窗口过程必须检查消息类型并根据消息类型决定如何解释wParam和lParam。   3         消息对列        窗口本身仅提供了处理消息的窗口过程,真正的处理是由创建窗口的线程来进行的。线程对创建的窗口有拥有权。如果一个线程建立一个窗口然后结束,操作系统会自动销毁线程所拥有的全部窗口。建立窗口的线程必须是为窗口处理所有消息的线程。这也意味着每个线程,如果它至少建立了一个窗口,都应由系统对它分配一个容纳待处理的消息的队列。这个队列用于窗口消息的派送。这个队列就是线程的消息队列。为了使窗口接收这些消息,线程必须有它自己的消息循环。        线程通过消息循环,从消息队列中取出消息,并分派到特定的窗口过程处理该消息。在处理过程中可能又会产生其它消息,这些消息被放到消息队列中。如此不断往复,直到应用程序调用PostQuitMessage为止。PostQuitMessage不会在消息队列中投递一个消息,而是在内部设定QS_QUIT唤醒标志并设置THREADINFO结构的nExitCode成员。因为这些操作永远不会失败,所以PostQuitMessage的原型被定义成返回VOID。        除了为每个线程维持一个消息队列外,系统还维持一个全局的消息队列,用于容纳各种硬件输入消息的系统硬件输入队列。当系统初始化时,需建立一个特殊的线程,即原始输入线程(Raw Input Thread,  RIT),同时建立系统硬件输入队列(System Hardware Input Queue, SHIQ)。        对鼠标消息,原始输入线程只是确定哪一个窗口在鼠标光标下。利用这个窗口,原始输入线程调用GetWindowThreadProc elssId来确定是哪个线程建立了这个窗口。返回的线程ID指出哪一个线程应该得到这个鼠标消息。        在任何给定时刻,只有一个线程同原始输入线程“连接”。这个线程就是我们前面讨论的前台线程(Foreground Thread),因为它建立了正在与用户交互的窗口。当切换前台窗口时(无论是通过键盘、鼠标还是通过函数调用),原始输入线程将自动切换和当前的前台线程的连接。        一般情况下,最新的消息总是放到队列的末尾,但WM_PAINT消息是惟一的例外。为了优化屏幕的绘制,系统对WM_PAINT消息采取了特殊的处理。首先,只有当消息队列中没有其它消息时,该消息才会被传递给窗口过程进行处理。其次,同一个窗口的多个WM_PAINT消息会被合并为一个WM_PAINT消息,组合时所有的待绘制的无效区域合并为一个区域。        为了将消息投递到线程的消息队列,系统首先要依据MSG结构进行过滤,然后将MSG结构拷贝到消息队列。下面是MSG结构的定义:        Typedef struct tagMSG{               HWMD          hwnd;               UINT             message;               WPARAM      wParam;               LPARAM lParam;               DWORD        time;               POINT           pt;        }MSG;        Time参数表示消息投递的时间,pt参数表示鼠标的位置。          应用程序通过调用GetMessage从消息对列中移出一条消息。如果仅仅是检查消息而不用移出,可以调用PeekMessage,该函数获得当前消息的一份拷贝。        移出一条消息后,应用程序通过调用DispatchMessage将消息分派到适当的窗口过程进行处理。DispatchMessage函数接收的MSG指针所指的数据由前面调用的GetMessage或PeekMessage填充。        在向窗口过程传递消息时,没有传递time 和pt参数。应用程序在处理消息时,可通过调用GetMessageTime和GetMessagePos获得这些消息。          通过调用WaitMessage,线程可以在其消息队列为空时将控制权转交给其他线程。WaitMessage会阻塞当前线程,直到有新的消息进入线程的消息队列。          还可以通过调用SetMessageExtraInfo,为当前线程的线程对列设置附加信息。        LPARAM SetMessageExtraInfo(               LPARAM lParam        );        该函数返回当前线程的消息队列的上次设定的附加消息。调用该消息后,会“冲掉”以前为该线程的消息队列设置的任何附加信息。          通过调用GetMessageExtraInfo,可以获得当前线程的消息队列的附加信息。   4         消息循环        任何GUI线程都拥有一组消息队列,并需要不断从消息队列中取出消息进行处理,处理过程忠又产生新的消息,如此往复构成消息循环。消息循环是Windows应用的典型结构。        一个简单的消息循环如下:        MSG  msg;        bool bRet;        while (bRet = GetMessage(&msg, NULL, 0, 0) != 0)        {               if (bRet == -1)               {                      //错误处理               }                   else               {                      TranslateMessage(&msg);                      DispatchMessage(&msg);               }        }        代码中的GetMessage从消息队列中检索到消息并将它拷贝到MSG结构中。它可能返回-1、0和其它值。-1表示碰到错误;0表示检索到WM_QUIT消息。        一般的情形是在主窗口的窗口过程中响应WM_DESTROY时,调用PostQuitMessage以结束消息循环。        Case WM_DESTROY:               //清理               PostQuitMessage(0);               Break; 线程消息循环中必须包含对TranslateMessage的调用,以接收键盘输入:

 

00oo.. 发表于 2005/11/7 21:36:01

阅读全文(1779) | 回复(0) | 编辑 | 精华



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)
 
♀链接


AoGo汇编小站: http://www.aogosoft.com/

CSDN:        http://www.csdn.net/

编程爱好者:   http://www.programfan.com/

阿蒙编程之家: http://www.vchome.net/

看雪学院:     http://www.pediy.com

VC开发指南:http://www.copathway.com

 

♀留言板                                                             ♀Blog信息

签写新留言

人生需要加油!
MSN LIVE messager邀请
我加你了google talk
blog名称:00oo..
日志总数:46
评论数量:228
留言数量:2
访问次数:391829
建立时间:2004年11月6日
用户名称:
登陆密码:
密码保存:



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.270 second(s), page refreshed 144761849 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号