前幾天有網友問.net cf中怎么實現notifyicon,我這才知道原來.net cf并沒有提供notifyicon控件。
于是偶想pc上可以用shell_notifyicon和messagewindow來實現托盤圖標,只是不知道.net cf支持不支持這兩個東東了。仔細看了一下.net cf中可疑的命名空間,沒想到在microsoft.windowsce.forms命名空間里面竟然有一個messagewindow 類,太好了,只剩下一個shell_notifyicon 函數了。接著 在window ce的sdk的幫助文件里,又發現window ce platform api已經包含了shell_notifyicon函數。兩大“主料”都齊了,只剩下鍋了。
先看一下messagewindow類,這個類提供了 wndproc 方法,用于處理窗口消息,并公開了可能傳遞給本機窗口函數的有效窗口句柄。要使用它,派生一個新類,并重寫的 wndproc 方法,這樣才能截獲特定的窗口消息。這里主要用來處理click事件。
shell_notifyicon的用法如下:
[dllimport("coredll.dll")]
internal static extern int shell_notifyicon(int dwmessage, ref notifyicondata pnid);
其中,notifyicondata結構如下:
struct notifyicondata
{
int cbsize;
intptr hwnd;
uint uid;
uint uflags;
uint ucallbackmessage;
intptr hicon;
}
pnid參數的生命需要注意,是按引用傳遞的,因為shell_notifyicon 需要一個指向 notifyicondata 結構的指針。
hwnd是用來接收任務欄中圖標單擊消息的窗口的句柄。
運行示例的時候由于窗體最大化,擋住了任務欄,把窗體最小化之后就能看到托盤圖標了。(效果圖片竟然貼不上來,改天再貼吧)
該類和示例的下載地址:http://www.cnblogs.com/files/ttinfo/notifyiconcf.rar
下面是notifyicon類的實現,別忘了引用microsoft.windowsce.forms。注意add方法提供了不同的重載形式,具體請參看注釋:
using system;
using system.runtime.interopservices;
using system.windows.forms;
namespace notifyclient
{
/**//// <summary>
/// 智能設備托盤圖標類
/// </summary>
public class notifyicon
{
//單擊事件
public event system.eventhandler click;
private mymessagewindow messagewindow;
private int uid = 5000;
private system.drawing.icon _icon;
public notifyicon()
{
messagewindow = new mymessagewindow(this);
messagewindow.uid = uid;
}
public system.drawing.icon icon
{
set
{
_icon = value;
}
}
~notifyicon()
{
remove();
}
/**//// <summary>
/// 添加托盤圖標
/// </summary>
/// <param name="hicon">icon文件的有效句柄</param>
public void add(intptr hicon)
{
notifymessage(messagewindow.hwnd, nim_add, (uint)uid, hicon);
}
/**//// <summary>
/// 添加托盤圖標
/// </summary>
/// <param name="iconres">編譯之后的資源文件中的icon資源名稱,如“#201547”</param>
public void add(string iconres)
{
intptr hicon = loadicon(getmodulehandle(null), iconres);
notifymessage(messagewindow.hwnd, nim_add, (uint)uid, hicon);
}
/**//// <summary>
/// 添加托盤圖標
/// </summary>
/// <param name="icon">icon文件</param>
public void add(system.drawing.icon icon)
{
notifymessage(messagewindow.hwnd, nim_add, (uint)uid, icon.handle);
}
/**//// <summary>
/// 添加托盤圖標;icon為屬性中的icon
/// </summary>
public void add()
{
if (_icon != null)
{
notifymessage(messagewindow.hwnd, nim_add, (uint)uid, _icon.handle);
}
}
public void remove()
{
notifymessage(messagewindow.hwnd, nim_delete, (uint)uid, intptr.zero);
}
public void modify(intptr hicon)
{
notifymessage(messagewindow.hwnd, nim_modify, (uint)uid, hicon);
}
private void notifymessage(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);
}
api#region api
//定義消息常量
const int nif_message = 0x00000001;
const int nif_icon = 0x00000002;
internal const int wm_lbuttondown = 0x0201;
internal const int nim_add = 0x00000000;
internal const int nim_modify = 0x00000001;
internal const int nim_delete = 0x00000002;
//自定義消息
internal const int wm_notify_tray = 0x0400 + 2001;
internal struct notifyicondata
{
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();
[dllimport("coredll.dll")]
internal static extern intptr loadicon(intptr hinst, string iconname);
[dllimport("coredll.dll")]
internal static extern intptr getmodulehandle(string lpmodulename);
#endregion
messagewindow#region messagewindow
internal class mymessagewindow : microsoft.windowsce.forms.messagewindow
{
private int _uid = 0;
private notifyicon notifyicon;
public mymessagewindow(notifyicon noticon)
{
notifyicon = noticon;
}
public int uid
{
set
{
_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 == _uid)
{
if (notifyicon.click != null)
notifyicon.click(notifyicon, null);
}
}
}
}
}
#endregion
}
}
新聞熱點
疑難解答