注册通行证 用户名 密码
  • 文章投稿
  • 博客
  • 论坛
  • 设为首页
  • 加入收藏
jztop.com网络技术
  • 首页
  • | iT新闻
  • | 操作系统
  • | 组网建网
  • | 网络安全
  • | 程序开发
  • | 办公一族
  • | 工具软件
  • | 网页制作
  • | 多媒体制作
  • | 网吧技术
  • | 服务器
  • | 专题教程
Vista | 软件评测 | 系统备份 | 优化 | 进程 | 聊天 | 病毒 | Linux | 黑客 | 防火墙 | 数据库 | Web开发 | Java | Word | 游戏 | 32位开发 | 移动开发
当前位置:首页 > 程序开发 > 微软开发专栏 > C#.NET 内容正文:利用C#实现标注式消息提示窗口

利用C#实现标注式消息提示窗口

发布时间:2006-10-13 09:43:00 来源:友佳学院 网友评论 0 条

  近一段时间由于项目需要一直专注于UI方面的编程,为了更加友好的将提示信息呈现给用户,我们必须对标准的Windows消息提示窗口进行处理。我们大家在Windows XP下使用U盘、闪存等移动存储设备,当插上或拔下这些设备时任务栏区域都会显示一个淡黄色背景,且具有标注样式的提示窗口弹出来,这样的提示即友善又美观,那么这到底是怎么实现的呢?其实道理并不复杂,该标注式提示窗口本身就是一个不规则窗体,当显示时它会将标注窗口的箭头指向不同控件。如下图:


一般情况下的p标注式提示窗口

屏幕边缘的标注式提示窗口


  一、技术要点

  就像本文开头所说的"标注式消息提示窗口"其实就是一个具有不规则外形的窗体,但却具备了更加复杂的属性和行为。标注的箭头会根据不同控件指向不同的位置,当需要标注的控件过于接近屏幕的边缘时,标注窗口还会自动调整显示位置以及箭头的长短和大小。

  我们为新创建的窗体取名为InfoWindow。在类的头部定义intArc和intArrowHeight两个私有变量,可以适当调整它们的值来微调提示窗口的位置和箭头的大小与位置。

  提示窗口的箭头位置无非具有左上、右上、左下和右下四个可能性,我们为此定义了枚举类型的变量ArrowLocation,根据提示窗口位于屏幕的不同位置,GetArrowLocation可以计算提示窗口的位置并且返回适当的ArrowLocation,定义如下:

……
public enum ArrowLocation
{
 TopLeft,
 TopRight,
 BottomLeft,
 BottomRight
}

  SetInfoWindowRegion函数非常重要,它在Form.Load事件即装载和显示提示窗体时被调用,当计算出新的提示窗口的位置和箭头显示位置后,调用SetBounds将更新后的位置和大小应用到提示窗口,gPath是GraphicsPath类型的私有变量,它表示标注式窗口的不规则图形路径,该图行路径也是根据提示窗口的位置和箭头显示的位置来创建,gPath.AddArc方法用来绘制提示窗口四个边角的弧度部分,和AddLine方法一起描绘出提示窗口包括箭头的轮廓,一切就绪后我们就用这个gPath对象传递给Region对象,当将这个Region对象赋给Form窗体的Region属性后,窗体就具备了标注式提示窗口样式的不规则外形了,部分代码如下:

