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(); } } }

     

     

  • 相关阅读:
    Window 窗口类
    使用 Bolt 实现 GridView 表格控件
    lua的table库
    Windows编程总结之 DLL
    lua 打印 table 拷贝table
    使用 xlue 实现简单 listbox 控件
    使用 xlue 实现 tips
    extern “C”
    COleVariant如何转换为int double string cstring
    原来WIN32 API也有GetOpenFileName函数
  • 原文地址:https://www.cnblogs.com/Alvin-ftd/p/4079676.html
Copyright © 2011-2022 走看看