文章导航PC6首页软件下载单机游戏安卓资源苹果资源

pc软件新闻网络操作系统办公工具编程服务器软件评测

安卓新闻资讯应用教程刷机教程安卓游戏攻略tv资讯深度阅读综合安卓评测

苹果ios资讯苹果手机越狱备份教程美化教程ios软件教程mac教程

单机游戏角色扮演即时战略动作射击棋牌游戏体育竞技模拟经营其它游戏游戏工具

网游cf活动dnf活动lol周免英雄lol礼包

手游最新动态手游评测手游活动新游预告手游问答

您的位置:首页精文荟萃软件资讯 → 用Flash和XML来构造一个聊天室

用Flash和XML来构造一个聊天室

时间:2004/10/7 18:29:00来源:本站整理作者:蓝点我要评论(0)


            
             
              
             
            

               
               

            



            点击这里下载源文件

  前面的教程我们介绍了Flash与XML结合使用的原理以及一个论坛的实现,下面我们继续结合Flash与XML来实现一个简单的聊天室,有在线聊天、在线人员名单、在线时间、简单的管理操作等功能。根据需要在此基础上稍作修改,就可以实现一个功能比较完备的聊天室了。


一、原理


  用Flash和XML来构造聊天室,跟直接用Flash和Asp来构造聊天室的基本原理是一样的。都是先在Flash端发送一个XML请求到服务器端,然后等待从服务器端的XML返回值,当值返回Flash端后,解释所返回的XML串,根据相应的值做相应的操作。


在Flash部分,用到的主要都是XML串的构造和sendAndLoad()函数的操作。在Asp部分,主要用到了global.asa文件和application()属性,先定义几个application对象,然后将要保持的内容放在application对象中,要用的时候,直接从application对象中取就是了。


下面就按顺序一个一个来实现聊天室的功能,每一个介绍的内容都分为“传递的XML”、“Flash部分”、“Asp部分”三部分。


二、登陆


  登陆就是将用户名和密码用XML格式发送到服务器端,服务器端将验证的结果用XML格式返回。


  A、传递的XML


  1、请求报文







用户名密码

  2、响应报文







用户名

  B、Flash部分


  1、在Flash MX 2004中新建一个Flash文件,设置场景的第一帧的帧标签为“login”,并在ActionScript面板上增加语句:







stop();

  2、在第一帧的场景中用文本工具拉两个文本框,类型都为“Input type”,变量名var分别设置为“username”、“userpwd”,这是用来输入用户名跟密码的。


  3、新建一个Button并拖到第一帧的场景中,摆放位置如图1所示。并在这个Button的ActionScript面板中增加如下语句:







on (release) {
if (length(_root.username) == 0) { //注释1
_root.username = "guest";
} else if (length(_root.userpwd) == 0) { //注释2
_root.username = "guest";
}
loginXml = new XML(); //注释3
loginElement = loginXml.createElement("LOGIN"); //注释4
// name node
nameElement = loginXml.createElement("USERNAME"); //注释5
nameNode = loginXml.createTextNode("name"); //注释6
nameNode.nodeValue = _root.username;
nameElement.appendChild(nameNode); //注释7
// pwd node
pwdElement = loginXml.createElement("PWD"); //注释8
pwdNode = loginXml.createTextNode("pwd");
pwdNode.nodeValue = _root.userpwd;
pwdElement.appendChild(pwdNode); //注释9
loginElement.appendChild(nameElement); //注释10
loginElement.appendChild(pwdElement);
loginXml.appendChild(loginElement); //注释11
xmlRepley = new XML(); //注释12
xmlRepley.onLoad = onLoginReply; //注释13
function onLoginReply(success) {
if (success) {
if (xmlRepley.firstChild.firstChild.attributes.right == "1") { //注释14
_root.gotoAndPlay("main");
} else {
_root.username = "登陆失败";
}
}
}
loginXml.sendAndLoad("http://localhost/xmlchat/login.asp", xmlRepley); //注释15
}


  注释1:检查输入框中用户名的长度,如为空,则默认为guest。
  注释2:检查输入框中密码的长度。
  注释3:新建一个XML对象,这是用来发送到服务器端的。
  注释4:创建一个LOGIN结点对象。
  注释5:创建一个USERNAME结点对象,注意不能直接在Element对象中放置文本内容,要在Text Node对象中才能放置文本内容。具体可以参见Flash帮助文件中有关XML.createElement()和XML.createTextNode() 中的内容。
  注释6:创建一个Text Node对象,用来放置USERNAME结点的文本内容。
  注释7:将创建的Text Node结点插入到USERNAME结点对象中。
  注释8:分别创建一个PWD结点对象和Text Node。
  注释9:将Text Node结点插入到PWD结点对象中。
  注释10:将USERNAME结点对象插入到LOGIN结点对象中,将PWD结点对象插入到LOGIN结点对象中。
  注释11:将LOGIN结点对象插入到所创建的XML对象中,从而构造一个完整的XML对象。注意这里在构建XML对象时,是从最里面开始构建的。
  注释12:新建一个XML对象,这里是用来放置接收到的XML对象的。
  注释13:设置接收XML对象的响应函数,当服务器端返回XML对象的时候触发。
  注释14:判断返回的XML对象中的结点属性是否符合要求。
  注释15:利用sendAndLoad()函数,将Flash端的XML对象发送到服务器端,并接收从服务器端返回的XML对象。


  C、Asp部分


  1、新建一个文件,命名为global.asa,输入如下内容:








