posts - 1,  comments - 1,  trackbacks - 0

WINDOWS CE的消息处理机制(一)


学习过windows编程的人,都明白windows的消息处理机制,在Windows CE中继承了这种机制。

为了能够获得消息,需要调用GetMessage函数
通常一个工程在消息循环中调用GetMessage函数

下面的代码,显示了如何在消息循环中调用GetMessage函数

while (GetMessage(&msg, NULL, 0, 0))
{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

当一个线程调用GetMessage函数时,Windows CE检测消息队列,Windows CE按照以下的步骤处理消息:

(1)Windows CE检测消息队列,这些消息是通过SendMessage函数产生的。当系统从消息队列提取消息后,它通过GetMessage函数将消息发送到适当地窗体过程,这样就可以保证消息的发送和接收保持同步。必须通过调用GetMessage函数才能保证消息被处理。

(2)如果没有通过SendMessage得到的消息,Windows CE检测由PostMessge发送的消息队列。

(3)如果没有通过PostMessage得到的消息,Windows CE检测用户用户输入消息。
在处理用户输入消息时,系统保证在处理下一个消息以前已经处理结束前一个输入的消息。

(4)如果没有用户输入消息,Windows CE检测WM_QUIT消息,该消息是由PostQuitMessage函数发送的。

(5)如果没有WM_QUIT消息,Windows CE检测WM_PAINT消息。

(6)如果没有WM_PAINT消息,Windows CE检测WM_TIMER消息

当GetMessage接收到任何消息,它返回消息的内容,该线程必须调用DispatchMessage函数来把消息发送到正确的窗体处理过程。如果这个消息是WM_QUIT消息,GetMessage函数的返回值为0,触发线程结束消息循环。

系统处理的消息是通过GetMessage函数在消息循环中的调用,又通过在消息循环中调用DispatchMessage函数来处理分派消息。

在通过DispatchMessage函数分发通过GetMessage得到的函数以前,用户可能需要处理这些消息,最常用的函数就是TranslateMessage, TranslateAccelerator, 和IsDialogMessage这三个函数。其中的一些函数可以自己分发消息,这样就必再次调用DispatchMessage来分发消息。


WINDOWS CE的消息处理机制(二)

用户通常使用TranslateMessage函数。该函数可以决定哪些字符对应相应的键盘消息。该函数同时也可以将字符发送到消息队列中,让下一次消息循环继续处理。

截取键盘消息产生菜单命令,用户可以调用TranslateAccelerator 函数,要对无模式对话框进行适当的操作需调用IsDialogMessage函数。

下面的例子向用户显示一个消息循环的例子,它使用到了DispatchMessage函数, TranslateMessage函数, TranslateAccelerator函数,和IsDialogMessage函数以及GetMessage函数。

while (GetMessage(&msg, NULL, 0, 0))
{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

if (hwndDLGCurrent != NULL || !IsDialogMessage(hwndDLGCurrent,

&msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}
}
}

用户可以通过GetMessage函数取得消息队列中的事件,并且从消息队列中去除该消息,用户也可以用PeekMessage函数从一个消息队列中获得消息,但却不必从消息队列中去除它。

通过该函数可以把有关消息的信息填充到MSG结构中。使用PeekMessage函数时要小心,因为它并不会阻止消息的等待,这样一个程序就会不管消息队列中是否有消息而不停地运行,这样CPU就不会处于low-power 模式,从而导致电池用电量过大。

当处理消息的时候,Windows CE不仅支持系统定义的消息同时也支持用户自定义的消息。系统消息定义从0到0x3ff,用户可以使用0x400到0x7fff定义自己的消息。Windows CE把0x400定义为WM_USER。如果用户想定义自己的一个消息。可以在WM_USER上加上一个值。下面的过程讲述了如何进行自定义消息。

#define WM_MYNEWMESSAGE (WM_USER + 999)

有两种系统定义的消息,一种是窗体消息,使用于所有的窗体,还要一种是特殊目的的消息,应用于一定的窗体类。通常的窗体消息覆盖的范围非常大,包括输入设备和一些键盘的消息,同时也包括一些如窗体建立和管理的消息。 一定的消息包含有特定的前缀,比如说,一个通常的WINDOWS消息通常以WM开头,属于按钮的消息通常以BM开头。

用户可以定义自己的消息,如果定义消息,一定要保证窗体过程争取地接收和解释消息,因为操作系统不会自动地处理用户定义的消息。

偶尔,用户也需要通过消息和别的进程中的休息保持通信。这种情况下,用户必须通过调用RegisterWindowMessage 函数来注册一个消息句柄。这样就可以保证消息号在整个系统中是唯一的,从而避免了不同的进程使用相同的消息号,造成冲突。

Windows CE不支持钩子函数,因为钩子函数需要的额外进程会不利于WINDOWS CE的执行。

在一个程序中处理消息序列时,请注意WM_HIBERNATE 消息。WINDOWS CE在系统资源不足时,通过WM_HIBERNATE 消息来通知应用工程。当一个工程接受到这个消息,它就会尽可能地释放资源。系统每隔五秒钟检测一次系统内存状态。

每一个WINDOWS CE的应用工程由于要适当地使用内存,所以都要能接收WM_HIBERNATE 消息。

如果一个应用工程的窗口不可见,该工程不能接收WM_HIBERNATE 消息。之所以收不到该消息,是因为WM_HIBERNATE 消息仅仅被发送到一个在任务栏上有相应菜单的工程。一个隐藏的窗体即使是占用内存很多,也不会接收到该消息。

posted on 2009-06-01 19:22 Aiscanf 阅读(1949) 评论(1)  编辑 收藏 引用 所属分类: Wince

FeedBack:
# re: wince中消息处理
2010-01-14 16:31 | as
winCE同样不接受窗口非客户区产生的消息,如WM_NCMOUSEMOVE
我想当鼠标在非客户区移动是写些代码你有办法处理吗?有的话给我指点指点,
crow024@163.com  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2010年1月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿

随笔档案

文章分类

文章档案

搜索

  •  

最新评论

  • 1. re: wince中消息处理
  • winCE同样不接受窗口非客户区产生的消息,如WM_NCMOUSEMOVE
    我想当鼠标在非客户区移动是写些代码你有办法处理吗?有的话给我指点指点,
    crow024@163.com
  • --as