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”);
當點擊a時,會調用tmail.exe
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);
}
以下是目前系統支持的一些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);
}