首页 > 代码库 > 简单的实现QQ通信功能(四)

简单的实现QQ通信功能(四)

第四部分:主界面的设计及代码

一:效果图及界面设计

1. 效果图:

2. 界面设计:

(1)上面显示自己信息用一个PictureBox和两个Label,用来显示自己的头像和昵称备注名。

(2)下面用了一个FlowLayoutPanel来显示好友列表,FlowDirection设置为TopDown,从上到下流式布局。

(3)下面一个ComboBox用来选择自己的状态。

(4)一个imageList3存放用户头像,根据登录者的头像代号进来选择需要的头像。

(5)一个notifyIcon1来设置任务栏右下角显示小图标。

(6)朋友列表中每一个朋友信息的显示是用了一个自定义控件Friendsmode,专门来加载朋友信息。

(7)Friendsmode里面一个imageList2存放用户头像,imageList2存放用户离线头像,时钟Timer1控制头像抖动,时钟Timer2控制来消息声音,时钟controltx来控制朋友上线和下线的声音及头像变化。

3. 用到的各个控件的名称:

登录者头像metouxiang,登录者昵称menickname,登录者备注名mememoname,用户列表friendlist,右下角修改状态updatastate;

自定义控件Friendsmode,自定义控件里的头像touxiang,自定义控件里的昵称nicheng,自定义控件里的备注名beizhu。

 

二:代码设计:

1. MainForm里的代码:

        //定义个_Uid记住登录者        private string _Uid;        //创建adp1是查user表的适配器,下面经常要用,写在了外面。        UsersTableAdapter adp1 = new UsersTableAdapter();        //构造函数        public MainForm()        {            InitializeComponent();        }        //构造函数重载,将登录者记录        public MainForm(string uid)        {            _Uid = uid;            InitializeComponent();        }        //加载        private void MainForm_Load(object sender, EventArgs e)        {            //根据登录者代号去数据库查找朋友            FriendsTableAdapter adp = new FriendsTableAdapter();            qqdata.FriendsDataTable table = new qqdata.FriendsDataTable();            table = adp.GetDataBy(_Uid);            //逐个朋友查找出来并显示            foreach (qqdata.FriendsRow row in table.Rows)            {                qqdata.UsersDataTable tab = new qqdata.UsersDataTable();                tab = adp1.GetDataByUsername(row.FriendName);                //造自定义控件,用到了自定义控件的构造函数传参数                Friendsmode friend = new Friendsmode(tab[0].PhotoCode, tab[0].NickName, tab[0].Memo, row.FriendName,_Uid);                //将控件添加进主界面                friendlist.Controls.Add(friend);            }            //调用显示自己信息的方法            loadmeinfo();            //调用加载状态列表的方法            loadState();           }        //显示自己的方法        private void loadmeinfo()        {            qqdata.UsersDataTable tab = new qqdata.UsersDataTable();            tab = adp1.GetDataByUsername(_Uid);            metouxiang.Image = imageList3.Images[tab[0].PhotoCode-1];            menickname.Text = tab[0].NickName;            mememoname.Text = tab[0].Memo;            //加载右下角ico上的文字            notifyIcon1.Text = "QQ:"+tab[0].NickName;        }        //加载状态列表的方法        private void loadState()        {            qqdata.UsersDataTable tab = new qqdata.UsersDataTable();            tab = adp1.GetDataByUsername(_Uid);            StateTableAdapter adp2 = new StateTableAdapter();            qqdata.StateDataTable tabs = new qqdata.StateDataTable();            tabs = adp2.GetData();            //绑定显示            updatastate.DataSource = tabs;            updatastate.DisplayMember = "StateName";            updatastate.ValueMember = "State";            //默认状态设置为数据库内的状态            updatastate.SelectedValue = http://www.mamicode.com/tab[0].State;        }        //窗体关闭后状态设置为离线        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)        {            adp1.UpdateStateByCode(0,_Uid);        }        //当用户更改状态时将更改的状态传到数据库        private void updatastate_SelectionChangeCommitted(object sender, EventArgs e)        {            adp1.UpdateStateByCode((Int32)updatastate.SelectedValue, _Uid);        }        //双击任务栏右下角小图标显示主窗体        private void notifyIcon1_DoubleClick(object sender, EventArgs e)        {            this.Visible = true;            this.WindowState = FormWindowState.Normal;        }        //最小化的时候隐藏窗体        const int WM_SYSCOMMAND = 0x112;        const int SC_CLOSE = 0xF060;        const int SC_MINIMIZE = 0xF020;        const int SC_MAXIMIZE = 0xF030;        protected override void WndProc(ref Message m)        {            if (m.Msg == WM_SYSCOMMAND)            {                if (m.WParam.ToInt32() == SC_MINIMIZE)                {                    this.Visible = false;                    return;                }            }            base.WndProc(ref m);        }

