WinCE通知API的解析及在控制程序中的应用

本文详细介绍了Windows CE的通知API,包括定时器事件通知、系统事件通知和用户通知三种类型及其应用场景。通过具体代码实例展示了如何注册、配置和处理各种通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.sudu.cn/info/html/edu/20070313/232608.html

1 引言
    以Windows CE 为操作系统的掌上电脑(如PocketPC或HPC),除具有PC的功能外,还具有很强的自身控制能力。Windows CE API超越微软其它操作系统的 API的一个方面是它提供了一个强有力的通知接口(Notification API),该接口允许应用程序自己安排自己在某个确定的时间运行,或者在某个系统事件发生时运行,这使得我们可以应用它来设计开发各种高级控制程序,比如按时间或预订的事件来自动开启/关闭计算机,或按时间或预订的事件来自动开启/关闭一个或多个应用程序,乃至控制一个或多个应用程序的运行流程。

2  通知API的解析
    所谓通知是操作系统对发生的某个事件所发出的响应信号。Windows CE对定时器事件发出的响应信号即“定时器事件通知”,而对系统事件发出的响应信号即“系统事件通知”。定时器事件表明已经到达指定时间,系统事件表明发生了系统级事件,如添加或删除了某设备,系统时间更改了,与其它设备发生同步,检测到RS232口连接等。如果我们要在给定的时间直接运行某个应用程序(不用用户干涉),就可以简单地使用“定时器事件通知”,而当我们需要监控一些系统事件的发生时,就要使用″系统事件通知″。特别需要强调的是:除非不安装电池或处于死机状态,否则掌上电脑的电源始终不关闭;当用户按下关闭电源按钮或不使用时,机器也只是处于休眠状态而并没有真正切断电源(在休眠状态下,它仅提供能保持其时钟、应用程序及RAM中存储的数据所需的最少能量)。因此,对于注册使用“定时器事件通知”或″系统事件通知″的程序,即使系统是关闭的,当定时器事件到达时或发生系统事件时,要运行的应用程序也会启动。
    上述的“定时器事件通知”的使用虽然方便,但有时不能满足用户的要求。比如对于复杂的控制流程,不但到了指定时间要运行应用程序,而且要根据用户的不同反应进行不同的控制。因此,Windows CE还提供了第三种通知接口: ″用户通知″。″用户通知″也使用定时器事件,但与“定时器事件通知”不同,“用户通知”发生时必须被用户确认,从而到了“用户通知”指定的时间可根据用户的不同反应进行不同的流程控制。比如,当用户仅需在指定的时间作一下提示,则使用“用户通知”的应用程序可设计为以四种方式(闪动LED,振动设备,播放声音和显示提示框)提示用户,而且用户可随时更改提示方式。又比如,当用户要求不仅在指定的时间作一下提示,还要在用户做出确认后才使程序继续运行,这就只能使用“用户通知”而不能使用“定时器事件通知”。
    当我们把自己开发的程序注册到特定的事件通知后,操作系统将在该事件发生时生成一个通知。系统使用通知与用户和其它程序通信。Windows CE共提供了六个通知接口:CeSetUserNotification、CeGetUser NotificationPreferences、 CeCleartUserNotification、 Ce-HandleAppNotifications、CeRunAppAtTime和CeRun App AtEvent,前四个为″用户通知″所使用,后两个分别为“定时器事件通知”和″系统事件通知″所使用。下面分别介绍这六个API的使用方法:
    (1)函数CeSetUserNotification用于注册用户通知,其原型是:
    HANDLE CeSetUserNotification(HANDLE hNotification,TCHAR* pwszAppName,SYSTEMTIME* lpTime,PCE_USER_NOTIFICATION lpUserNotification);其参数含义是:句柄hNotification设置为0表示创建一个新的通知,而要更改已注册的通知则设置hNotification为希望更改的用户通知的句柄(这个句柄是由注册用户通知的程序在调用CeSetUserNotification后的返回值);pwszAppName是该应用程序的名称,当通知发生时,该应用程序的小图标将在任务栏上显示;lpTime是一个指向SYSTEMTIME结构指针,该结构指定了通知发生的时间;lpUserNotification也是一个结构指针,它指向PCE_USER_NOTIFICATION结构, Windows CE用该结构描述用户如何被通知,这个结构的定义是:
