C#实现QQ/MSN等客户端聊天软件从右下角弹出窗体(Popup Window)
源代码是从2年前写的一个项目中copy过来的,稍做修改并加注释。
1.测试窗体源代码.
学习内容: 1.委托定义 2.Invoke方法应用 3.多线程及多线程访问主线程内的控件 4.定义一个回调方法
public partial class frmTest : Form
{
delegate void AddMessageDelegate(MessageBody msg);
public frmTest()
{
InitializeComponent();
}
//定义一个MessageEventHandler委托
public void HandlingPopupWindowCallBack(object sender, MessageEventArgs e)
{
listBox1.Invoke(new AddMessageDelegate(this.AddMessage), new object[] { e.Message });
}
private void AddMessage(MessageBody msg)
{
listBox1.Items.Add("---------------------------");
listBox1.Items.Add(msg.Title);
listBox1.Items.Add(msg.Body);
}
private void btnTest_Click(object sender, EventArgs e)
{
Thread _MyThread = new Thread(new ThreadStart(PopupMessage));
_MyThread.IsBackground = true;
_MyThread.SetApartmentState(ApartmentState.MTA);
_MyThread.Start(); //啟動線程
}
/// <summary>
/// 自動彈出系統消息
/// </summary>
private void PopupMessage()
{
List<MessageBody> list = new List<MessageBody>();
list.Add(new MessageBody("测试消息1", "测试消息1的内容"));
list.Add(new MessageBody("测试消息2", "测试消息2的内容"));
list.Add(new MessageBody("测试消息3", "测试消息3的内容"));
list.Add(new MessageBody("测试消息4", "测试消息4的内容"));
frmPopupWindow window = new frmPopupWindow(this.HandlingPopupWindowCallBack, list, 1000);
window.ShowDialog();
}
2.弹出窗体源代码
public partial class frmPopupWindow : Form
{
private int _MsgIndex = 0;
private List<MessageBody> _messageList = null;
private MessageEventHandler _CallBackWhenClick;
/// <summary>
/// 重载构造器
/// </summary>
/// <param name="callBack">回调事件</param>
/// <param name="messageList">消息列表</param>
/// <param name="waitTotalTime">每个消息显示时间</param>
public frmPopupWindow(MessageEventHandler callBack, List<MessageBody> messageList,
int waitTotalTime)
{
InitializeComponent();
try
{
this.TopMost = true;
this.tmWait.Interval = waitTotalTime;
this.tmWait.Enabled = true;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - this.Width - 3,
Screen.PrimaryScreen.WorkingArea.Height - this.Height);
WinAPI.AnimateWindow(this.Handle, 500, WinAPI.AW_SLIDE | WinAPI.AW_VER_NEGATIVE);
this._messageList = messageList;
this._CallBackWhenClick = callBack;
this.ShowMessage(0);
}
catch (Exception ex)
{
MessageBody msg = new MessageBody("构造器发生错误", ex.Message);
_CallBackWhenClick(null, new MessageEventArgs(msg));
}
}
private void btnPrior_Click(object sender, EventArgs e)
{
tmWait.Stop();
_MsgIndex -= 1;
if (_MsgIndex >= 0)
ShowMessage(_MsgIndex);
else
_MsgIndex = 0;
}
private void btnNext_Click(object sender, EventArgs e)
{
tmWait.Stop();
_MsgIndex += 1;
if (_MsgIndex <= _messageList.Count - 1)
ShowMessage(_MsgIndex);
else
_MsgIndex = _messageList.Count - 1;
}
private void btnClose_Click(object sender, EventArgs e)
{
MessageBody msg = new MessageBody("关闭弹出窗体", "用户关闭了弹出窗体.");
//测试回调事件
_CallBackWhenClick(sender, new MessageEventArgs(msg));
this.Close();
}
private void tmWait_Tick(object sender, EventArgs e)
{
if (_messageList == null) return;
if (_MsgIndex == _messageList.Count)
{
MessageBody msg = new MessageBody("消息显示完成", "系统自动关闭了弹出窗体.");
//测试回调事件
_CallBackWhenClick(sender, new MessageEventArgs(msg));
this.Close(); // close
}
else
{
ShowMessage(_MsgIndex);
_MsgIndex = _MsgIndex + 1;
}
}
/// <summary>
/// 显示消息
/// </summary>
private void ShowMessage(int index)
{
MessageBody msg = _messageList[index];
label1.Text = msg.Title;
label2.Text = msg.Body;
label1.Update();
label2.Update();
this.Update();
this.Refresh();
}
//by www.csframework.com ,如转载请注明出处
}
3.WinAPI定义
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace PopupWindow
{
public class WinAPI
{
#region WinAPI Function&Const defination
public const int AW_HOR_POSITIVE = 0x00000001;
public const int AW_HOR_NEGATIVE = 0x00000002;
public const int AW_VER_POSITIVE = 0x00000004;
public const int AW_VER_NEGATIVE = 0x00000008;
public const int AW_CENTER = 0x00000010;
public const int AW_HIDE = 0x00010000;
public const int AW_ACTIVATE = 0x00020000;
public const int AW_SLIDE = 0x00040000;
public const int AW_BLEND = 0x00080000;
[DllImport("user32", CharSet = CharSet.Auto)]
public static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
[DllImport("Winmm")]
public static extern bool PlaySound(string pszSound, IntPtr hmod, UInt32 fdwSound);
private const Int32 SND_ASYNC = 1;
private const Int32 SND_LOOP = 8;
private const Int32 SND_FILENAME = 131072;
#endregion
//by www.csframework.com ,如转载请注明出处
}
}
4.公共类Common.cs
using System.Collections.Generic;
using System.Text;
namespace PopupWindow
{
/// <summary>
/// 消息实体类
/// </summary>
public class MessageBody
{
private string _Title;
private string _Body;
public MessageBody(string title, string body)
{
_Title = title;
_Body = body;
}
public string Title { get { return _Title; } set { _Title = value; } }
public string Body { get { return _Body; } set { _Body = value; } }
}
/// <summary>
/// 自定义参数
/// </summary>
public class MessageEventArgs : EventArgs
{
private MessageBody _CurrentMessage;
public MessageEventArgs(MessageBody currentMsg)
: base()
{
_CurrentMessage = currentMsg;
}
/// <summary>
/// 当前处理的消息
/// </summary>
public MessageBody Message
{
get { return _CurrentMessage; }
set { _CurrentMessage = value; }
}
}
/// <summary>
/// 回调事件委托.用户在弹出窗体点击消息标题,触发这个事件.
/// 学习内容: 1.自定义委托, 2.自定义委托方法的参数
/// </summary>
public delegate void MessageEventHandler(object sender, MessageEventArgs e);
//by www.csframework.com ,如转载请注明出处
}
5.程序截图