以前, 看见很多程序有这个功能,觉得这个功能太好了.并且很cool.
只需要在Today界面上点击这个图标,你的应用程序就会弹出来,实在是一个不错的功能.相当于桌面上的最大化和最小化.
相信在桌面上解决这个问题实在是easy,本质上是加个托盘图标.
切换到正题上来.
如何加入?查了一下.net cf库,你会发现没有提供相应的类以及函数.不过不要紧,如果有Windows API的Windows相关编程经验,你会注意到下面的问题还是相对简单的.
查找一下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
以上大部分代码来自此.