简单的实现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 = 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(); } } }

 

 

原文地址:https://www.cnblogs.com/Alvin-ftd/p/4079676.html