private void SetInfoWindowRegion()
{
 if (!this.IsHandleCreated)
  return;
 System.Drawing.Size windowSize = this.Size;
 Point[] ArrowPoints = new Point[3];
 Point topLeftPoint = Point.Empty;
 Point bottomRightPoint = (Point)windowSize;
 switch (this.GetArrowLocation)
 {
  case ArrowLocation.TopLeft:
   ……
  case ArrowLocation.TopRight:
   ……
  case ArrowLocation.BottomLeft:
   ……
  case ArrowLocation.BottomRight:
   ……
 }
 ……
 ……
 if ((this.GetArrowLocation == ArrowLocation.TopLeft) ||
(this.GetArrowLocation == ArrowLocation.TopRight))
 {
  gPath.AddArc(topLeftPoint.X, rectY2 - arcRadius, arcDia, arcDia, 90, 90);
  gPath.AddLine(topLeftPoint.X, rectY2, topLeftPoint.X, rectY1);
  gPath.AddArc(topLeftPoint.X, topLeftPoint.Y, arcDia, arcDia, 180, 90);
  gPath.AddLine(rectX1, topLeftPoint.Y, ArrowPoints[0].X, topLeftPoint.Y);
  gPath.AddLines(ArrowPoints);
  gPath.AddLine(ArrowPoints[2].X, topLeftPoint.Y, rectX2, topLeftPoint.Y);
  gPath.AddArc(rectX2 - arcRadius, topLeftPoint.Y, arcDia, arcDia, 270, 90);
  gPath.AddLine(bottomRightPoint.X, rectY1, bottomRightPoint.X, rectY2);
  gPath.AddArc(rectX2 - arcRadius, rectY2 - arcRadius, arcDia, arcDia, 0, 90);
  gPath.AddLine(rectX2, bottomRightPoint.Y, rectX1, bottomRightPoint.Y);
 }
 else
 {
  gPath.AddLine(rectX1, topLeftPoint.Y, rectX2, topLeftPoint.Y);
  gPath.AddArc(rectX2 - arcRadius, topLeftPoint.Y, arcDia, arcDia, 270, 90);
  gPath.AddLine(bottomRightPoint.X, rectY1, bottomRightPoint.X, rectY2);
  gPath.AddArc(rectX2 - arcRadius, rectY2 - arcRadius, arcDia, arcDia, 0, 90);
  gPath.AddLine(rectX2, bottomRightPoint.Y, ArrowPoints[0].X, bottomRightPoint.Y);
  gPath.AddLines(ArrowPoints);
  gPath.AddLine(ArrowPoints[2].X, bottomRightPoint.Y, rectX1, bottomRightPoint.Y);
  gPath.AddArc(topLeftPoint.X, rectY2 - arcRadius, arcDia, arcDia, 90, 90);
  gPath.AddLine(topLeftPoint.X, rectY2, topLeftPoint.X, rectY1);
  gPath.AddArc(topLeftPoint.X, topLeftPoint.Y, arcDia, arcDia, 180, 90);
 }
 gPath.CloseFigure();
 this.Region = new Region(this.gPath);
}

  ShowInfoWindow函数用来将提示窗口显示出来,该函数需要将提示窗口附着的控件和需要显示的文本传递过来。然后,AnchorPointFromControl根据控件的位置返回提示窗口的箭头应该显示的坐标,代码如下:

public static Point AnchorPointFromControl(Control anchorControl)
{
 if (anchorControl == null)
 throw new ArgumentException();
 Point controlLocation = anchorControl.Location;
 System.Drawing.Size controlSize = anchorControl.Size;

 if (anchorControl.Parent != null)
  controlLocation = anchorControl.Parent.PointToScreen(controlLocation);
 return controlLocation + new Size(controlSize.Width / 2, controlSize.Height / 2);
}

  PointToScreen表明将工作区点的位置映射成屏幕坐标统一进行计算。上述代码最后以行说明提示窗口的箭头显示在附着控件的中点。

  将提示窗口的背景颜色设置成Info,外观如下图:


  我们发现这样的外观有点别扭,没错!因为提示窗口缺少黑色边框!所以,还需要在窗体的OnPaint事件中添加代码,如下:

protected override void OnPaint(PaintEventArgs e)
{
 Pen p = new Pen(Color.Black , 2);
 e.Graphics.DrawPath(p, gPath);
 base.OnPaint(e);
}

  二、程序实现

  启动Visual Studio 2005,新建Visual C#的Windows 应用程序项目,并取名为ShowInfoWindow,添加4个Button组件、1个Label组件、1个textBox组件和3个Panel组件,其中3个Button用来显示标注式消息提示窗口并分别附着在三个组件之上,代码如下:

……
private InfoWindow iw;
……
private void button1_Click(object sender, EventArgs e)
{
 iw = new InfoWindow();
 iw.ShowInfoWindow(label1, "关于标签组件的提示说明。");
}
private void button3_Click(object sender, EventArgs e)
{
 iw = new InfoWindow();
 iw.ShowInfoWindow(button2, "关于按钮组件的提示说明。");
}

private void button4_Click(object sender, EventArgs e)
{
 iw = new InfoWindow();
 iw.ShowInfoWindow(textBox1, "关于文本框组件的提示说明。");
}

  然后,我们在项目中添加新Windows窗体,取名为InfoWindow,将InfoWindow的BackColor设为Info,FormBorderStyle设为None,将ShowIcon和ShowInTaskbar都设为False,在窗体上放置1个Label组件和1个Button组件,分别用来显示消息内容和关闭提示窗口的操作。具体实现请参见文章附带的源码,这里不再详述。

  三、总结

  本文演示了标注式消息提示窗口的创建和显示,利用GraphicsPath对象、Region对象以及屏幕坐标映射等方法有效的实现了提示窗口的外观和样式,提示窗口可以自动附着在相应控件之上,并且根据附着控件在屏幕上的位置自动调整提示窗口箭头的位置和大小。演示程序在Windows XP SP2以及.Net 框架 2.0环境下运行通过。
相关文章
  • C#操作xml文件入门
  • 用C#和ADO.NET建立一个数据绑定网格
  • C#处理数码相片之马赛克的实现
  • Visual C# 诠释常用排序算法
  • 用C#通过网址得到域名
【评论】【收藏本文】【打印】【关闭】
上一篇文章:C#操作xml文件入门
下一篇文章:使用C#开发SmartPhone程序入门
讨论区
查看
已有 0 位对此新闻感兴趣的网友发表了看法
匿名发表
注册通行证 登陆
图文阅读推荐
推荐阅讯
  • 用C#和ADO.NET建立一个数据绑定网格
  • C#箴言:定义常量的两种方法
  • 用C#实现生成PDF文档(附源码)
  • C#+ASP.NET开发基于Web的RSS阅读器
  • C# 3.0中新匿名类型特性初体验
  • 《C语言程序设计》教学的几点体会
  • C# 3.0 新特性:扩展方法初探
  • 叩开C#之门系列之C#与面向对象编程语言
  • 如何在C#中播放AVI短片并使背景透明
  • 使用C# 2.0泛型实现单例模式重用
阅读排行
  • 1.Visual C#组件技巧之深入ComboBox美容
  • 2.用C#实现HTTP协议下的多线程文件传输
  • 3.《C语言程序设计》教学的几点体会
  • 4.对C#中的TreeView添加背景图
  • 5.使用C#开发SmartPhone程序入门
  • 6.Visual C#中编写多线程程序之起步
  • 7.Visual C#实现HTTP代理服务程序
  • 8.用Visual C#打造多页面网页浏览器
  • 9.深入理解C#编程中的组件-事件-委托
  • 10.利用C#实现标注式消息提示窗口
专题教程
  • 大话G游 专题:手机病毒揭密
  • ARP攻击防范与解决方案 路由故障处理手册
  • Picasa中文版_Picasa教程 专题:清除流氓软件
  • Firefox专题 seo搜索引擎优化专区
  • 重装Windows必知的事情 装机之必备软件大行动
病毒专杀栏
  • 杀毒软件反被病毒杀 连"救命"都不能喊
  • 金山ARP防火墙
  • 还原卡神话破灭“机器狗”病毒来势汹汹
  • cctv经济半小时:你的手机现在安全吗?
  • 新挂马方式开始流行 ARP挂马称雄局域网
  • 木马和病毒清除的通用解法
  • IP地址不再冲突 查找ARP攻击者元凶
  • 教你几招识别和防御Web网页木马
  • 分析:封杀BT只是暂时的止痛药
  • QQ爆危险漏洞,“QQ游戏邀请大盗”邀请你玩病
关于我们 | 诚聘英才 | 联系我们 | 版权声明 | 网站大事 | 网站地图 | 意见建议
CopyRight 2005-2007 Jztop.Com 版权所有 未经许可 请勿转载