适用于:
Microsoft® .NET Framework 精简版
Microsoft Visual Studio® .NET 2003
摘要:学习如何使用 .NET Framework 精简版中的 MessageWindow 类来创建 NotifyIcon。
下载 NotifyIcon.msi(英文)。(请注意,在示例文件中,程序员的注释使用的是英文,本文中将其译为中文是为了便于读者理解。)
简介
尽管 Microsoft® .NET Framework 精简版是一个丰富的 .NET Framework 类库子集,但作为子集就意味着并非 .NET Framework 完整版中所有可用的类、方法和属性在 .NET Framework 精简版中都可用。发送至托管控件的窗口消息的拦截就是这样一个例子。但 NET Framework 精简版实现了 MessageWindow 类,允许本地应用程序和托管应用程序通过 Windows 消息结构进行通信。
MessageWindow 是 Microsoft.WindowsCE.Forms 命名空间的一部分,因此必须在基于 .NET Framework 精简版的项目中添加对 Microsoft.WindowsCE.Forms.dll 程序集的引用。MessageWindow 类提供了 WndProc 方法,用于处理窗口消息并公开可能传递给本机窗口函数的有效窗口句柄。
要在程序中使用 MessageWindow,需要通过从 MessageWindow 派生来创建新类,并覆盖默认的 WndProc 行为,以便查看特定的窗口消息:
[C# using Microsoft.WindowCE.Forms; public class MyMessageWindow : MessageWindow { protected override void WndProc(ref Message msg) { switch(msg.Msg) { case WM_LBUTTONDOWN: //在此处执行操作 break; } // 调用基类 WndProc 处理默认消息 base.WndProc(ref msg); } }
使 MessageWindow 开始工作
了解 MessageWindow 用法的最佳方法是使用示例。
我们将创建一个 NotifyIcon 对象,以便在 Today(今日)屏幕的工具栏上放置一个图标。该对象还将在用户单击图标时通知我们,以便我们执行相应的操作。
Window CE Platform API 包含 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; }
请注意,由于 Shell_NotifyIcon 需要一个指向 NOTIFYICONDATA 结构的指针,因此将 NOTIFYICONDATA pnid 参数声明为按引用传递。
NOTIFYICONDATA 结构中的 hWnd 成员是窗口(将接收与任务栏状态区域中的图标关联的通知消息)句柄。这就是 MessageWindow 的方便之处。
我们首先创建名为 NotifyClient 的新 Microsoft Visual C#™ Smart Device Application(智能设备应用程序),然后选择 Pocket PC 平台和 Windows 应用程序作为项目类型。将新的 NotifyIcon.cs 类添加到此项目中,并插入以下包装了对 Shell_NotifyIcon 函数调用的辅助函数:
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace NotifyClient { public class NotifyIcon { 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; Shell_NotifyIcon(dwMessage, ref notdata); } } }
在上述代码中,我们创建了 NOTIFYICONDATA 结构的新实例,指定了所有必要的成员,并将该实例传递给 Shell_NotifyIcon 函数。
然后,将创建 MessageWindow 的子类,用于处理要从任务栏发送的消息。新类 WindowSink 将位于 NotifyIcon 的内部,因为我们不希望使用 NotifyIcon 类的客户端能够访问 MessageWindow 提供的消息循环:
internal class WindowSink : Microsoft.WindowsCE.Forms.MessageWindow { //私有成员 private int m_uID = 0; private NotifyIcon notifyIcon; //构造函数 public WindowSink(NotifyIcon notIcon) { notifyIcon = notIcon; } public int uID { set { m_uID = value; } } protected override void WndProc(ref Message msg) { if (msg.Msg == WM_NOTIFY_TRAY) { if((int)msg.LParam == WM_LBUTTONDOWN) { if ((int)msg.WParam == m_uID) { //如果某个用户被挂起,则引发事件 if (notifyIcon.Click != null) notifyIcon.Click(notifyIcon, null); } } } } }
在 WndProc 覆盖中,我们尝试捕获自定义消息 WM_NOTIFY_TRAY,以确定工具栏上的图标是否被点击。如果被点击,则引发 NotifyIcon 类的 Click 事件。需要在 NotifyIcon 类中按如下所示对 Click 事件进行声明:
public event System.EventHandler Click;
下一步,我们将添加这些公共方法:
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); }
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-126760/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10294527/viewspace-126760/