2、新建一个Asp文件,命名为login.asp,输入如下的内容:






<%
Set MyFileObject = Server.CreateObject("Scripting.FileSystemObject") ‘注释1
Set MyTextFile = MyFileObject.CreateTextFile("G:\写作\flashxmlchat\source\login.xml", 8, TRUE) ‘注释2
MyTextFile.WriteLine(Request.Form) ‘注释3


set objDom = server.CreateObject("microsoft.xmldom") ‘注释4
objDom.loadxml(Request.Form) ‘注释5
set objname = objdom.documentElement.SelectSingleNode("//LOGIN/USERNAME") ‘注释6
username = objname.text ‘注释7


set objpwd = objdom.documentElement.SelectSingleNode("//LOGIN/PWD") ‘注释8
pwd = objpwd.text


righ = "-1"
'判断
set conn=Server.CreateObject("ADODB.Connection") ‘注释9
conn.open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("/xmlchat/xmlchat.mdb") ‘注释10
set rs=Server.CreateObject("ADODB.Recordset") ‘注释11
strSql="select * from UserInfo where UserName = '" & username & "' and Pwd = '" & pwd & "'" ‘注释12
rs.open strSql,conn, 1, 1
if not(rs.bof and rs.eof) then ‘注释13
application("VisitorNum") = application("VisitorNum") + 1
application("VisitorName") = application("VisitorName") & username & "," & rs("ID") & ";" ‘注释14
righ = rs("Right")
tempstr= username & " login......"
application("AllCanSee") = application("AllCanSee") & tempstr ‘注释15
Else
righ = "0"
end if
rs.close ‘注释16
conn.close


'返回
response.write("" & username & "") ‘注释17
%>


  注释1:利用FileSystemObject组件建立一个文件对象,将通讯过程中传送的东西写在文件里面,方便调试。
  注释2:注意根据实际需要修改文件的路径。
  注释3:把Request.Form是传送进来的所有内容都写在文件里面,在服务器端留下调试痕迹。可以用日志模式进一步完善此功能。
  注释4:创建一个XML对象。可以在MS XML包中找到更多有关XML操作的信息。
  注释5:通过loadxml()函数,导入Flash端传送进来的XML格式字符串。
  注释6:建立USERNAME结点的对象。
  注释7:取得USERNAME结点的内容。
  注释8:建立PWD结点的对象,取得PWD结点的内容。
  注释9:建立一个数据库Connection集合。
  注释10:建立一个数据库的ADO连接,这里用到的是Access 2000数据库,数据库的格式见后面的附录,请注意数据库的存放位置。
  注释11:建立一个数据库Recordset集合。
  注释12:根据取得的用户名和密码,构造一个SQL字符串。
  注释13:判断查询结果是否为空。
  注释14:将用户名和ID号添加到application("VisitorName")对象中。
  注释15:将登陆信息添加到application("AllCanSee")对象中。
  注释16:关闭数据库连接,释放资源。
  注释17:直接构造一个XML字符串,并通过write函数写到Flash端。


