简单的实现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[].PhotoCode, tab[].NickName, tab[].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[].PhotoCode-];
menickname.Text = tab[].NickName;
mememoname.Text = tab[].Memo; //加载右下角ico上的文字
notifyIcon1.Text = "QQ:"+tab[].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[].State; }
//窗体关闭后状态设置为离线
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
adp1.UpdateStateByCode(,_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 = ; 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-;
_Nickname = nickname;
_Memo = memo;
} //加载
private void Friendsmode_Load(object sender, EventArgs e)
{
//加载的时候根据朋友代号查询数据库,如果在线头像显示彩色,如果离线或隐身显示头像灰色
//并将其加载到主界面
UsersTableAdapter adp = new UsersTableAdapter();
qqdata.UsersDataTable tab = adp.GetDataByUsername(_Friendname);
if (tab[].State == || tab[].State == )
{
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 = ;
} //控制头像抖动
int i = ;
private void timer1_Tick(object sender, EventArgs e)
{
//获取PictureBox当前的位置
int x = touxiang.Location.X;
int y = touxiang.Location.Y;
if (i == )
{
touxiang.Location = new Point(x + , y + );
}
else if (i == )
{
touxiang.Location = new Point(x - , y);
}
else if (i == )
{
touxiang.Location = new Point(x + , y - );
}
i++;
if (i >= )
{
i = ;
}
} //记录朋友最后发送时间,用来区别新的未读消息
DateTime tabx ; //控制来新消息的头像抖动和声音提示的时钟
private void timer2_Tick(object sender, EventArgs e)
{
//去数据库查询发送者是该朋友的接受者是自己的,状态未读的消息
ChatTableAdapter adp = new ChatTableAdapter();
qqdata.ChatDataTable tab = adp.GetDataBySenderAndReceiver(_Friendname, _Mename, ); //判断如果查出来了,而且最后一条的发送时间与上次的不一样,且聊天窗口未打开时头像抖动和声音提示。
if (tab.Count > && tab[tab.Count-].Time != tabx && n==)
{
timer1.Enabled = true;
tabx =tab[tab.Count-].Time;
//播放声音
string sound = Application.StartupPath + "/sound/msg.wav"; //Application.StartupPath:程序exe所在的位置
SoundPlayer player = new SoundPlayer(sound);
player.Load(); //把声音加载到内存
//player.PlayLooping();//播放
player.Play();
}
} //定义变量用来控制上线时声音只响一次
int sx = ;
//控制在线头像变化和声音
private void controltx_Tick(object sender, EventArgs e)
{
UsersTableAdapter adp = new UsersTableAdapter();
qqdata.UsersDataTable tab = adp.GetDataByUsername(_Friendname);
if (tab[].State == || tab[].State == )
{
touxiang.Image = imageList1.Images[_Photo];
sx = ;
}
else
{
if (sx == )
{
touxiang.Image = imageList2.Images[_Photo];
sx = ;
string sound = Application.StartupPath + "/sound/Global.wav"; //Application.StartupPath:程序exe所在的位置
SoundPlayer player = new SoundPlayer(sound);
player.Load(); //把声音加载到内存
//player.PlayLooping();//播放
player.Play();
}
}
}
简单的实现QQ通信功能(四)的更多相关文章
- 简单的实现QQ通信功能(二)
第二部分:功能需求以及大体思路 一:功能需求: 1. 角色:登录用户. 2. 登录: (1)检查用户名和密码是否正确,正确登录成功,否则提醒用户名或密码错误. (2)登录时可以选择登录状态,送入数据库 ...
- 简单的实现QQ通信功能(三)
第三部分:登陆界面的设计及代码 一:效果图及界面设计 1. 效果图: 2. 界面设计: (1)仿照QQ的登陆界面,右上角放了三个Label,用来做关闭.最小化和设置,使用了它们的Click事件当做按钮 ...
- 简单的实现QQ通信功能(五)
第五部分:聊天界面的设计及代码 一:效果图及界面设计 1. 效果图: 2. 界面设计: (1)左上角显示朋友的头像和“某某正在和某某聊天”. (2)中间的聊天窗口用了一个ListView,视图用详细信 ...
- 简单的实现QQ通信功能(一)
第一部分:数据库的设计,数据集的建立 一:数据库的设计: 1.用户表:包含用户名.密码.昵称.性别.备注.状态.头像代号和最后登录时间. 2.朋友关系表:自增长列为主键列,用户名和好友名,还有朋友的状 ...
- Android BLE与终端通信(四)——实现服务器与客户端即时通讯功能
Android BLE与终端通信(四)--实现服务器与客户端即时通讯功能 前面几篇一直在讲一些基础,其实说实话,蓝牙主要为多的还是一些概念性的东西,当你把概念都熟悉了之后,你会很简单的就可以实现一些逻 ...
- 经测试稳定可用的蓝牙链接通信Demo,记录过程中遇到的问题的思考和解决办法,并整理后给出一个Utils类可以简单调用来实现蓝牙功能
说明:这是本人在蓝牙开发过程中遇到过的问题记录和分析,以及解决办法. 在研究过程中,许多的前人给出的解决方案和思路指导对我相当有帮助,但并非都是可采取的解决方法, 经过本人对这些方法的测试和使用过后, ...
- android-使用环信SDK开发即时通信功能及源代码下载
近期项目中集成即时聊天功能.挑来拣去,终于选择环信SDK来进行开发,选择环信的主要原因是接口方便.简洁.说明文档清楚易懂.文档有android.ios.和后台server端.还是非常全的. 环信官网: ...
- jsp+servlet+mysql 实现简单的银行登录转账功能
jsp+servlet+mysql 实现简单的银行登录转账功能 [前期的准备] html(登录界面),servlet(处理业务逻辑),jsp(主要实现界面),mysql(实现与数据库的简单的交互)先从 ...
- 网站集成QQ登录功能
最近在做一个项目时,客户要求网站能够集成QQ登录的功能,以前没做过这方面的开发,于是去QQ的开放平台官网研究了一下相关资料,经过自己的艰苦探索,终于实现了集成QQ登录的功能,现在把相关的开发经验总结一 ...
随机推荐
- java数据类型图:
java数据类型图: ┏数值型━┳━整数型:byte short int long ┏基本数据类型━━┫ ...
- java里的静态变量是放在了堆内存还是栈内存?
堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对 ...
- C# DataGridView添加新行的2个方法
可以静态绑定数据源,这样就自动为DataGridView控件添加 相应的行.假如需要动态为DataGridView控件添加新行,方法有很多种,下面简单介绍如何为DataGridView控件动态添加新行 ...
- Linux Kernel ‘oz_cdev_write()’函数本地缓冲区溢出漏洞
漏洞名称: Linux Kernel ‘oz_cdev_write()’函数本地缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-060 发布时间: 2013-11-07 更新时间: 201 ...
- ubunt下的MinimalCD
ubuntu有MinimalCD,水平高的衍生版制作者基于MinimalCD安装并编译,定制出独特风格的ubuntu衍生版,如 crunchbang.水平不高的个人用户可以从Alternate(文字安 ...
- 【 D3.js 进阶系列 — 6.2 】 饼状图的拖拽
本文讲解稍微复杂一些的拖拽应用,即拖拽饼图的各部分. 在[入门 - 第 9.1 章]讲解了如何制作饼状图.饼状图的各部分是用具有宽度的弧线来表示的.在与用户进行交互的时候,如果每一部分都能拖拽,是很有 ...
- WMS
Web地图位置服务 Web地图服务(Web map service)利用具有地理空间位置信息的数据制作地图.其中将地图定义为地理数据可视的表现.这个规范定义了三个操作:GetCapabitities返 ...
- PHP 201307 月最新手册chm 免费下载
本次更新两个版本 php_manual_zh_notreview.chm (15MB 不带评论) php_manual_zh_review.chm (32MB 带评论) 制作方 ...
- P.V操作【转】
阐述P,V原语的理论不得不提到的一个人便是赫赫有名的荷兰科学家 E.W.Dijkstra.如果你对这位科学家没有什么印象的话,提起解决图论中最短路径问题的Dijkstra算法应当是我们再熟悉不过的了. ...
- [CODEVS1037]取数游戏
N(2 <=N<=200,且为偶数)个正整数的序列放在一个游戏平台上,A.B两人轮流从序列的两端取数,取数后该数字被去掉并累加到本玩家的得分中,当数取尽时,游戏结束.以最终得分多者为胜(A ...