zoukankan      html  css  js  c++  java
  • 简单的实现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(); } } }

     

     

  • 相关阅读:
    1111实验二 作业调度模拟实验
    1006实验一实验报告
    0909对操作系统的认识
    南阳OJ-138 找球号(二)(hash表应用)
    南阳OJ-38 布线问题(最小生成树应用_prim)
    插入排序
    南阳OJ-756 重建二叉树(二叉树的中序遍历和后序遍历求先序遍历)
    南阳OJ-63 小猴子下落(数据结构-二叉树)
    UVA OJ-11095 Maximum Product(暴力求解法)
    UVA OJ-725 Division (暴力求解法)
  • 原文地址:https://www.cnblogs.com/Alvin-ftd/p/4079676.html
Copyright © 2011-2022 走看看