2. 自定义控件下的代码:

       //定义一个变量、属性来控制头像抖动和声音        private static int n = 0;        public static int N        {            get { return Friendsmode.n; }            set { Friendsmode.n = value; }        }        //定义变量、属性来接收MainForm传过来的自己的名字代号        private string _Mename;        public string Mename        {            get { return _Mename; }            set { _Mename = value; }        }        //定义变量、属性来接收MainForm传过来的朋友的名字代号        private string _Friendname;        public string Friendname        {            get { return _Friendname; }            set { _Friendname = value; }        }               private string _Nickname;        private string _Memo;        private int _Photo;        //默认构造        public Friendsmode()        {            InitializeComponent();        }        //构造函数重载,将头像代号,昵称,备注,朋友代号和自己的代号传过来接收        public Friendsmode(int photo,string nickname,string memo,string friendname,string mename):this()        {            _Mename = mename;            _Friendname = friendname;            _Photo = photo-1;            _Nickname = nickname;            _Memo = memo;        }        //加载        private void Friendsmode_Load(object sender, EventArgs e)        {            //加载的时候根据朋友代号查询数据库,如果在线头像显示彩色,如果离线或隐身显示头像灰色            //并将其加载到主界面            UsersTableAdapter adp = new UsersTableAdapter();            qqdata.UsersDataTable tab = adp.GetDataByUsername(_Friendname);            if (tab[0].State == 0 || tab[0].State == 9)            {                touxiang.Image = imageList1.Images[_Photo];            }            else            {                touxiang.Image = imageList2.Images[_Photo];            }            nicheng.Text = _Nickname;            beizhu.Text = _Memo;        }        //双击头像进入聊天窗口        private void touxiang_DoubleClick(object sender, EventArgs e)        {            Chat ch = new Chat(_Friendname, _Mename);            ch.Show();            //此朋友的头像抖动在打开此聊天窗口时不可用            timer1.Enabled = false;            //设置n为1,用来标识此朋友聊天窗口已打开            n = 1;        }        //控制头像抖动        int i = 0;        private void timer1_Tick(object sender, EventArgs e)        {            //获取PictureBox当前的位置            int x = touxiang.Location.X;            int y = touxiang.Location.Y;            if (i == 0)            {                touxiang.Location = new Point(x + 3, y + 3);            }            else if (i == 1)            {                touxiang.Location = new Point(x - 6, y);            }            else if (i == 2)            {                touxiang.Location = new Point(x + 3, y - 3);            }            i++;            if (i >= 3)            {                i = 0;            }        }        //记录朋友最后发送时间,用来区别新的未读消息        DateTime tabx ;        //控制来新消息的头像抖动和声音提示的时钟        private void timer2_Tick(object sender, EventArgs e)        {            //去数据库查询发送者是该朋友的接受者是自己的,状态未读的消息            ChatTableAdapter adp = new ChatTableAdapter();            qqdata.ChatDataTable tab = adp.GetDataBySenderAndReceiver(_Friendname, _Mename, 0);            //判断如果查出来了,而且最后一条的发送时间与上次的不一样,且聊天窗口未打开时头像抖动和声音提示。            if (tab.Count > 0 && tab[tab.Count-1].Time != tabx && n==0)            {                timer1.Enabled = true;                tabx =tab[tab.Count-1].Time;                
//播放声音
string sound = Application.StartupPath + "/sound/msg.wav"; //Application.StartupPath:程序exe所在的位置 SoundPlayer player = new SoundPlayer(sound); player.Load(); //把声音加载到内存 //player.PlayLooping();//播放 player.Play(); } } //定义变量用来控制上线时声音只响一次 int sx = 0; //控制在线头像变化和声音 private void controltx_Tick(object sender, EventArgs e) { UsersTableAdapter adp = new UsersTableAdapter(); qqdata.UsersDataTable tab = adp.GetDataByUsername(_Friendname); if (tab[0].State == 0 || tab[0].State == 9) { touxiang.Image = imageList1.Images[_Photo]; sx = 0; } else { if (sx == 0) { touxiang.Image = imageList2.Images[_Photo]; sx = 1; string sound = Application.StartupPath + "/sound/Global.wav"; //Application.StartupPath:程序exe所在的位置 SoundPlayer player = new SoundPlayer(sound); player.Load(); //把声音加载到内存 //player.PlayLooping();//播放 player.Play(); } } }

 

 

 

简单的实现QQ通信功能(四)