如何使用PPC Notification (显示图标到屏幕的顶部) [转]

来源:互联网 发布:淘宝免费开店是怎么回事 编辑:程序博客网 时间:2024/04/29 09:47

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);
         }