typedef struct UserNotificationType
DWORD ActionFlags;
TCHAR* pwszDialogTitle;
TCHAR* pwszDialogText;
TCHAR* pwszSound;
DWORD nMaxSound;
DWORD dwReserved;
?妖CE_USER_NOTIFICATION;
    其中变量ActionFlags是一组定义了在到达指定的时间时以何种形式提示用户的标志:PUN_LED(闪动屏幕),PUN_VIBRATE(振动设备),PUN_DIALOG(显示对话框),PUN_SOUND(播放声音文件)和PUN_REPEAT(重复声音文件10到15秒),它可以是上述标志的任意组合。从程序调用CeSetUserNotification开始到用户得到通知的这一时间段中,通知一直处于活动状态。如要在它超时之前修改此通知,程序可通过再次调用CeSetUserNotification来实现
    (2)调用CeGetUserNotificationPreferences(HWND hWndParent,PCE_USER_NOTIFICATION lpNotification))可配置用户通知,以便让用户能有修改提示方式的机会,其中hWndParent是提示框父窗口的窗口句柄。
    (3)调用CeCleartUserNotification(HANDLE hNo-tification)可以实现在用户通知到达之前清除它。
    (4)调用CeHandleAppNotifications 函数以确认用户通知。用户通知到达后要求确认。对于显示提示框的通知,确认的方式是点击提示框的确定按钮或按下设备外壳上的通知按钮(此时用户通知仅起到提示的作用,不启动应用程序);对于不显示提示框的通知,系统将在任务栏上显示注册该通知的程序的图标,当用户点击此图标时系统将启动相应的应用程序的一个实例(系统还传递一个命令行参数lpCmdLine以表明为什么应用程序会运行,该参数是串APP_RUN_ TO_HANDLE_NOTIFICATION加空格加通知的句柄)。对于不显示提示框的用户通知,在应用程序中要调用CeHandleAppNotifications 函数来确认通知,该函数将所有用于应用程序的活动通知都标记为已处理,并删除任务栏上的图标。在实际编码时还要考虑是否有该应用程序的另一个实例在运行,如有,则应向它发送一个自定义消息由该实例处理此通知并终止自身以节省资源。
    (5)调用BOOL CeRunAppAtTime(TCHAR* pwsz AppName,SYSTEMTIME* lpTime)生成“定时器事件通知”,其参数含义是:lpTime是一个结构指针,该结构指定了运行应用程序的时间;pwszAppName是要运行的应用程序的名称。由于只是在给定的时间自动运行某个应用程序,因此比较简单。要修改“定时器事件通知”,只要再次调用CeRunAppAtTime。因为后一次调用CeRunAppAtTime将替换前一次的通知。要清除“定时器事件通知”,只要在调用CeRunAppAtTime时,在参数lpTime中传递一个NULL指针。
    (6)调用BOOL CeRunAppAtEvent(TCHAR* pwsz-AppName,LONG lWhichEvent) 生成″系统事件通知″,其参数含义是:pwszAppName是要运行的应用程序的名称;lWhichEvent 是指出要监视哪一个事件,标志常量如下:
NOTIFICATION_EVENT_NONE     清除事件通知
NOTIFICATION_EVENT_SYNC_END       同步完成通知
NOTIFICATION_EVENT_DEVICE_CHANGE    添加或删除设备通知
NOTIFICATION_EVENT_RS232_DETECTED 检测到RS232连接通知
NOTIFICATION_EVENT_TIME_CHANGE 系统时间更改通知
NOTIFICATION_EVENT_RESTORE_END   设备恢复完成通知
    要停止响应系统事件通知,应用程序只要再次调用CeRunAppAtEvent,并在lWhichEvent参数中传递其名称和NOTIFICATION_EVENT_NONE。

