wMessage 来对它进行注册,这个函数可防止由于其它的应用程序基于不同的目的使用了相同的消息标识所产生的冲突。
消息过滤应用程序可使用函数 GetMessage 或 PeekMessage 来指定一个消息过滤器,从消息队列中检取指定的消息忽略其它的消息,这是一个消息标识的范围由第一个和最后一个标识指定、一个窗口句柄或者两者都是 GetMessage 和 PeekMessage利用消息过滤器有选择地检取队列中的某条消息。
如果某个应用程序必须检索消息队列中的排在后面的消息,消息过滤则是很有用的。
过滤消息的应用程序必须保证满足消息过滤器的消息是能被投递的,例如,如果某个应用程序的过滤器用于一个并不接收键盘输入的窗口中的 WM_CHAR 消息,函数 GetMessage 就不能返回,这样就会“挂起”这个应用程序。
要过滤键盘、鼠标和 DDE 消息,应用程序可以便用下列常量 WM_KEYFIRST 和 WM_KEYLAST WM_MOUSEFIRST 和WM_MOUSELAST messages 和 WM_DDE_FIRST 和 WM_DDE_LAST消息死锁调用函数 SendMessage 的线程向另一个线程发送一条消息,要等待接收消息的窗口过程返回,如果接收消息的线程在处理消息时放弃了控制,发送消息的线程就不能继续执行下去,因为它正等待 SendMessage 返回,这种情况就叫做死锁。
接收消息的线程无须直接地放弃控制,调用下列函数其个的一个就能让线程放弃控制。
DialogBoxDialogBoxIndirectDialogBoxIndirectParamDialogBoxParamGetMessageMessageBoxPeekMessage窗口过程可以确定它所接收的消息是不是另一个线程通过调用函数 InSendMessage 发来的。
在处理一条消息时调用前面所列出的任一个函数之前,窗口过程应首先调用 InSendMessage,如果函数返回 TRUE,窗口过程就必须在调用任何能使线程放弃控制的函数之前调用函数 ReplyMessage。
使用消息和消息队列这节描述如何完成下面的工作创建消息循环检查消息队列投递消息发送消息创建消息循环windows 系统为每一个线程自动创建消息队列,如果线程创建了一个或多个窗口,就必须提供从线程消息队列中检取消息,并把它们发送至相应窗口过程的消息循环。
因为 windows 系统指导向应用程序中的某个窗口发送消息线程就必须在启动它的消息循环之前至少要创建—个窗口,绝大多数 windows 应用程序含有一个创建窗口的线程。
一个典型的应用程序是在函数 WinMain 中注册它主窗口的窗口类。
创建和显示主窗口.然后启动消息循环。
函数 GetMessage 和 DispatchMessage 用来创建消息循环,如果应用程序必须从用户得到字符输入,那么在消息循环中应包含函数 TranslateMessage,TranslateMessage 把虚键消转换成字符消息。
下面的范例说明了一个简单的 windows 应用程序的 WinMain 函数中的消息循环HINSTANCE hinstHWND hwndMainint PASCAL WinMainHINSTANCE hInstance HINSTANCE hPrevInstanceLPSTR lpszCmdLine int nCmdShowMSG msgWNDCLASS wcUNREFERENCED_PARAMETERlpszCmdLine// Register the window class for the main window.if hPrevInstancewc.style 0wc.lpfnWndProc WNDPROC WndProcwc.cbClsExtra 0wc.cbWndExtra 0wc.hInstance hInstancewc.hIcon LoadIconHINSTANCE NULL IDI_APPLICATIONwc.hCursor LoadCursorHINSTANCE NULL IDC_ARROWwc.hbrBackground GetStockObjectWHITE_BRUSHwc.lpszMenuName quotMainMenuquotwc.lpszClassName quotMainWndClassquotif RegisterClassampwcreturn FALSEhinst hInstance // save instance handle// Create the main window.hwndMain CreateWindowquotMainWndClassquot quotSamplequot WS_OVERLAPPEDWINDOW CW_USEDEFAULTCW_USEDEFAULTCW_USEDEFAULT CW_USEDEFAULT HWND NULL HMENU NULL hinst LPVOID NULL// If the main window cannot be created terminate// the application.if hwndMainreturn FALSE// Show the window and paint its contents.ShowWindowhwndMain nCmdShowUpdateWindowhwndMain// Start the message loop.while GetMessageampmsg HWND NULL 0 0TranslateMessageampmsgDispatchMessageampmsg// Return the exit code to Windows.return msg.wParam函数 GetMessageTranslateMessage 以及 DispatchMessage 把 MSG 结构的指针当作一个参数。
如果有消息,GetMessage 把它复制到 MSG 结构中,如果这个消息是一条虚键消息如 WM_KEYDOWN 或 WM_SYSKEYDOWN,TranslateMessage 产生一个字符消息WM_CHAR 或 WM_SYSCHAR,并把它放到消息队列中去。
DispatchMessage 也使用 MSG 结构的成员用作窗口过程的参数.但要等到窗口过程完成处理后才返回。
如果某个线程支持加速键,那么它的消息循环必须含有函数 TranslateAccelerator。
这个函数检查与线程加速键表中的一个入口相匹配的组合键,如果它找到一个匹配值.TranslateAccelerator 就把组合键翻译成一条 WM_COMMAND 消息,并把它发送到窗口过程。
如果某个线程使用模式对话框,消息循环中必须含有函数 IsDialogMessage 以便于对话框能够接收键盘输入。
有关对话框,参见“对话框”。
下面的范例说明了一个使用加速键的线程的消息循环,其中显示了一个模式对话框。
如果 TranslateAccelerator 或 IsDialogMessage 返回 TRUE指示消息已被处理,就不再调用 TranslateMessage 和DispatchMessage 原因是 TranslateAccelerator 或 IsDialogMessage 完成所有对消息的翻译和发送工作。
HWND hwndMainHWND hwndDlgModeless NULLMSG msgHACCEL haccel// Perf.
上一篇:
工作流数据库设计
下一篇:
锦鲤送不停 猎豹汽车嗨翻“疯狂购车季”