三、发送


  发送部分的基本原理是从Flash端发送XML格式的聊天内容到服务器端,在服务器端将聊天内容添加到application("AllCanSee")对象中,并将修改后的application("AllCanSee")对象的内容用XML格式返回到Flash端。


  A、传递的XML


  1、请求报文







用户名发送内容
2、响应报文





用户名

  B、Flash部分


  1、在主场景的第5帧中添加关键帧,将此帧命名为“main”,在帧的Action面板中增加下面的语句:







now = new Date(); //注释1
starttime = now.getTime();
stop();

  注释1:这是为了在下面计算在线时间用的。


  2、在主场景中拉一个文本框,属性设置如图2所示。



  3、在主场景main帧中增加一个Button,显示的内容为“发送”。在Button的Action面板上面增加如下语句:







on (release) {
if (length(_root.txtsend) == 0) { //注释1
_root.txtsend = "内容为空";
}
sendXml = new XML(); //注释2
sendElement = sendXml.createElement("SEND"); //注释3
// name node
nameElement = sendXml.createElement("USERNAME"); //注释4
nameNode = sendXml.createTextNode("name"); //注释5
nameNode.nodeValue = _root.username;
nameElement.appendChild(nameNode); //注释6
// content node
cntElement = sendXml.createElement("CONTENT"); //注释7
cntNode = sendXml.createTextNode("cnt"); //注释8
cntNode.nodeValue = _root.txtsend;
cntElement.appendChild(cntNode); //注释9
sendElement.appendChild(nameElement); //注释10
sendElement.appendChild(cntElement);
sendXml.appendChild(sendElement); //注释11

xmlSendRepley = new XML(); //注释12
xmlSendRepley.onLoad = onSendReply; //注释13
function onSendReply (success) {
if (success) {
if (xmlSendRepley.firstChild.firstChild.attributes.sflag == "true") { //注释14
_root.txtcontent = xmlSendRepley.firstChild.firstChild.attributes.scontent; //注释15
}else {
_root.txtcontent = "连接超时……";
}
}
}
sendXml.sendAndLoad("http://localhost/xmlchat/send.asp", xmlSendRepley); //注释16
}

  注释1:判断发送的内容是否为空。
  注释2:创建一个用于发送的XML对象。
  注释3:创建一个SEND结点对象。
  注释4:创建一个USERNAME结点对象。
  注释5:创建一个TEXT NODE对象,用于存放用户名。
  注释6:将创建的TEXT NODE对象添加到USERNAME结点对象中。
  注释7:创建一个CONTENT结点对象。
  注释8:创建一个TEXT NODE对象,用于存放要发送的内容。
  注释9:将创建的TEXT NODE对象添加到CONTENT结点对象中。
  注释10:将创建的USERNAME和CONTENT对象添加到SEND结点对象中。
  注释11:将创建的SEND结点对象添加到SEND对象中。
  注释12:创建一个用于接收的XML对象。
  注释13:设置接收XML对象的响应函数。
  注释14:判断从服务器返回的值,根据判断结果做相应的操作。
  注释15:将聊天室的内容显示出来。
  注释16:利用sendAndLoad()函数,将Flash端的XML对象发送到服务器端,并接收从服务器端返回的XML对象


C、Asp部分


  新建一个空白文件,命名为send.asp,其内容如下:









<%
Set MyFileObject = Server.CreateObject("Scripting.FileSystemObject") ‘注释1
Set MyTextFile = MyFileObject.CreateTextFile("G:\写作\flashxmlchat\source\login.xml", 8, TRUE)
MyTextFile.WriteLine(Request.Form) ‘注释2


set objDom = server.CreateObject("microsoft.xmldom") ‘注释3
objDom.loadxml(Request.Form) ‘注释4
set objname = objdom.documentElement.SelectSingleNode("//SEND/USERNAME") ‘注释5
username = objname.text


