使用 Microsoft .NET Framework 精简版中的 MessageWindow 类 收藏

Alex Yakhnin
IntelliProg, Inc.
2003年3月

适用于:
    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 消息结构进行通信。

MessageWindowMicrosoft.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);
}

重要信息:应用程序退出时,必须从工具栏删除此图标。这就是我们应该在 NotifyIcon 类的析构函数中添加清除代码的原因:

//析构函数~NotifyIcon(){   Remove();}

所有必要的代码都必须提供所需功能。

请记住,本文所列举的只是部分代码。可以下载整个代码示例,请参阅本文开头的链接。

生成客户端

现在,即可使用创建的 NotifyIcon 类。首先,我们将向创建的 NotifyClient 项目中添加应用程序图标。要完成此操作,需要从 Visual Studio 主菜单中选择 Project(项目)- Properties(属性)来打开 Project Properties Dialog(项目属性)对话框。选择 Application Icon(应用程序图标)项,并指定您选择的图标文件。

图 1:Project Properties(项目属性)对话框

编译程序时,我们选择的图标将成为本机资源,可以使用 LoadIcon 平台 API 调用进行检索:

[DllImport("coredll.dll")]internal static extern IntPtr LoadIcon(IntPtr hInst, string IconName);

此函数中的第二个参数是已编译程序中的应用程序图标的资源标识符。通过使用资源管理器在已编译的可执行文件中拾取,我发现基于 .NET Framework 精简版的应用程序图标与本机应用程序“#32512”的资源标识符相同。因此,现在我们已拥有调用 NotifyIcon 类所需的全部信息。让我们在表单上对齐两个按钮,并在其 click 事件中插入以下代码:

private void cmdAddIcon_Click(object sender, System.EventArgs e){   IntPtr hIcon = LoadIcon(GetModuleHandle(null), "#32512");   notifyIcon.Add(hIcon);}

private void cmdRemoveIcon_Click(object sender, System.EventArgs e)
{
notifyIcon.Remove();
}

不要忘记连接到 NotifyIcon 的 Click 事件,以便在用户点击图标时获得通知:

