分类: WINDOWS
2010-06-24 17:49:50
从2003到WM5,PPC Notification 支持做了一下改进,但是SDK并没有做详细的描述,至少我下载的5.0 PPC SDK没有,只能自己硬啃头文件,所以我将自己一些平时使用Notification的一些心得记录下来,一来做个备忘(笔者忘东西的速度很快),二来也希望帮助下那些还没用过Notification的朋友,啃啃头文件真的很痛苦。
长话短说,让我们从最简单的开始:
1.最简单的Tray Notification:
const DWORD NOTIFICATION_ID = 4711; //定义Notification ID
const GUID guidNotificationSample = { 0x35466543, 0x77EF, 0x5676, { 0x23, 0x77, 0x35, 0xA2, 0x55, 0x3A, 0xB1, 0x43 } }; //定义clsid,你可以自己随意定制,当然这个clsid也有它自己的意义,通过它你可以在系统Notification设置页面由PDA用户对你的Notification进行个性化设置,这个在以后会介绍到。
SHNOTIFICATIONDATA g_NotifyData;
BOOL CreateNotification(LPCTSTR szHtml)
{
ZeroMemory(&g_NotifyData, sizeof(SHNOTIFICATIONDATA));
g_NotifyData.cbStruct = sizeof(SHNOTIFICATIONDATA);
g_NotifyData.npPriority = SHNP_ICONIC;//SHNP_INFORM;
g_NotifyData.csDuration = 5;
g_NotifyData.hwndSink = g_hWnd;
g_NotifyData.pszHTML = szHtml;
g_NotifyData.hicon = g_hIcon;
g_NotifyData.pszTitle = _T("Test Notification");
g_NotifyData.grfFlags = SHNF_DISPLAYON;
g_NotifyData.dwID = NOTIFICATION_ID;
g_NotifyData.clsid = guidNotificationSample;
return ERROR_SUCCESS == SHNotificationAdd(&g_NotifyData);
}
void RemoveNotification()
{
SHNotificationRemove( &(g_NotifyData.clsid), g_NotifyData.dwID );
}
我们基本上主要通过SHNotificationAdd通知Tray产生一个Notification,这个过程是异步的。通过SHNotificationRemove移除一个Notification。
现在我们来简要介绍一下SHNOTIFICATIONDATA结构,通过修改它的值我们可以产生不同样式的Notification.
typedef struct _SHNOTIFICATIONDATA
{
DWORD cbStruct; //通常为sizeof(SHNOTIFICATIONDATA)
DWORD dwID; //ID
SHNP npPriority; //priority, 目前有两种取值,SHNP_ICONIC代表只显示ICON,如图1-1所示,SHNP_INFORM表示在显示ICON的同时显示BUBBLE,如图1-2所示。
DWORD csDuration; // duration of the notification (usage depends on prio),注意单位为秒,当BUBBLE显示了指定时间后会自动收起。
HICON hicon; // the icon for the notification。
DWORD grfFlags; // 样式设置,接下来会详细讲述。
CLSID clsid; // unique identifier for the notification class
HWND hwndSink; // window to receive command choices, dismiss, etc.指定消息接收方窗口
LPCTSTR pszHTML; // HTML content for the bubble,设置需要在BUBBLE上显示的文本,注意它是支持HTML的,通过HTML我们可以显示出更加丰富的内容,这个以后也会提到。
LPCTSTR pszTitle; // Optional title for bubble,BUBBLE的标题
LPARAM lParam; // User-defined parameter
union
{ // Defines the softkey bar for the notification
SOFTKEYMENU skm; // Either pass an HMENU in skn (and set SHNF_HASMENU)
SOFTKEYNOTIFY rgskn[NOTIF_NUM_SOFTKEYS]; // or two softkeys in rgskn.
}; //这个UNION主要是为了个性化Notification的菜单和通知消息,以后会介绍。
LPCTSTR pszTodaySK; // Text to put on SK2 on the Today screen. If NULL, will default to "Notification"见下面的解释
LPCTSTR pszTodayExec; // What to execute when SK2 is pressed. If NULL, the toast will be displayed. 见下面的解释
} SHNOTIFICATIONDATA;
关于pszTodaySK和pszTodayExec在平时的工作中并没有用到,但是经过实验结果如下:
pszTodaySK用于在Today Screen左下BUTTON位置显示指定字符串(应该就是指的SK2)
pszTodayExec指定当SK2被点击时会被调用的程序全路径。
比如在CreateNotification中加上如下代码:
g_NotifyData. pszTodaySK = _T(“a”);
g_NotifyData. pszTodayExec = _T(“\\Windows\\tmail.exe”);
效果如图1-3所示,当点击a时,会调用tmail.exe
(图1-3)
2.不同样式的tray Notification:
通过设置不同的grfFlags,可以产生不同样式的Notification,下面来简单介绍一下各种值的含义:
SHNF_STRAIGHTTOTRAY:
直接放置ICON,但是默认不会弹出BUBBLE,只有当用户点击Tray Icon时,BUBBLE才会弹出。
SHNF_CRITICAL
将Notification的标题和边框加粗显示。
SHNF_FORCEMESSAGE
强制BUBBLE添加时自动弹出,并且忽略用户在Setting里对Notification的设置,作用与SHNF_STRAIGHTTOTRAY相反。
SHNF_DISPLAYON
默认BUBBLE添加时自动弹出,与SHNF_FORCEMESSAGE不同的是它会考虑用户对Notification的设置。
SHNF_SILENT
取消Notification显示时的声音和震动效果,通常在Update Notification时很有用。它不考虑用户对Notification的设置。
SHNF_HASMENU
表明提供了一个Menu,允许创建者加上自己的菜单。
以下四个因为平时没用过,待试过之后补充:
SHNF_TITLETIME // Draw the current time with the title
SHNF_SPINNERS // A notification with "stack" support
SHNF_ALERTONUPDATE // RE-play physical alerts on an update
SHNF_WANTVKTTALK //Capture the VK_TTALK button and forward it to the notification's sink window
3.Notification菜单管理
A) 使用Soft-Key:
我们可以通过设置SHNOTIFICATIONDATA里的成员:
SOFTKEYNOTIFY rgskn[NOTIF_NUM_SOFTKEYS];
来设置左右两个Sift-Key对应菜单(分别对应rgskn[0]和rgskn[1])。让我们修改下CreateNotification函数:
BOOL CreateNotification(LPCTSTR szHtml)
{
ZeroMemory(&g_NotifyData, sizeof(SHNOTIFICATIONDATA));
g_NotifyData.cbStruct = sizeof(SHNOTIFICATIONDATA);
g_NotifyData.npPriority = SHNP_ICONIC;//SHNP_INFORM;
g_NotifyData.csDuration = 5;
g_NotifyData.hwndSink = g_hWnd;
g_NotifyData.pszHTML = szHtml;
g_NotifyData.hicon = g_hIcon;
g_NotifyData.pszTitle = _T("Test Notification");
g_NotifyData.grfFlags = SHNF_DISPLAYON;
g_NotifyData.dwID = NOTIFICATION_ID;
g_NotifyData.clsid = guidNotificationSample;
g_NotifyData.rgskn[0].pszTitle = _T("L_SoftKey"); //显示BUTTON文字
g_NotifyData.rgskn[0].skc.grfFlags = NOTIF_SOFTKEY_FLAGS_DISMISS; //BUTTON flag,详细介绍看后面
g_NotifyData.rgskn[0].skc.wpCmd = 1000; //CMD ID,当用户点击该BUTTON时,将会发WM_COMMAND给通知窗口,WPARAM为该值。
g_NotifyData.rgskn[1].pszTitle = _T("R_SoftKey");
g_NotifyData.rgskn[1].skc.grfFlags = NOTIF_SOFTKEY_FLAGS_HIDE;
g_NotifyData.rgskn[1].skc.wpCmd = 1001;
return ERROR_SUCCESS == SHNotificationAdd(&g_NotifyData);
}
看看效果:
(图3-1)
以下是目前系统支持的一些Flag:
NOTIF_SOFTKEY_FLAGS_DISMISS // Remove the notification when the softkey is pressed,当用户点击时,自动移除Notification。
NOTIF_SOFTKEY_FLAGS_HIDE // Hide the notification when the softkey is pressed (but do not dismiss),当用户点击时,自动隐藏Notification。
NOTIF_SOFTKEY_FLAGS_STAYOPEN // Do not dismiss or hide the notification when the softkey is pressed,当用户点击时,不要移除或者隐藏Notification。
NOTIF_SOFTKEY_FLAGS_SUBMIT_FORM // Submit the HTML form in the associated notification instead of sending WM_COMMAND to the sink,提交HTML页面
NOTIF_SOFTKEY_FLAGS_DISABLED // This softkey is disabled,该BUTTON是disabled状态的
B) 使用自定义菜单:
首先自定义一个菜单,随便举个例子:
IDR_MENU MENU DISCARDABLE
BEGIN
POPUP "Menu"
BEGIN
MENUITEM "Menu 1", IDM_MENU_ONE
MENUITEM "Menu 2", IDM_MENU_TWO
MENUITEM "Menu 3", IDM_MENU_THREE
END
END
然后修改CreateNotification如下:
BOOL CreateNotification(LPCTSTR szHtml)
{
ZeroMemory(&g_NotifyData, sizeof(SHNOTIFICATIONDATA));
g_NotifyData.cbStruct = sizeof(SHNOTIFICATIONDATA);
g_NotifyData.npPriority = SHNP_ICONIC;//SHNP_INFORM;
g_NotifyData.csDuration = 5;
g_NotifyData.hwndSink = g_hWnd;
g_NotifyData.pszHTML = szHtml;
g_NotifyData.hicon = g_hIcon;
g_NotifyData.pszTitle = _T("Test Notification");
g_NotifyData.grfFlags = SHNF_DISPLAYON | SHNF_HASMENU; //加上SHNF_HASMENU,表示创建者会自行创建MENU
g_NotifyData.dwID = NOTIFICATION_ID;
g_NotifyData.clsid = guidNotificationSample;
g_NotifyData.skm.hMenu = ::LoadMenu( g_hInst, MAKEINTRESOURCE(IDR_MENU) ); //设置Menu资源
g_NotifyData.skm.cskc = 2; //说明我们有3个Item需要修改默认行为,关于这点需要说明一下,如果你没有为某个ITEM设置行为,默认如果用户点击了这个ITEM,那么Notification按照NOTIF_SOFTKEY_FLAGS_DISMISS处理,将会移除Notification。
g_NotifyData.skm.prgskc = new SOFTKEYCMD[2]; //分配空间
g_NotifyData.skm.prgskc[0].grfFlags = NOTIF_SOFTKEY_FLAGS_HIDE;
g_NotifyData.skm.prgskc[0].wpCmd = IDM_MENU_ONE; //说明Item:IDM_MENU_ONE行为为Hide。
g_NotifyData.skm.prgskc[1].grfFlags = NOTIF_SOFTKEY_FLAGS_STAYOPEN;
g_NotifyData.skm.prgskc[1].wpCmd = IDM_MENU_TWO; //说明Item:IDM_MENU_TWO行为为Stay Open。
//第3个ITEM: IDM_MENU_THREE我们没有给它设置,那么按照刚才所说的,点了它之后系统将会自动移除Notification。
return ERROR_SUCCESS == SHNotificationAdd(&g_NotifyData);
}
执行后效果如下图3-2所示,里面分配的内存和资源记着适时释放。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yzx0023/archive/2006/03/11/621849.aspx