set objcnt = objdom.documentElement.SelectSingleNode("//SEND/CONTENT") ‘注释6
content = objcnt.text


tempstr= username & " say: " & content & "..."
application("AllCanSee") = application("AllCanSee") & tempstr ‘注释7


'返回
response.write("aa") ‘注释8
%>


  注释1:利用FileSystemObject组件建立一个文件对象,将通讯过程中传送的东西写在文件里面,方便调试。
  注释2:把Request.Form是传送进来的所有内容都写在文件里面,在服务器端留下调试痕迹。
  注释3:创建一个XML对象。
  注释4:通过loadxml()函数,导入Flash端传送进来的XML格式字符串。
  注释5:建立USERNAME结点的对象,取得相应内容。
  注释6:建立CONTENT结点的对象,取得相应内容。
  注释7:将从Flash端发送过来的内容添加到application("AllCanSee")对象中。
  注释8:直接构造一个XML字符串,并通过write函数写到Flash端。


四、显示聊天内容和在线人员名单


 显示聊天内容的基本原理是从Flash端发送要显示聊天内容的XML请求,在服务器端将application("AllCanSee")的内容按XML格式发送到Flash端,在Flash端解释和显示出来。


  显示在线人数名单的基本原理是在Flash端发送显示在线人数名单的XML请求,服务器端将application("VisitorName")对象的内容按XML格式发送到Flash端,在Flash端解释和显示出来。


  A、传递的XML


  1、请求报文








用户名


  2、响应报文








用户名



  B、Flash部分


  1、在主场景中拉一个文本框,属性设置如图3所示。



  2、从组件库里面选择List组件,在场景中拉一个List,命名为“talkerlist”。此时场景中的布局应该如图4所示。



3、在主场景main帧中增加一个Button,显示的内容为“刷新”。在Button的Action面板上面增加如下语句:






on (release) {
refreshXml = new XML(); //注释1
refreshElement = refreshXml.createElement("REFRESH"); //注释2
// name node
nameElement = refreshXml.createElement("USERNAME"); //注释3
nameNode = refreshXml.createTextNode("name"); //注释4
nameNode.nodeValue = _root.username;
nameElement.appendChild(nameNode); //注释5
refreshElement.appendChild(nameElement); //注释6
refreshXml.appendChild(refreshElement);
xmlRefreshRepley = new XML(); //注释7
xmlRefreshRepley.onLoad = onRefreshReply; //注释8
function onRefreshReply(success) {
if (success) {
if (xmlRefreshRepley.firstChild.firstChild.attributes.cflag == "true") { //注释9
_root.txtcontent = xmlRefreshRepley.firstChild.firstChild.attributes.ccontent; //注释10
strTalker = xmlRefreshRepley.firstChild.firstChild.attributes.talker;
_root.talkerlist.removeAll(); //注释11
if (strTalker.length>0) { //注释12
talkerarray = new Array(); //注释13
temparray = new Array();
talkerarray = strTalker.split(";"); //注释14
for (i=0; itemparray = talkerarray[i].split(","); //注释16
_root.talkerlist.addItem(temparray[0], temparray[1]); //注释17
}
}
} else {
_root.txtcontent = "连接超时……";
}
}
}
refreshXml.sendAndLoad("http://localhost/xmlchat/refresh.asp", xmlRefreshRepley); //注释18
}


  注释1:创建一个用于发送的XML对象。
  注释2:创建一个REFRESH结点对象。
  注释3:创建一个USERNAME结点对象。
  注释4:创建一个TEXT NODE对象,用于存放用户名。
  注释5:将创建的TEXT NODE对象添加到USERNAME结点对象中。
  注释6:将创建的USERNAME对象添加到REFRESH结点对象中。
  注释7:创建一个用于接收的XML对象。
  注释8:设置接收XML对象的响应函数。
  注释9:判断从服务器返回的值,根据判断结果做相应的操作。
  注释10:将聊天室的内容显示出来。
  注释11:将场景中的下拉列表中的内容清空。
  注释12:判断从服务器端返回的在线名单是否为空。
  注释13:创建两个数组,用来操作在线用户名单。
  注释14:调用String的split函数,将分割后的String保存到数组中。
  注释15:循环读取数组里面的String,继续分割。
  注释16:调用String的split函数,将分割后的String保存到数组中。
  注释17:将分割后取得的用户名和ID号,都添加到场景中的下拉列表中。
  注释18:利用sendAndLoad()函数,将Flash端的XML对象发送到服务器端,并接收从服务器端返回的XML对象。


  C、Asp部分


  新建一个文件,命名为refresh.asp,添加如下内容:









