• 在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
    以上大部分代码来自此.

  • 相关阅读:
    深入理解Aspnet Core之Identity(1)
    vscode同步插件 sync(gist,token)
    括号匹配问题
    EI目录下载地址及保护密码
    极简单的方式序列化sqlalchemy结果集为JSON
    OpenCvSharp 通过特征点匹配图片
    HttpWebRequest提高效率之连接数,代理,自动跳转,gzip请求等设置问题
    子网掩码划分
    使用批处理复制并以时间规则重命名文件
    九步确定你的人生目标
  • 原文地址:https://www.cnblogs.com/confach/p/406175.html
Copyright © 2020-2023  润新知