public Form1(){   //   // Windows Form Designer(Windows 窗体设计器)支持所需   //   InitializeComponent();   // 创建实例   notifyIcon = new NotifyIcon();   // 连接到事件   notifyIcon.Click+=new EventHandler(notifyIcon_Click);}

private void notifyIcon_Click(object sender, EventArgs e)
{
MessageBox.Show("图标被单击!");
}

因此,运行程序后,点击 Add Icon(添加图标)按钮并切换到 Pocket PC 上的 Today(今日)视图,应该可以看到所创建的图标:

图 2:Today(今日)屏幕

点击图标将立即引发 notifyIcon_Click 事件并显示一个消息框:

图 3:已捕获的事件

小结

我们刚刚完成了 NotifyIcon 类的创建,即通过 P/Invoke 使用 Windows CE API,以及将 MessageWindow 类用作接收与工具栏上的图标关联的通知消息的窗口。

转载于:https://www.cnblogs.com/lanru/archive/2010/10/19/1855520.html

使用 Microsoft .NET Framework 精简版中的 MessageWindow 类相关推荐

  1. Microsoft .NET Framework 各版可再发行组件包

    Microsoft .NET Framework 各版可再发行组件包 Microsoft .NET Framework 各版可再发行组件包 Microsoft .NET Framework 2.0 版 ...

  2. 可用于在 Microsoft.NET Framework 4.0 中的 ASP.NET 浏览器定义文件的修补程序

    http://support.microsoft.com/kb/2600088 此修补程序为 Internet Explorer 和 Mozilla Firefox 在浏览器定义文件引入了更新的定义. ...

  3. Microsoft Sync Framework 2.1 软件开发包 (SDK)

    Sync Framework 2.1 引入了新功能,这些功能支持您计算机上的 SQL Server 或 SQL Server Compact 数据库与 SQL Azure 数据库进行同步.此发行版还引 ...

  4. oracle10g精简版配置,oracle 10g 精简版安装步骤分享

    今天遇到个软件要求安装oracle client端,于是考虑装精简版本的,就从http://www.oracle.com/technology/software/tech/oci/instantcli ...

  5. oracle11g客户端完整版和精简版安装教程

    完整版 一.创建用户和组 [root@zhjhapp6 ~]# groupadd oinstall [root@zhjhapp6 ~]# groupadd dba [root@zhjhapp6 ~]# ...

  6. 稳安快ghost win7 x64 sp1 超级精简版v2.0试用报告

    昨天忍无可忍无须再忍,将win8所有相关东西都清理掉了.打算换个win7.先说说我为什么热衷精简版.原因特别简单,我只有一个4G的u盘,大白菜启动占了550M,乱七八糟的装机必备软件占了400M,需要 ...

  7. Oracle Database Client 11gR2 精简版 发布

    Oralce Database Client 是我从 Oralce 11gR2 的官方客户端安装包中,精简而来的 Oracle 数据库客户端.除了可以连接远程数据库以外,还包含 SQL Plus.JD ...

  8. oracle精简版_使用Entity Framework Core访问数据库(Oracle篇)

    前言 哇..看看时间 真的很久很久没写博客了 将近一年了. 最近一直在忙各种家中事务和公司的新框架  终于抽出时间来更新一波了. 本篇主要讲一下关于Entity Framework Core访问ora ...

  9. Win7 旗舰版 SP1环境下安装Microsoft .NET Framework 4.8

    [问题描述] 在Win7 旗舰版 SP1环境下安装ArcGIS Pro 2.5时,弹出一个错误提示:ArcGIS Pro requires Microsoft .NET Framework 4.8 于 ...

最新文章

  1. 【深度学习入门到精通系列】CIFAR-10数据集说明
  2. 清华大学计算机系71班张晨,“神仙打架”要来了!网友:又到了凡人围观的时刻...
  3. 利用js实现 禁用浏览器后退| 去除上一个历史记录链接
  4. 论文浅尝 | 基于Universal Schema与Memory Network的知识+文本问答
  5. HttpClient4.5 简单入门实例(一)
  6. 微信小程序服务器支付sdk,微信小程序之支付后如何调用SDK的异步通知
  7. 在Java中避免NullPointerException
  8. SQL SERVER 2008传递表值参数
  9. activiti mysql_基于MySQL的Activiti6引擎创建
  10. 【06月18日】A股滚动市净率PB历史新低排名
  11. 【安全资讯】关键信息基础设施安全保护条例,自2021年9月1日起施行
  12. 访问局域网计算机切换用户,Win7切换用户账户访问共享文件夹的方法
  13. 关于灵魂,意识,自我和死亡
  14. PCM音频 I2S音频
  15. 一篇解释清楚Cookie是什么?
  16. PLC模拟量传输过程
  17. Python|Anaconda安装
  18. 在 JavaScript 中 0 与 1 和 true 与 false 的关系
  19. Android studio登陆注册的实现及介绍
  20. JQuery 查询文档元素

热门文章

  1. 【深度学习】像素级分割网络新思路之DeepLabv3+
  2. 【响应式Web前端设计】Register Demo
  3. python【数据结构与算法】选数问题(选不相连最大值——DP)
  4. 覆盖分类的方法_老罗讲分类|垃圾分类回收模式到底用哪种好?
  5. android利用反射调用截屏api,Android利用反射机制调用截屏方法和获取屏幕宽高的方法...
  6. 百度网络推广总结大家在做页面标题优化时需注意的事项!
  7. 网站内部优化的4个细节小技巧
  8. 如何快速增加网站收录?
  9. 裸奔浏览器_大概是最好用的隐私浏览器 - Firefox Focus
  10. Android Retrofit @Streaming 注解失效(二)