<%
Set MyFileObject = Server.CreateObject("Scripting.FileSystemObject") ‘注释1
Set MyTextFile = MyFileObject.CreateTextFile("G:\写作\flashxmlchat\source\login.xml", 8, TRUE) ‘注释2
MyTextFile.WriteLine(Request.Form) ‘注释3


set objDom = server.CreateObject("microsoft.xmldom") ‘注释4
objDom.loadxml(Request.Form) ‘注释5
set objname = objdom.documentElement.SelectSingleNode("//REFRESH/USERNAME") ‘注释6
username = objname.text


'返回
response.write("aa") ‘注释7
%>


  注释1:利用FileSystemObject组件建立一个文件对象,将通讯过程中传送的东西写在文件里面,方便调试。
  注释2:创建一个文件。
  注释3:把Request.Form是传送进来的所有内容都写在文件里面,在服务器端留下调试痕迹。
  注释4:创建一个XML对象。
  注释5:通过loadxml()函数,导入Flash端传送进来的XML格式字符串。
  注释6:建立USERNAME结点的对象,取得相应内容。
  注释7:根据聊天室内容和在线人员名单构造一个XML字符串,并通过write函数写到Flash端


五、显示在线时间


  Flash中的时间功能已经足够强大,单凭Flash端就可以计算在线时间。不断地用当前时间去减记录下来的开始时间,并显示出来,就是在线时间了。


  A、Flash部分


  1、在主场景中拉一个文本框,属性设置如图5所示。



  2、按“Ctrl + F8”新建一个空白的Movie Clip,将此Clip拖到场景中,并在此Clip的Action面板上面增加如下语句(注意是在场景中的Clip上面,不是在Clip里面):








onClipEvent (load) {
timedate = new Date();
}
onClipEvent (enterFrame) { //注释1
mytime = timedate.getTime(); //注释2
_root.txttime = "您共在线 " + Math.round((Math.ceil((mytime - _root.starttime)/1000)/60)) + " 分钟"; //注释3
delete timedate; //注释4
timedate = new Date(); //注释5
}


  注释1:当Clip的帧从头播放的时候触发。
  注释2:取得当前时间。
  注释3:将统计所得的秒转换成分钟,并显示出来。
  注释4:删除当前的时间对象。
  注释5:重新构造一个时间对象,这样就可以不断的取得最新的时间。


六、管理员权限


  聊天室中,管理功能是必不可少的,这里以简单的“踢人”功能为例来说明一下。


  A、传递的XML


  1、请求报文








要踢的用户名和ID串


  2、响应报文








用户名


  B、Flash部分


  1、在场景中新建一个Button,显示的内容为“踢人”,在Button的Action面板上面增加如下语句:









on (release) {
kickXml = new XML(); //注释1
sendElement = kickXml.createElement("KICK"); //注释2
// id node
nameElement = kickXml.createElement("ID"); //注释3
nameNode = kickXml.createTextNode("id"); //注释4


nameNode.nodeValue = _root.talkerlist.selectedItem.label + "," +_root.talkerlist.selectedItem.data + ";"; //注释5
nameElement.appendChild(nameNode); //注释6
sendElement.appendChild(nameElement);
kickXml.appendChild(sendElement); //注释7

xmlKickRepley = new XML(); //注释8
xmlKickRepley.onLoad = onKickReply; //注释9
function onKickReply (success) {
if (success) {
if (xmlKickRepley.firstChild.firstChild.attributes.kflag == "true") { //注释10
strTalker = xmlKickRepley.firstChild.firstChild.attributes.talker; //注释11
_root.talkerlist.removeAll(); //注释12
if (strTalker.length>0) { //注释13
talkerarray = new Array();
temparray = new Array();
talkerarray = strTalker.split(";");
for (i=0; itemparray = talkerarray[i].split(",");
_root.talkerlist.addItem(temparray[0], temparray[1]); //注释14
}
}
}else {
_root.txtcontent = "连接超时……";
}
}
}
kickXml.sendAndLoad("http://localhost/xmlchat/kick.asp", xmlKickRepley); //注释15

注释1:创建一个用于发送的XML对象。
  注释2:创建一个KICK结点对象。
  注释3:创建一个ID结点对象。
  注释4:创建一个TEXT NODE对象,用于存放ID。
  注释5:将场景中的下拉列表中的值赋给TEXT NODE对象。
  注释6:将创建的TEXT NODE对象添加到USERNAME结点对象中。
  注释7:将创建的KICK对象添加到KICK结点对象中。
  注释8:创建一个用于接收的XML对象。
  注释9:设置接收XML对象的响应函数。
  注释10:判断从服务器返回的值,根据判断结果做相应的操作。
  注释11:取得从服务器端返回的用户列表。
  注释12:清空场景中的下拉列表。
  注释13:判断从服务器端返回的用户列表是否为空。
  注释14:将从服务器端返回的用户列表分割,并添加到场景中的下拉列表中。
  注释15:利用sendAndLoad()函数,将Flash端的XML对象发送到服务器端,并接收从服务器端返回的XML对象。

  C、Asp部分


  新建一个文件,命名为kick.asp,在文件中添加如下内容:








<%
Set MyFileObject = Server.CreateObject("Scripting.FileSystemObject") ‘注释1
Set MyTextFile = MyFileObject.CreateTextFile("G:\写作\flashxmlchat\source\login.xml", 8, TRUE) ‘注释2
MyTextFile.WriteLine(Request.Form) ‘注释3


set objDom = server.CreateObject("microsoft.xmldom") ‘注释4
objDom.loadxml(Request.Form) ‘注释5
set objname = objdom.documentElement.SelectSingleNode("//KICK/ID") ‘注释6
oldid = objname.text
'处理踢人动作
dim i,j,num ‘注释7
i = 1
j = 1
num = 0
do while j<>0
j = instr(i,application("VisitorName"), ";", 1)
if j<>0 then
num = num + 1
str = mid(application("VisitorName"), i, j-i)
temppos = instr(1, str, ";", 1) + 1
UserNum = mid(str, temppos)
if UserNum = oldid then
i = i -1
j = j + 1
application("VisitorName") = mid(application("VisitorName"),1,i) & mid(application("VisitorName"),j)
exit do
end if
end if
i = j + 1
loop


'返回
response.write("aa") ‘注释8
%>


  注释1:利用FileSystemObject组件建立一个文件对象,将通讯过程中传送的东西写在文件里面,方便调试。
  注释2:创建一个文件。
  注释3:把Request.Form是传送进来的所有内容都写在文件里面,在服务器端留下调试痕迹。
  注释4:创建一个XML对象。
  注释5:通过loadxml()函数,导入Flash端传送进来的XML格式字符串。
  注释6:建立ID结点的对象,取得相应内容。
  注释7:这几步是处理“踢人”的动作,在这里只是简单地把要踢的用户从在线用户名单中删除,更严格的“踢人”可以把要踢的用户的IP地址写数据库中,只到管理员解开为止。
  注释8:直接构造一个XML字符串,并通过write函数写到Flash端。


七、FAQ


  1、开发环境介绍


  系统的开发环境为Win 2k + Flash MX 2004 + IIS 6.0 + IE 6.0 + 记事本。在IIS中所设置的虚拟目录的名称为xmlchat。


  2、涉及的数据库


  系统用到的数据库为Access 2000,数据库中只有一个用户表UserInfo,表中的字段为:ID、UserName、Pwd、Right。


  点击这里下载源文件

相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本