C#开发案例精粹
上QQ阅读APP看书,第一时间看更新

bt2-L 实例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的闪烁图标提示。