实例007 任务栏通知窗体
实例说明
在日常上网的过程中,有时候会发现任务栏的右下角有一个图标在闪烁,单击后会弹出一条提示信息。本实例模拟该过程的实现效果。实例运行结果如图1.8所示。
图1.8 任务栏通知窗体
技术要点
本实例主要通过Timer组件的时间事件来实现窗体状态的判断,在显示的过程中借助Windows提供的API函数ShowWindow。
ShowWindow函数用来显示窗体。其语法如下:
[DllImportAttribute("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hwnd,Int32 cmdShow);
参数说明如下。
◇ hwnd:将要显示的窗体的句柄。
◇ cmdShow:将要显示的窗体的类型。
◇ 返回值:返回true,表示窗体显示成功;返回false,表示窗体显示失败。
实现过程
01 新建一个项目,将其命名为TaskMessageWindow,修改默认窗体为TaskMessageWindow;添加一个Windows窗体,将其命名为MainForm。
02 在TaskMessageWindow窗体中添加2个Button控件、3个Label控件以及1个TextBox控件和RichTextBox控件,设置该窗体的StartPosition属性为CenterScreen。在MainForm窗体中添加2个Label控件、3个Timer组件、1个PictureBox控件、1个ImageList控件和1个NotifyIcon控件,修改displayCounter组件中的Interval属性为1000,修改iconCounter组件中的Interval属性为400。
03 主要代码。
在TaskMessageWindow窗体中需要定义及声明一些变量。代码如下:
01 public static string MainFormTitle = ""; //通知窗体的标题内容
02 public static string MainFormContent = "";//通知窗体的文本内容
03 MainForm InformWindow = new MainForm(); //实例化类MainForm的一个对象
在TaskMessageWindow窗体中,当用户输入完通知标题和通知内容后,单击“通知”按钮,在任务栏中会出现一个闪烁图标。代码如下:
01 private void informButton_Click(object sender,EventArgs e)
02 {
03 MainForm.IconFlickerFlag = true; //设置图标闪烁标识
04 InformWindow.IconFlicker(); //调用闪烁图标方法
05 }
在上面的代码中,闪烁图标用到IconFlicker方法和iconCounter计时器的Tick事件。代码如下:
01 public void IconFlicker()//自定义方法用来使托盘图标闪烁
02 {
03 if(MainForm.IconFlickerFlag != false) //当托盘闪烁图标为真时
04 {
05 taskBarIcon.Icon = Properties.Resources._1;//托盘图标显示为图片
06 iconCounter.Enabled = true;//启动托盘图标的Timer
07 //在titleInform中显示通知标题
08 titleInform.Text = TaskMessageWindow.MainFormTitle;
09 //在contentInform中显示通知内容
10 contentInform.Text = TaskMessageWindow.MainFormContent;
11 }
12 }
13 private void iconCounter_Tick(object sender,EventArgs e)
14 {
15 if(IconFlag) //当该值为真时
16 {
17 taskBarIcon.Icon = Properties.Resources._1; //设定托盘控件的图标
18 IconFlag = false; //修改该值为假
19 }
20 else //当该值为假时
21 {
22 taskBarIcon.Icon = Properties.Resources._2; //设定托盘控件的图标
23 IconFlag = true; //修改该值为真
24 }
25 }
当阅读完提示信息后,单击“关闭”按钮,任务栏中的闪烁图标消失。代码如下:
01 private void closeInform_Click(object sender,EventArgs e)
02 {
03 InformWindow.CloseNewWindow(); //关闭新显示的窗体
04 }
在上面的代码中,让闪烁图标消失用到CloseNewWindow方法。代码如下:
01 public void CloseNewWindow()
02 {
03 base.Hide();//隐藏该窗体
04 iconCounter.Enabled = false;//设定计时器iconCounter不可用
05 taskBarIcon.Icon = Properties.Resources._2;//设定托盘图标
06 MainForm.IconFlickerFlag = false;//更改静态变量IconFlickerFlag的值
07 }
在MainForm窗体中需要显示通知标题和通知内容,因此在TaskMessageWindow窗体中需要保存通知的标题和内容。代码如下:
01 private void title_TextChanged(object sender,EventArgs e)
02 {
03 MainFormTitle = title.Text; //记录通知的标题
04 }
05 private void content_TextChanged(object sender,EventArgs e)
06 {
07 MainFormContent = content.Text; //记录通知的内容
08 }
在MainForm窗体的加载过程中,应该在它的构造函数中定义窗体的工作区。代码如下:
01 public MainForm()
02 {
03 InitializeComponent();
04 //开启显示提示窗体的计时器
05 displayCounter.Start();
06 //初始化工作区的大小
07 System.Drawing.Rectangle rect = System.Windows.Forms.Screen.GetWorkingArea
(this);//实例化一个当前窗体的对象
08 this.Rect = new System.Drawing.Rectangle(rect.Right - this.Width - 1,rect.
Bottom - this.Height - 1,this.Width,this.Height); //创建工作区
09 }
在MainForm窗体中需要定义和声明一些变量。代码如下:
01 public static int SW_SHOWNOACTIVATE = 4;//该变量决定窗体的显示方式
02 public static int CurrentState;//该变量标识当前窗体状态
03 public static bool MainFormFlag=true ;
04 private System.Drawing.Rectangle Rect;//定义一个存储矩形框的区域
05 private FormState InfoStyle = FormState.Hide;//定义变量为隐藏
06 public static bool MouseState; //该变量标识当前鼠标指针状态
07 bool IconFlag = true;//用来标识图标闪烁
08 public static bool IconFlickerFlag;//运用本标识避免单击"关闭"按钮时弹出信息框
09 protected enum FormState
10 {
11 //隐藏窗体
12 Hide = 0,
13 //显示窗体
14 Display = 1,
15 //隐藏窗体中
16 Hiding=3,
17 //显示窗体中
18 Displaying = 4,
19 }
20 protected FormState FormNowState
21 {
22 get { return this.InfoStyle; } //返回窗体的当前状态
23 set { this.InfoStyle = value; } //设定窗体当前状态的值
24 }
如果要使MainForm窗体处于运行状态,那么必须触发NotifyIcon控件的MouseDoubleClick事件。代码如下:
01 private void taskBarIcon_MouseDoubleClick(object sender,MouseEventArgs e)
02 {
03 iconCounter.Enabled = false;//停止闪烁托盘图标计时器
04 taskBarIcon.Icon = Properties.Resources._2;//清空托盘中原有的图片
05 ShowNewWindow();//调用显示窗体方法
06 }
运行MainForm窗体时,需要调用ShowNewWindow方法。代码如下:
01 public void ShowNewWindow()
02 {
03 switch(FormNowState) //判断当前窗体处于哪种状态
04 {
05 case FormState.Hide://当提示窗体的状态为隐藏时
06 this.FormNowState = FormState.Displaying;//设置提示窗体的状态为显示中
07 //显示提示窗体,并把它放在屏幕底端
08 this.SetBounds(Rect.X,Rect.Y + Rect.Height,Rect.Width,0);
09 ShowWindow(this.Handle,4); //显示提示窗体
10 displayCounter.Interval = 100; //设定时间事件的频率为100ms一次
11 displayCounter.Start(); //启动计时器displayCounter
12 break;
13 case FormState.Display: //当提示窗体的状态为显示时
14 displayCounter.Stop(); //停止计时器displayCounter
15 displayCounter.Interval = 5000; //设定时间事件的频率为5000ms一次
16 displayCounter.Start(); //启动计时器displayCounter
17 break;
18 }
19 taskBarIcon.Icon = Properties.Resources._1;//设定托盘图标
20 }
MainForm窗体显示时从桌面的右下角出现,本过程通过displayCounter计时器的Tick事件完成。代码如下:
01 private void displayCounter_Tick(object sender,EventArgs e)
02 {
03 switch(this.FormNowState) //判断当前窗体的状态
04 {
05 case FormState.Display: //当窗体处于显示状态时
06 this.displayCounter.Start(); //启动计时器displayCounter
07 this.displayCounter.Interval = 100; //设定计时器的时间事件间隔
08 if(!MouseState) //当鼠标指针不在窗体上时
09 {
10 this.FormNowState = FormState.Hiding; //隐藏当前窗体
11 }
12 this.displayCounter.Start(); //启动计时器displayCounter
13 break;
14 case FormState.Displaying: //当窗体处于显示中状态时
15 if(this.Height <= this.Rect.Height - 12) //如果窗体没有完全显示
16 {
17 this.SetBounds(Rect.X,this.Top - 12,Rect.Width,this.Height + 12);
//设定窗体的边界
18 }
19 else //当窗体完全显示时
20 {
21 displayCounter.Stop(); //停止计时器displayCounter
22 //设定窗体的边界
23 this.SetBounds(Rect.X,Rect.Y,Rect.Width,Rect.Height);
24 this.FormNowState = FormState.Display; //修改当前窗体所处的状态
25 this.displayCounter.Interval = 5000; //设定计时器的时间事件间隔
26 this.displayCounter.Start(); //启动计时器displayCounter
27 }
28 break;
29 case FormState.Hiding: //当窗体处于隐藏中状态时
30 if(MouseState) //当鼠标指针在窗体上时
31 {
32 this.FormNowState = FormState.Displaying;//修改窗体的状态为显示中
33 }
34 else //当鼠标指针离开窗体时
35 {
36 if(this.Top <= this.Rect.Bottom - 12) //当窗体没有完全隐藏时
37 {
38 this.SetBounds(Rect.X,this.Top + 12,Rect.Width,this.Height - 12);
//设定窗体的边界
39 }
40 else //当窗体完全隐藏时
41 {
42 this.Hide(); //隐藏当前窗体
43 this.FormNowState = FormState.Hide; //设定当前的窗体状态
44 }
45 }
46 break;
47 }
48 }
在MainForm窗体的隐藏与显示的过程中需要判断鼠标指针是否在窗体中。代码如下:
01 private void MainForm_MouseEnter(object sender,EventArgs e)
02 {
03 MouseState = true; //设定bool型变量MouseState的值为真
04 }
05 private void MainForm_MouseLeave(object sender,EventArgs e)
06 {
07 MouseState = false; //设定bool型变量MouseState的值为假
08 }
举一反三
根据本实例,读者可以实现以下功能。
◇ 制作任务栏弹出窗体。
◇ 实现类似腾讯QQ的闪烁图标提示。