欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    windows消息队列.docx

    • 资源ID:9538322       资源大小:25.17KB        全文页数:19页
    • 资源格式: DOCX        下载积分:3金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要3金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    windows消息队列.docx

    1、windows消息队列windows消息队列 一节详细描述消息和消息队列以及如何在你程序中使用他们。 关于消息和消息队列与传统的应用程序不同,Microsoft Windows应用程序并不显式地用一个函数的调用(如c运行库)来获取输入,而是,等待windows系统把输入传给它们。 windows系统把应用程序的所有输入传给应用程序的窗口,每个窗口都有一个称之为窗口过程的函数当窗口有输入时windows系统要调用它,窗口过程处理输入并把控制返回windows系统。有关窗口过程,参见 “窗口过程”。 这一章讲述消息及消息队列,并说明在应用程序中如何使用它们。 消息windows系统以消息的形式把输

    2、入传给窗口过程,消息是由windows系统或应用程序产生的windows系统对每一个输入事件都要产生消息,例如,用户按键盘、移动鼠标或单击一个滚动条控制框。windows系统为了响应应用程序给系统带来的变化也会产生消息,比如应用程序改变了系统字体资源池或是改变了一个窗门的大小。应用程序可通过产生消息指导它自己的窗口来完成某个任务,或是与其它应用程序的窗口进行通信。 windows系统把消息发送给窗口过程窗口过程有四个参数:窗口句柄、消息标识以及两个叫做消息参数的32位值。窗口句柄决定消息将发送到哪个窗口,windows系统则用它来确定向哪一个窗口过程发送消息。 消息标识是一个命名的常量,由它来

    3、标明消息的目的。如果窗口过程接收到一条消息,它就通过消息标识来决定如何处理这条消息。例如,消息标识WM_PAINT通知窗口过程,窗口的客户区被改变了,需要重画。 消息参数指定窗口过程在处理消息时所用的数据或数据的位置,消息的意图及数值取决了消息本身。消息参数可以是一个整数、紧缩的位标志、一个含有附加数据结构的指针等等。如果消息不使用消息参数,一般就都设置成NULL、窗口过程必须检查消息标识以确定如何解释消息参数。 消息路由windows系统用两种方式向窗口过程发送消息:把消息投递到一个先进先出的消息队列中,它是一个系统定义的内存块用于临时存储消息;或是把消息直接发给窗口过程。 投递到消息队列中

    4、的消息叫排队消息,它们主要是用户通过鼠标或键盘的输入结果如WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, and WM_CHAR消息。其它的排队消息包括定时器、绘制和退出消息:WM_TIMER, WM_PAINT, and WM_QUIT。所有直接发送到窗口过程的其它消息称之为非队列消息。 排队消息windows系统在同一时间可显示多个窗口,要发送鼠标和键盘输入到相应的窗口,windows系统要用到消息队列,它要管理一个系统消息队列和任意数目线程消息队列,每一个队列对应于一个线程。 不管什么时候,只要用户移动鼠标或是敲键盘鼠标或键盘的设备驱动器都要把输入转换

    5、成消息,并把它们放到系统消息队列中去。windows从系统队列中每次移走一条消息,确定目的窗口,再把它们投递到创建目的窗口的线程的消息队列中,线程消息队列接收所有由该线程创建的窗口的鼠标和键盘消息。线程从它的队列中移走消息并指导windows系统将它们发送到相应的窗口过程进行处理。有关线程,参见 “进程和线程”。 WM_PAINT消息有点特别,windows系统总是把这条消息放在消息队列的最后,这样可保证窗口按先进先出次序接收它的输入消息,WM_PAINT消息被保持在队列中,只有在队列中没有其它消息时才发送到窗口过程。同一个窗口的多个WM_PAINT消息被合并成一个WM_PAINT消息,把客户

    6、区所有无效部分合并成一个区域合并WM_PAINT消息节约了窗口必须重画客户区内容的时间。 系统向线程消息队列投递消息是通过填充一个MSG结构,再把它复制到消息队列中,MSG结构中的信息包括接收消息的窗口句柄、消息标识、两个消息参数、消息时间以及鼠标的位置,线程可把消息投递到它自己的消息队列中或是通过函数 PostMessage和PostThreadMessage把消息投递到其它线程的队列中去。 应用程序可通过函数GetMessage从它的队列中移走一条消息,应用程序还可用函数PeekMessage来检查队列中的某个消息但并不移走它,这个函数用有关这条消息的信息填充MSG结构。 把一条消息从它的

    7、队列中移走后应用程序可用函数DispatchMessage指导windows系统把这条消息发送到窗口过程进行处理。DispatchMessage利用前面调用函数GetMessage或PeekMessage时填充的MSG结构的指针,把窗口句柄、消息标识及两个消息参数传给窗口过程,但它并不传送时间或鼠标光标的位置应用程序可以在处理一条消息时,通过调用函数GetMessageTime和GetMessagePos来获取这些信息。 一个线程可以用函数WaitMessage当他没有其他消息在其队列里时,产生对其他线程的控制。此函数将终止线程,直到一个新消息被放入该线程的消息队列里,然后返回。 你可以调用函

    8、数SetMessageExtraInfo来设置当前线程消息队列的附加信息。是和当前线程的消息队列联系的32位值。用户可以用函数GetMessageExtraInfo来获得附加信息,该信息将会保留到下次调用函数GetMessage或PeekMessage之前。 非队列消息非队列消息是直接发送到目标窗口过程的,而不通过系统消息队列和线程消息队列。windows系统一般通过发送非队列消息把影响某窗口的事件通知窗口。例如,如果用户激活一个新的应用程序窗口windows系统就会向该窗口发送一系列的消息,包括:WM_ACTIVATE ,WM_SETFOCUS和WM_SETCURSOR,这些消息分别通知窗口

    9、:它被激活了;将通过这个窗口进行键盘输入;鼠标已移到这个窗口边框的里面了。非队列消息也有可能发生在应用程序调用一个windows系统函数时,例如,在应用程序用函数SetWindowPos来移动一个窗口之后,windows系统发送一条WM_WINDOWPOSCHANGED消息。 应用程序是调用函数SendMessage、SendNotifyMessage或SendDlgItemMessage发送消息的。 消息处理应用程序必须删除和处理投递到它的线程消息队列中的消息,单一线程的应用程序一般是在它的WinMain函数中使用一个消息循环来删除消息,并把消息发送到相应的窗口过程进行处理。具有多重线程的应

    10、用程序在创建窗口的每一个线程中使用一个消息循环,下一节将讲述消息循环是如何工作的,另外还解释了窗口过程的一般规则。 消息循环一个简单的消息循环含有一个对下列函数的调用:GetMessage, TranslateMessage和DispatchMessage。函数GetMessage从队列中检取一条消息并把它复制到一个MSG结构中GetMessage应返回TRUE,但如果它得到的是WM_QUIT消息,它就返回FALSE并结束循环。在单一线程的应用程序中,结束消息循环通常是关闭应用程序的第一步。一般在应用程序主窗口的窗口过程中响应WM_DESTROY消息时,应用程序通过函数PostQuitMess

    11、age关闭它自己的消息循环。 如果在GetMessage中指定窗口句柄,那么从队列中检取的只是指定窗口的消息。GetMessage 也能过滤队列中的消息,这种情况下检取的只是指定范围内的消息。有关过滤消息,参见 “消息过滤”。 如果某个线程想接收键盘的字符输入,那么线程消息循环中必须含有TranslateMessage。Windows系统在用户每按一次键时会产生一个虚键消息(WM_KEYDOWN和WM_KEYUP),虚键消息含有一个标识哪一个键被按过的虚键码,但不是它的字符值,要得到这个值,消息循环中必须含有TranslateMessage,由它来把虚键消息翻译成字符消息(WM_CHAR),再

    12、把它放回到应用程序的消息队列中去这样字符消息才能在消息循环的下一轮循环中被发送到窗口过程。 函数DispatchMessage把消息发送到与MSG结构中指定的窗口句柄相应的窗口过程,如果窗口句柄是HWND_TOPMOST ,DispatchMessage就把消息发送到系统中所有顶层窗口的窗口过程。如果窗口句柄是NULL,对于这条消息DispatchMessage则什么也不做。 应用程序的主线程在初始化应用程序并且至少创建了一个窗口之后就开始了消息循环,一旦开始,消息循环就连续不断地从线程的消息队列中校取消息并把它们分发到相应的窗口,函数GetMessage从消息队列中检取到WM_QUIT消息时

    13、,消息循环就结束了。 一个消息队列只需要有一个消息循环,而不管应用程序有多少个窗口,因为队列中的每一条消息是一个MSG结构,其中含有接收消息的窗口句柄,DispatchMessage总能把消息发送到相应的窗口。 应用程序可以有多种方法修改它的消息循环,例如,它可以从队列中检取消息但并不发送到任何窗口,这对那些投递不指定窗口的消息的应用程序是很有用的,(这些消息是提供给应用程序的,而不是某个窗口,因为它们含有NULL窗口句柄)。应用程序也能指导GetMessage来搜索队列中一个特定的消息,而不管其它消息,这对那些有时不按消息队列先进先出次序检取消息的应用程序来说是很有用的。 使用键盘加速键的应

    14、用程序必须能够把键盘消息转换成命令消息,要这样做,应用程序的消息循环必须调用函数TranslateAccelerator有关加速键,参见 “键盘加速键”。 窗口过程窗口过程是一个函数,用来接收和处理所有发送到该窗口的消息,每个窗口类都有一个窗口过程,同一窗口类所创建的窗口共用同一个窗口过程来响应消息。 系统通过把消息数据作为过程的参数来向窗口过程发送消息,再由窗口过程完成与消息相应的活动。它需要检查消息的标识,在处理消息时要使用由消息参数指定的这个信息。 窗口过程一般不会忽略条消息,如果它不处理某条消息,它就必须把这条消息传回系统进行默认处理,窗口过程是调用函数DefWindowProc来完成

    15、的,由它完成一个默认的操作并返回消息结果。绝大多数窗口过程只处理几种类型的消息,其它的则通过调用DefWindowProc传给了系统。 因为窗口过程是由所有属于同类窗口共享的,所以它能处理几个不同窗口的消息,要识别受消息影响的某个窗口,窗口过程可以检查消息所带的窗口句柄。有关窗口过程,参见 “窗口过程”。 传递和发送消息任何应用程序都能投递和发送消息,就跟系统一样,应用程序投递一条消息是通过把它复制到消息队列,发送消息则是通过把消息数据作为窗门过程的参数。要投递消息,应用程序需要用到函数PostMessage,要发送消息,程序使用函数SendMessage, BroadcastSystemMe

    16、ssage, SendMessageCallback, SendMessageTimeout, SendNotifyMessage或SendDlgItemMessage。 应用程序通常投递条消息来通知某个窗口去完成一个任务。PostMessage为消息创建一个MSG结构并把消息拷到消息队列中,最后由应用程序的消息循环检取这条消息再把它发送到相应的窗口过程。 应用程序一般是通过发送一条消息通知窗口过程立即完成某项任务,函数SendMessage把消息发送到与给定窗口相应的窗口过程,这个函数要等待窗口过程完成处理井返回消息的结果。父窗口与子窗口之间也是通过发送消息来进行相互间的通信,例如,某个父窗

    17、口有一个编辑控制框作为它的子窗口,就可通过向它发送消息设置控制框的正文,这个控制框则通过向父窗口发送消息来把用户对正文的改变通知其父窗口。 函数SendMessageCallback也能发送消息到指定窗口的窗口过程里,但是,这函数是立即返回,当窗口过程函数处理完消息后,系统调用指定的回调函数,有关更多回调函数信息,参考函数SendAsyncProc。 有时,应用程序也有可能要求向系统中的所有顶层窗口发送或投递一条消息,例如,如果应用程序改变了系统的时间,它必须通过发送WM_TIMECHANGE消息来通知所有顶层窗口,应用程序向所有顶层窗口发送或投递一条消息是调用函数SendMessage或Po

    18、stMessage,并在hwnd参数中指定HWND_TOPMOST。你同样通过函数BroadcastSystemMessage指定参数lpdwRecipients的值为BSM_APPLICATIONS来广播消息给所有程序 应用程序能够投递一条消息而不指定窗口,在调用PostMessage时应用程序提供NULL窗口句柄,这条消息就被投递到与当前线程相应的队列中。因为没有指定窗口句柄,应用程序就必须在处理消息循环中的这条消息,这也是一种创建消息的方法此类消息适用于整个应用程序,而不只是指某个窗口。 使用函数InSendMessage窗口过程能够确定它所处理的消息是从另一个线程发来的,这种能力在需要

    19、根据消息源进行消息处理时是很有用的。 经常出现的一个编程错误是假设函数PostMessage总能成功地投递一条消息,这在消息队列是满的时候是不对的,应用程序应该检查函数PostMessage的返回值以确认消息是否已经被投递,否则要重新投递这条消息。 消息种类这部分将两种类型windows消息;系统定义的消息,程序定义的消息 系统消息系统使用系统定义的消息来控制应用程序的操作,并给应用程序提供输入或其他信息进行处理。系统在与应用程序进行通信是时是发送系统消息的。应用程序也能发送或投递系统消息,应用程序通常用这些消息来控制预注册类创建的控制窗口的操作。 每条系统消息都有一个唯一的消息标识,对应于一

    20、个符号常量(在Windows系统头文件中定义),它表明了消息的目的,例如,常量WM_PAINT要求窗口绘制它的内容。 符号常量指定了系统消息所属的类别,常量的前缀标识能够解释和处理消息的亩口的类型。下表列出了前缀及相应的消息类别: 前缀 消息类 ABM Application desktop toolbar BM Button control CB Combo box control CDM Common dialog box DBT Device DL Drag list box DM Default push button control EM Edit control HDM Heade

    21、r control LB List box control LVM List view control PBM Progress bar PSM Property sheet SB Status bar window SBM Scroll bar control STM Static control TB Toolbar TBM Trackbar TCM Tab control TTM Tooltip control TVM Tree-view control UDM Up-down control WM General window 通用窗口消息覆盖了个较大范围的信息和请求,包括鼠标和键盘输

    22、入消息、菜单和对话框输入消息、窗口创建和管理消息及动态数据交换消息(DDL)。 应用程序定义消息应用程序可创建用在它自己的窗口中的消息,或是与其它进程中的窗口进行通信的消息。如果应用程序创建了它自己的消息,接收它们的窗口过程必须能够对消息进行翻译,并提供相应的处理。 windows系统保留用于系统定义的消息的标识值的范围从0x0000到0x03FF(等于WM_USER1)和0x8000到0xBFFF应用程序不能把这些值用于私有消息。 从0x0400(WM_USER的值)到0x7FFF之间的值是可用于应用程序定义的用于它自己的消息标识,而从0xC000到0xFFFF之间的值是应用程序为了与其它应

    23、用程序中的窗口进行通信所定义的消息标识。 应用程序用函数RegisterWindowMessage注册一条消息时,windows系统返回的消息标识在0xC000到0xFFFF之间,这个函数所返回的消息标识应保证在整个系统中是唯一的。如果应用程序要创建与其它应用程序中的窗口进行通信的消息,则使用RegisterWindowMessage来对它进行注册,这个函数可防止由于其它的应用程序基于不同的目的使用了相同的消息标识所产生的冲突。 消息过滤应用程序可使用函数GetMessage或PeekMessage来指定一个消息过滤器,从消息队列中检取指定的消息忽略其它的消息),这是一个消息标识的范围(由第一

    24、个和最后一个标识指定)、一个窗口句柄或者两者都是GetMessage和PeekMessage利用消息过滤器有选择地检取队列中的某条消息。如果某个应用程序必须检索消息队列中的排在后面的消息,消息过滤则是很有用的。 过滤消息的应用程序必须保证满足消息过滤器的消息是能被投递的,例如,如果某个应用程序的过滤器用于一个并不接收键盘输入的窗口中的WM_CHAR消息,函数GetMessage就不能返回,这样就会“挂起”这个应用程序。 要过滤键盘、鼠标和DDE消息,应用程序可以便用下列常量WM_KEYFIRST 和 WM_KEYLAST, WM_MOUSEFIRST 和 WM_MOUSELAST messag

    25、es, 和 WM_DDE_FIRST 和 WM_DDE_LAST 消息死锁调用函数SendMessage的线程向另一个线程发送一条消息,要等待接收消息的窗口过程返回,如果接收消息的线程在处理消息时放弃了控制,发送消息的线程就不能继续执行下去,因为它正等待SendMessage返回,这种情况就叫做死锁。接收消息的线程无须直接地放弃控制,调用下列函数其个的一个就能让线程放弃控制。 DialogBox DialogBoxIndirect DialogBoxIndirectParam DialogBoxParam GetMessage MessageBox PeekMessage 窗口过程可以确定它所

    26、接收的消息是不是另一个线程通过调用函数InSendMessage发来的。在处理一条消息时调用前面所列出的任一个函数之前,窗口过程应首先调用InSendMessage,如果函数返回TRUE,窗口过程就必须在调用任何能使线程放弃控制的函数之前调用函数ReplyMessage。 使用消息和消息队列这节描述如何完成下面的工作 创建消息循环 检查消息队列 投递消息 发送消息 创建消息循环windows系统为每一个线程自动创建消息队列,如果线程创建了一个或多个窗口,就必须提供从线程消息队列中检取消息,并把它们发送至相应窗口过程的消息循环。 因为windows系统指导向应用程序中的某个窗口发送消息,线程就必

    27、须在启动它的消息循环之前至少要创建个窗口,绝大多数windows应用程序含有一个创建窗口的线程。一个典型的应用程序是在函数WinMain中注册它主窗口的窗口类。创建和显示主窗口然后启动消息循环。 函数GetMessage 和 DispatchMessage用来创建消息循环,如果应用程序必须从用户得到字符输入,那么在消息循环中应包含函数TranslateMessage,TranslateMessage把虚键消转换成字符消息。下面的范例说明了一个简单的windows应用程序的WinMain函数中的消息循环 HINSTANCE hinst; HWND hwndMain; int PASCAL Win

    28、Main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) MSG msg; WNDCLASS wc; UNREFERENCED_PARAMETER(lpszCmdLine); / Register the window class for the main window. if (!hPrevInstance) wc.style = 0; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0;

    29、wc.hInstance = hInstance; wc.hIcon = LoadIcon(HINSTANCE) NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(HINSTANCE) NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = MainMenu; wc.lpszClassName = MainWndClass; if (!RegisterClass(&wc) return FALSE; hinst = hInstance;

    30、/ save instance handle / Create the main window. hwndMain = CreateWindow(MainWndClass, Sample, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL, hinst, (LPVOID) NULL); / If the main window cannot be created, terminate / the application. if (!

    31、hwndMain) return FALSE; / Show the window and paint its contents. ShowWindow(hwndMain, nCmdShow); UpdateWindow(hwndMain); / Start the message loop. while (GetMessage(&msg, (HWND) NULL, 0, 0) TranslateMessage(&msg); DispatchMessage(&msg); / Return the exit code to Windows. return msg.wParam; 函数GetMes

    32、sage,TranslateMessage以及DispatchMessage把MSG结构的指针当作一个参数。如果有消息,GetMessage把它复制到MSG结构中,如果这个消息是一条虚键消息(如WM_KEYDOWN或WM_SYSKEYDOWN),TranslateMessage产生一个字符消息(WM_CHAR或WM_SYSCHAR),并把它放到消息队列中去。DispatchMessage也使用MSG结构的成员用作窗口过程的参数但要等到窗口过程完成处理后才返回。 如果某个线程支持加速键,那么它的消息循环必须含有函数TranslateAccelerator。这个函数检查与线程加速键表中的一个入口相匹配的组合键,如果它找到一个匹配值TranslateAcce


    注意事项

    本文(windows消息队列.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开