zoukankan      html  css  js  c++  java
  • 在Pocket PC的Today界面上的任务栏加入你的应用程序图标

    以前, 看见很多程序有这个功能,觉得这个功能太好了.并且很cool.

    只需要在Today界面上点击这个图标,你的应用程序就会弹出来,实在是一个不错的功能.相当于桌面上的最大化和最小化.

    相信在桌面上解决这个问题实在是easy,本质上是加个托盘图标.

    切换到正题上来.

    如何加入?查了一下.net cf,你会发现没有提供相应的类以及函数.不过不要紧,如果有Windows APIWindows相关编程经验,你会注意到下面的问题还是相对简单的.

    查找一下Windows提供的API,你会发现一个一个结构NOTIFYICONDATA.让我们看看这个结构干什么用的.下面的信息来自于MSDN:

    NOTIFYICONDATA结构包含了系统处理任务栏状态区域信息的信息.

    此结构为:

    typedef struct _NOTIFYICONDATA { 
      DWORD cbSize;
    //结构的大小
      HWND hWnd; //于任务栏图标相关的窗体句柄
      UINT uID; //任务栏图标的应用程序定义的标志符.
      UINT uFlags; //包含有效数据的标记
      UINT uCallbackMessage; //回调消息的标志符
      HICON hIcon; //图标的句柄
      WCHAR szTip[64]; //tips
    } NOTIFYICONDATA, *PNOTIFYICONDATA; 

    看了这个结构,就知道大概意思了.注意到此结构需要窗体的句柄,图标的句柄,以及事件的标志.有了这3个家伙,我们就可以实现了.

    那么哪一个函数调用此结构呢?答案是Shell_NotifyIcon,看看Shell_NotifyIcon的定义(MSDN):

    WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
      DWORD dwMessage, 
      PNOTIFYICONDATA pnid 
    );

    此方法有2个参数,前者指定发送的消息值它有3种消息: NIM_ADD,NIM_MODIFY,NIM_DELETE.这些就是对任务栏图标的操作.第二个参数就是NOTIFYICONDATA的指针形式.

    怎么样,知道怎么做了吧.

    好了,说了这么多开始实现它吧.

    首先写写NotifyIcon类吧,它用来增加和删除任务栏的图标.代码如下:

    /// <summary>
        
    /// IconNotify class, is used to add/remove the icon in Today screen.Also can send a notification to application.
        
    /// </summary>
        public class IconNotify
        {
            
    //Declare click event
            public event System.EventHandler Click;

            
    private WindowSink windowSink;
            
    private int uID = 5000;

            
    //Constructor
            public IconNotify()
            {
                
    //Create instance of the MessageWindow subclass
                windowSink = new WindowSink(this);
                windowSink.uID 
    = uID;
            }

            
    //Destructor
            ~IconNotify()
            {
                Remove();            
            }

            
    public void Add(IntPtr hIcon)
            {
                TrayMessage(windowSink.Hwnd, NIM_ADD, (
    uint)uID, hIcon);
            }

            
    public void Remove()
            {
            
                TrayMessage(windowSink.Hwnd, NIM_DELETE, (
    uint)uID, IntPtr.Zero);
            }

            
    public void Modify(IntPtr hIcon)
            {
                
                TrayMessage(windowSink.Hwnd, NIM_MODIFY, (
    uint)uID, hIcon);

            }

            
    private void TrayMessage(IntPtr hwnd, int dwMessage, uint uID, IntPtr hIcon)
            {
                NOTIFYICONDATA notdata 
    = new NOTIFYICONDATA();

                notdata.cbSize 
    = 152;
                notdata.hIcon 
    =  hIcon;
                notdata.hWnd 
    = hwnd;
                notdata.uCallbackMessage 
    = WM_NOTIFY_TRAY;
                notdata.uFlags 
    = NIF_MESSAGE | NIF_ICON;
                notdata.uID 
    = uID;

                
    int ret = Shell_NotifyIcon(dwMessage, ref notdata);
            } 

            
    #region API Declarations

            
    internal const int WM_LBUTTONDOWN = 0x0201;
            
    //User defined message
            internal const int WM_NOTIFY_TRAY = 0x0400 + 2001;

            
    internal const int NIM_ADD       =  0x00000000;
            
    internal const int NIM_MODIFY    =  0x00000001;
            
    internal const int NIM_DELETE    =  0x00000002;

            
    const int NIF_MESSAGE   =  0x00000001;
            
    const int NIF_ICON      =  0x00000002;

            
    /// <summary>
            
    /// Contains information that the system needs to process taskbar status area messages.
            
    /// </summary>
            internal struct NOTIFYICONDATA 
            { 
                
    /// <summary>
                
    /// Size of this structure, in bytes.
                
    /// </summary>
                internal int cbSize;
                
    internal IntPtr hWnd; 
                
    internal uint uID; 
                
    internal uint uFlags; 
                
    internal uint uCallbackMessage; 
                
    internal IntPtr hIcon; 
            }


            [DllImport(
    "coredll.dll")]
            
    internal static extern int Shell_NotifyIcon(
                
    int dwMessage,ref NOTIFYICONDATA pnid);
            
            [DllImport(
    "coredll.dll")]
            
    internal static extern int SetForegroundWindow(IntPtr hWnd);
            
            [DllImport(
    "coredll.dll")]
            
    internal static extern int ShowWindow( 
                IntPtr hWnd, 
                
    int nCmdShow); 
            
            [DllImport(
    "coredll.dll")]
            
    internal static extern IntPtr GetFocus();

            
    #endregion
    }

    但是看了上面的代码,总觉得少了一点什么东西似的,,那就是消息的触发.那么点击了任务栏的图标之后如何触发事件呢?首先我们得实现Tray Icon(托盘图标)事件,在此事件里,需要更进一步的实现WM_LBUTTONDOWN事件.但是如何实现了呢?幸运的是.net cf提供了一个Microsoft.WindowsCE.Forms.Message,它提供了托管消息与非托管消息的交互.这样就好办了.代码如下:

    #region WindowSink

            
    internal class WindowSink : Microsoft.WindowsCE.Forms.MessageWindow
            {
                
    //Private members
                private int m_uID = 0;
                
    private IconNotify notifyIcon;

                
    //Constructor
                public WindowSink(IconNotify notIcon)
                {
                    notifyIcon 
    = notIcon;    
                }
                
                
    public int uID
                {
                    
    set
                    {
                        m_uID 
    = value;

                    }    
                }

                
    protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message msg)
                {
                     
                    
    if (msg.Msg == WM_NOTIFY_TRAY)
                    {
                        
    if((int)msg.LParam == WM_LBUTTONDOWN)
                        {
                            
    if ((int)msg.WParam == m_uID)
                            {
                                
    //If somebody hooked, raise the event
                                if (notifyIcon.Click != null)
                                    notifyIcon.Click(notifyIcon, 
    null);
            
                            }
                        }    
                    }
                                    
                }
            }
            
    #endregion
    简单吧,,^_^

     FAQ:
    1)如何得到窗体的句柄?
       调用FindWindow()方法.具体参见MSDN.
    2)如何调用Icon的句柄?
     调用LoadIcon().具体参见MSDN.
    3)如何加入点击消息?
       实现NotifyIcon.Click事件.
    4)如何得到里面的常数?
       2种方法:1是直接根据MSDN在VC下的头文件里找.2是调用API Text Viewer工具.不过以上2种方法都需要你安装VS98.

    参考:http://www.microsoft.com/downloads/details.aspx?FamilyId=5A8384C0-34A5-47D1-BB50-E5E261288AE3&displaylang=en
    以上大部分代码来自此.

  • 相关阅读:
    Spring Boot 使用 Dom4j XStream 操作 Xml
    Spring Boot 使用 JAX-WS 调用 WebService 服务
    Spring Boot 使用 CXF 调用 WebService 服务
    Spring Boot 开发 WebService 服务
    Spring Boot 中使用 HttpClient 进行 POST GET PUT DELETE
    Spring Boot Ftp Client 客户端示例支持断点续传
    Spring Boot 发送邮件
    Spring Boot 定时任务 Quartz 使用教程
    Spring Boot 缓存应用 Memcached 入门教程
    ThreadLocal,Java中特殊的线程绑定机制
  • 原文地址:https://www.cnblogs.com/confach/p/406175.html
Copyright © 2011-2022 走看看