3  通知API的使用代码实例
#include <notify.h>               
CE_USER_NOTIFICATION g_ceun;
(1) 对CE_USER_NOTIFICATION结构初始化的代码片段.   memset (&g_ceun, 0, sizeof (g_ceun));
    g_ceun.ActionFlags = PUN_DIALOG;
    g_ceun.pwszDialogTitle = szDlgTitle;
    g_ceun.pwszDialogText = szDlgText;
    g_ceun.pwszSound = szSound;
    g_ceun.nMaxSound = sizeof (szSound);
(2)注册用户通知的代码片段:
    SYSTEMTIME st;    GetLocalTime (&st);
    GetModuleFileName (hInst, szExeName, sizeof (szExeName));
    hNotify = CeSetUserNotification (0, szExeName, &st, &g_ceun);
(3)配置用户通知的代码段:
    CeGetUserNotificationPreferences (hWnd, &g_ceun);
(4)使用CeHandleAppNotifications并只运行一个实例(为节省资源)的代码段 :
      //判断应用程序的启动是否源于用户通知
if(lstrcmp(szText, APP_RUN_TO_HANDLE_NOTIFICATION)==0)
 GetMoudleFileName(hInst,szText,sizeof(szText));
 CeHandleAppNotifications(szText);
hNotify = (HANDLE)_wtol(pPtr);  //取通知的句柄
//检查是否已有应用程序的实例在运行
hWnd = FindWindow(NULL,szAppName);
if(hWnd)//如有,向它发送一个自定义消息,由它处理此用户通知
SendMessage(hWnd,MYMSG_TELLNOTIFY,0,(LPARAM)hNotify);
//终止自身, 代码略去
?妖
     ?妖
(5)使用“定时器事件通知”的代码段:
SYSTEMTIME st;    GetLocalTime (&st);
GetModuleFileName (hInst, szExeName, sizeof (szExeName));
CeRunAppAtTime (szExeName, &st);
(6)使用“系统事件通知”的代码段:
  LONG lEvent;
if (IsDlgButtonChecked(hWnd, IDC_SYNC_END)== 1)
lEvent |= NOTIFICATION_EVENT_SYNC_END;
if (IsDlgButtonChecked (hWnd,IDC_SERIAL_DETECT)== 1)
lEvent |= NOTIFICATION_EVENT_RS232_ DETECTED;
if (IsDlgButtonChecked(hWnd,IDC_DEVICE_ CHANGE)== 1)
lEvent |= NOTIFICATION_EVENT_DEVICE_ CHANGE;
if (IsDlgButtonChecked (hWnd, IDC_TIME_ CHANGE) == 1)
lEvent |= NOTIFICATION_EVENT_TIME_ CHANGE;
if (IsDlgButtonChecked (hWnd, IDC_RESTORE_ END) == 1)
lEvent |= NOTIFICATION_EVENT_RESTORE_END;
GetModuleFileName (hInst, szExeName,sizeof (szExeName);
CeRunAppAtEvent (szExeName, lEvent);
    以上我们介绍了Windows CE Notification API的使用方法,关于Windows CE应用程序开发环境的使用,可参考有关资料[1][2][3][4]。

参考文献
[1]Douglas Boling著,北京博彦科技发展有限公司 译. Microsoft Windows CE 程序设计.北京:北京大学出版社,1999
[2]田东风. IrSock 红外通讯的原理与实现. 微计算机信息,2001;(11)
[3]田东风. PPC上的MODEM通讯程序设计.微计算机信息,2000;(2)
[4]田东风. Windows CE应用程序开发实例.软件世界,2000;(1)
作者简介:田东风,中国地质大学(北京) 信息工程学院副教授,主要研究方向为人工智能,嵌入式系统应用。电话:010-82323183(O)。
(100083  北京  中国地质大学信息工程学院) 田东风



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值