一对一聊天ajax实现

前端页面:
好友列表:
这里写图片描述
好友列表代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ page import="java.util.Random" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<title>好友列表</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="js/jquery.charfirst.pinyin.js"></script>
<script type="text/javascript" src="js/sort.js"></script>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/style1.css">
<style>input {border: 2px solid #7BA7AB;border-radius: 5px;}
</style>
<%request.setCharacterEncoding("UTF-8"); String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<base href="<%=basePath %>">
<script type="text/javascript">
$(function() { timeID = setInterval('fresh()', 2000); //注意:执行的函数需要加引号,否则会报错的  fresh();    }); function fresh(){/*用这种方式刷新的话性能太差*//* window.location.reload() */var id = $("#username").val();
/*      $.ajax({data:id,type:"post",url:"friendList.action?username="+id,dataType:"json",success:function(){},error:function(){}}) */}function f(val){$.ajax({data : val,type : "post",url : "CharServlet?id=" + val,dataType : "json",success : function(msg) {},error : function(msg) {alert("请求失败");}});}
</script>
</head>
<body><%Random random = new Random();request.setCharacterEncoding("UTF-8"); 
%>
<form id="fy" action="studentFind?" method="post"><input id="find" name="find" onkeyup="f(this.value)"style="width:300px;height:20px; redius:1px;"type="text" placeholder="请输入查找的好友"/>&nbsp;<img id="searchImg"style="width:20px;"alt="" src="img/search.png">&nbsp;&nbsp;<a href="javascript:window.location.href=''"></a><span id="mark"></span></a><a href="javascript:window.location.href='friend.jsp'"><img style="width:20px;"alt="" src="img/exit.png"></a>
</form><div class="gongneng"><div class="page"><img style="width:50px;height: 50px;" src="img/addFriend.svg" alt=""></div><a href="commend.action?username=${user.username}">添加好友</a></div><div id="letter" ></div>
<div class="sort_box"><c:forEach items="${list}" var="friend"><div class="sort_list"><div class="num_logo"><!-- 输出图片 --><img src="img/<%=random.nextInt(7)+1%>.jpg" alt=""></div><div class="num_name"><a href="sender2.jsp?name=${friend.name}&receiver=${friend.username}">${friend.name}</a></div></div></c:forEach>
</div>
<div class="initials"><ul><li><img src="img/068.png"></li></ul>
</div>
<input type="hidden" id="username" value="${user.username}"></body>
</html>

一对一聊天:
这里写图片描述

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta charset="UTF-8">
<title>聊天助手</title>
<link rel="stylesheet" href="css/chat.css">
<link rel="alternate icon" href="assets/i/favicon.ico">
<link rel="stylesheet" href="assets/css/amazeui.min.css">
<link rel="stylesheet" href="assets/css/app.css">
<link href="umeditor/themes/default/css/umeditor.css" rel="stylesheet">
<link rel="stylesheet" href="css/chat.css">
<link rel="stylesheet" href="css/common.css" />
<link rel="stylesheet" href="css/layout.css" />
<link rel="stylesheet" href="css/app_bar.css" />
<link rel="stylesheet" href="css/header.css" />
<link rel="stylesheet" href="css/content.css" />
<script type="text/javascript" src="js/zs_me.js"></script>
<script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
<style>
* {margin: 0;padding: 0;
}.chat-content-container {height: 49rem;overflow-y: auto;border: 1px solid silver;
} 
.am-u-sm-6{left:0px;
}
.am-u-sm-push-6{width:100%;
}
</style>
<%request.setCharacterEncoding("UTF-8"); String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<base href="<%=basePath %>">
<script>
$(function() { timeID = setInterval('f1()', 1000); //注意:执行的函数需要加引号,否则会报错的  f1();   }); function f1(){var username = $("#sender").val();var friendid = $("#receiver").val();var Rname=$('#name').val();var Sname=$('#sendername').val();$.ajax({data:null,type:"post",url:"message.action?username="+encodeURIComponent(username)+"&friendid="+encodeURIComponent(friendid),contentType: "application/json;charset=utf-8",dataType:"json",success:function(msg){var num = $("#num").text();var msNum = 0;/*msNum数据库中拿到的消息数量*/for(var i in msg){msNum = msNum + 1;}if(msNum != num){/*截取消息只保留新的消息内容,存在的问题第一次加载不需要截取*/var len = 0;$(msg).each(function(){var cname;/* len > num 说明数据库消息更新了 num==0 第一次加载消息 */if(len >= num || num==0){if(this.sender == username){isSelf = true;cname=Sname;}else{isSelf = false;cname=Rname;}var messageItem = '<li class="am-comment '+ (isSelf ? 'am-comment-flip' : 'am-comment')+ '">'+ '<a href="javascript:void(0)" ><img src="assets/images/'+ (isSelf ? 'self.jpg' : 'others.jpg')+ '" alt="" class="am-comment-avatar" width="48" height="48"/></a>'+ '<div class="am-comment-main"><header class="am-comment-hd"><div class="am-comment-meta">'+ '<a href="javascript:void(0)" class="am-comment-author">'+ cname + '</a> <time>' + '</time></div></header>'+ '<div class="am-comment-bd">' + this.message+ '</div></div></li>';$(messageItem).appendTo('#message-list');// 把滚动条滚动到底部$(".chat-content-container").scrollTop($(".chat-content-container")[0].scrollHeight);}len++;});/* num已接受的消息数量 */$("#num").html(msNum);}},error:function(){}});};document.onkeydown = function(e) {if (e.keyCode == 13 && e.ctrlKey) {// 这里实现换行document.getElementById("sendContent").value += "\n";} else if (e.keyCode == 13) {// 避免回车键换行e.preventDefault();// 下面写你的发送消息的代码f();}}/*自定义时间格式*/Date.prototype.Format = function (fmt) { // author: meizzvar o = {"M+": this.getMonth() + 1, // 月份"d+": this.getDate(), // 日"h+": this.getHours(), // 小时"m+": this.getMinutes(), // 分"s+": this.getSeconds(), // 秒"q+": Math.floor((this.getMonth() + 3) / 3), // 季度"S": this.getMilliseconds() // 毫秒};if (/(y+)/.test(fmt))fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));for (var k in o)if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));return fmt;}function fc(){window.location.href="friendList.action?username=${user.username}"}function f() {/*得到消息发送时间*/var time = new Date().Format("yyyy-MM-dd hh:mm:ss");/* 获得发送的信息 *//* var goodslength = $(".").length; */var cnt = $("#sendContent").val();$('#sendContent').val('');var sender = $("#sender").val();var receiver = $("#receiver").val();if(cnt == '')alert('内容不能为空');   if(cnt != ''){/*消息数量*/var n = $("#num").text();if(n>0){$("#sendContent").val(''); }$.ajax({data : cnt,type : "post",url : "chat.action?content=" + encodeURIComponent(cnt)+"&sender="+sender+"&receiver="+receiver+"&time="+time,contentType: "application/json;charset=utf-8",dataType : "json",success : function(msg) {},error : function(msg) {}});}}
</script>
</head>
<center><input id="sender" type="hidden" value="${user.username}"><br><input id="sendername" type="hidden" value="${user.name}"><br><!-- param接受a链接传值 --><input id="receiver" type="hidden" value="${param.receiver}"><br><input id="name" type="hidden" value="${param.name}"><br><span style="visibility:hidden" id="num">0</span>
</center><!-- 聊天内容框开始 --><div class="am-container container" ><div class="am-u-sm-12" style="background:#dcad50;"><!-- <div class="am-u-sm-3 am-u-sm-push-6"> --><h3 style="text-align:center;margin-top:auto;margin-bottom:auto;padding:3px 0px;font-size:20px">${param.name}</h3><!-- </div> --></div><div class="chat-content-container"><div class="am-u-sm-6 am-u-sm-push-6"><ul id="message-list" class="am-comments-list am-comments-list-flip"></ul></div></div>
<!--    </div> --><!-- 聊天内容框结束 --><div class="message-input am-margin-top"><!-- 输入内容框开始 --></div><div class="border-img"></div><textarea id="sendContent" style="width:100%; height:19rem;"></textarea><!-- 输入昵称框开始 --><!-- <div class="am-g am-g-fixed am-margin-top"> --><div class="am-u-sm-6" style="display: none;"><div id="message-input-nickname" class="am-input-group am-input-group-primary"><span class="am-input-group-label"><i class="am-icon-user"></i></span><input id="nickname" type="text" class="am-form-field" value="${user.name}"/></div></div><div class="am-u-sm-12"><p style="text-align:right;margin:0px"><button onclick="fc()" class="am-btn am-btn-warning">关闭</button><button id="send" onclick="f()" type="button" class="send am-btn am-btn-primary"><i class="am-icon-send"></i>发送</button></p></div></div>
</body>
</html>

后端处理:

package com.itcast.constroller;import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;import com.itcast.pojo.Chat;
import com.itcast.pojo.Commend;
import com.itcast.pojo.Commends;
import com.itcast.pojo.RegisterPojo;
import com.itcast.pojo.User;
import com.itcast.service.RegisterDemo;import net.sf.json.JSONArray;@Controller
public class ItemConstroller{@Autowiredprivate RegisterDemo registerDemo;@RequestMapping(value="/login.action")/*登录验证*/public ModelAndView showLoginPage(String username, String password,HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) throws IOException {response.setCharacterEncoding("UTF-8");User user = new User();user.setUsername(username);user.setPassword(password);/*获取用户信息*/User myUser = registerDemo.queryByUser(user);ModelAndView mv = new ModelAndView();if(myUser!=null){request.getSession().setAttribute("user", myUser);mv.setViewName("friend.jsp");}else{mv.setViewName("login.jsp");}return mv;}
/*  public String showLoginPage(String username, String password,HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) throws IOException {User user = new User();response.setCharacterEncoding("UTF-8");user.setUsername(username);user.setPassword(password);User myUser = registerDemo.queryByUser(user);if(myUser==null){解决通过服务器向页面弹出对话框?
//             PrintWriter out=response.getWriter();
//             out.print("<script language=\"javascript\">alert('登录失败!');window.location.href='/chat1/login.jsp'</script>");return "redirect:/login.jsp";}else{return "redirect:/friend.html";}}*/@RequestMapping(value="/test.action")public void test(String id, HttpServletRequest request, HttpServletResponse response) throws IOException{String str = request.getParameter(id);System.out.println(str);response.getWriter().write("{\"msg\":\"ok\"}");}/*验证账户是否已经存在*/@RequestMapping(value="/findUsername.action")public void findUsername(String id,HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException{System.out.println("验证账户");PrintWriter out = response.getWriter();if(registerDemo.queryById(id) == null){out.println("{\"state\":true }");}else{out.println("{\"state\":false }");System.out.println("账户已经存在");}}@RequestMapping(value="/register.action")/*若要直接往response中写内容而不经过视图解析器时可以使用@ResponseBody* @ResponseBody加上之后对返回ajax数据造成失效* *//*用户注册:RegisterPojo为注册的信息类*/public void ItemUpdate(User user, HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException{PrintWriter out = response.getWriter();user.setGroupsum(3);System.out.println(user.toString());if(user.getCompany() == null && user.getEmail() == null && user.getPassword() == null && user.getSex() == null && user.getTel() == null && user.getUsername() == null){out.println("{\"isSuccess\":false}");}else{if(registerDemo.insert(user)>0){System.out.println("注册成功");out.println("{\"isSuccess\":true}");}else{System.out.println("注册失败");out.println("{\"isSuccess\":false}");}}}@RequestMapping(value="/chat.action")/*发送消息*/public void AjaxSendMessage(String content, String sender, String receiver, String time, HttpServletRequest request, HttpServletResponse response){Chat chat = new Chat();System.out.println("内容"+content);chat.setSender(sender);StringBuilder str = new StringBuilder(content);/*将时间拼接到消息中 %作为标识符*/str.append("%").append(time);content = str.toString();chat.setMessage(content);chat.setReceiver(receiver);int insert = registerDemo.insert(chat);if(insert > 0){System.out.println("消息存储到数据库中"+content);}else{System.out.println("消息存储失败");}}@RequestMapping(value="/message.action")/*ajax接收消息*/public <T> void AjaxReceiveMessage(String username, String friendid, HttpServletRequest request, HttpServletResponse response) throws IOException{request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();//测试
//      System.out.println("3333333333333333333"+username+"---"+friendid);List<Chat> listSender = registerDemo.queryBySenderAndReceiver(username,friendid);List<Chat> listReceiver = registerDemo.queryBySenderAndReceiver(friendid, username);/*接受消息按照时间进行排序并且区分发送者和接受者 注意:当用户发送消息的时候前端已经添加了div此时并不需要去重复添加工作*/List<Chat> list = new ArrayList<>();list = listSender;list.addAll(listReceiver);for (Chat chat : list) {System.out.println("排序前:"+chat.getSender()+chat.getMessage()+chat.getReceiver());}/*时间排序*/Collections.sort(list,new Comparator<Chat>() {@Overridepublic int compare(Chat o1, Chat o2) {//一开始没设计好,按照时分秒存储的消息排序,隔天消息乱序输出
/*              String[] split = o1.getMessage().split("%");int len = split.length;String time1 = split[len-1];String[] tm = time1.split(":");Integer[] a = new Integer[3];a[0] = Integer.valueOf(tm[0]);a[1] = Integer.valueOf(tm[1]);a[2] = Integer.valueOf(tm[2]);Time t1 = new Time(a[0], a[1], a[2]);String[] split2 = o2.getMessage().split("%");len = split2.length;String time2 = split2[len-1];String[] tm2 = time2.split(":");Integer[] b = new Integer[3];b[0] = Integer.valueOf(tm2[0]);b[1] = Integer.valueOf(tm2[1]);b[2] = Integer.valueOf(tm2[2]);Time t2 = new Time(b[0],b[1],b[2]);return t1.compareTo(t2);*///按照年月日时分秒存储的消息记录排序DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");String[] split = o1.getMessage().split("%");String[] split2 = o2.getMessage().split("%");Date d1 = new Date();Date d2 = new Date();try {d1 = format.parse(split[split.length-1]);d2 = format.parse(split2[split2.length-1]);} catch (ParseException e) {e.printStackTrace();}return d1.compareTo(d2);}});/*更改message截取时间*/for (int i = 0; i < list.size(); i++) {Chat chat = list.get(i);String[] s = chat.getMessage().split("%");chat.setMessage(s[0]);}for (Chat chat : list) {//System.out.println("排序后:"+chat.getSender()+chat.getMessage()+chat.getReceiver());}if(list.size()>0){JSONArray json = JSONArray.fromObject(list);     //System.out.println("消息:"+json);out.println(json);  }else{System.out.println("获取信息失败");}}/*获取好友列表*/@RequestMapping(value="/friendList.action")public ModelAndView FriendList(String username, HttpServletRequest request, HttpServletResponse response){List<String> list = registerDemo.queryFriendListById(username);for (String s : list) {System.out.println("好友id:"+s);}ModelAndView mv = new ModelAndView();List<User> ll = new ArrayList<>();if(list.size()>0){for (String id : list) {if(!id.equals("")){User u = registerDemo.queryUserByid(id);ll.add(u);}}           }else{System.out.println("好友为空");}for (int i = 0; i < ll.size(); i++) {if(ll.get(i).getUsername().equals(username)){ll.remove(i);}}request.setAttribute("list", ll);
//      mv.addObject("list",list);/*mv.setViewName("redirect:friendList.jsp");导致前端通过jstl无法获取值问题?*/mv.setViewName("friendList.jsp");return mv;}/*查找好友*/@RequestMapping(value="/addFriend.action")public <T> void addFriend(String username, HttpServletRequest request, HttpServletResponse response) throws IOException{response.setContentType("text/html;charset=utf-8");User user = registerDemo.queryById(username);if(user!=null){/*加入list集合才能转换为jsonArray*/List<User> list = new ArrayList<>();list.add(user);System.out.println("查找的用户信息:"+user.getName()+user.getUsername());PrintWriter out = response.getWriter();JSONArray json = JSONArray.fromObject(list);System.out.println(json);out.println(json);  }else{System.out.println("查找的用户不存在");}}/*添加好友*/@RequestMapping(value="/add.action")public void add(String username, String id, HttpServletRequest request, HttpServletResponse response) throws IOException{response.setContentType("text/html;charset=utf-8");if("".equals(id)||"".equals(username)) return;/*验证是否已经添加过好友,避免重复添加操作*/System.out.println("账户:"+username);List<String> list = registerDemo.queryFriendListById(username);PrintWriter out = response.getWriter();boolean flag = true;for (String string : list) {if(string.equals(id)){flag = false;out.println(0);}}if(flag){out.println(1);registerDemo.addFriendById(username,id);registerDemo.addFriendById(id,username);}}/*好友推荐*/@RequestMapping(value="/commend.action")public ModelAndView command(String username, HttpServletRequest request, HttpServletResponse response){/*用来存储关联好友信息*/List<String> list = new ArrayList<>();/*获取当前用户的好友*/List<String> myFriend = registerDemo.queryFriendListById(username);/*找出好友的好友*/for (String id : myFriend) {List<String> list2 = registerDemo.queryFriendListById(id);list.addAll(list2);}System.out.println("我的好友"+myFriend);/*推荐算法实现*/Set<String> set = new HashSet<>();set.addAll(list);Map<String,Integer> map = new HashMap<>();for(String str : set){map.put(str, 0);}for(String str : list){Integer sum = map.get(str);map.put(str, sum++);}List<Map.Entry<String, Integer>> listEntry = new ArrayList<>(map.entrySet());Collections.sort(listEntry, new Comparator<Entry<String,Integer>>() {@Overridepublic int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}});List<Commend> l = new ArrayList<>();myFriend.add(username);//把自己账户添加进去做去重操作for (String ss : myFriend) {System.out.println("我的朋友:"+ss);}boolean flag = true;for (Entry<String, Integer> e : listEntry) {for(String ch : myFriend){if(ch.equals(e.getKey())){flag = false;}}if(flag){l.add(new Commend(e.getKey(),e.getValue()));}flag = true;}/*去重操作,去掉已经添加完的好友*/System.out.println("用户"+username);ModelAndView mv = new ModelAndView();for (Commend commend : l) {System.out.println("推荐好友123+:"+commend.getTimes()+commend.getUsername());}/*如果没有好友推荐就推荐所有用户*/List<String> lUser = registerDemo.selectUser(username); for (String s : lUser) {l.add(new Commend(s, -1));}List<Commends> names = new ArrayList<>();for (Commend c : l) {User user = registerDemo.queryById(c.getUsername());names.add(new Commends(c.getUsername(),c.getTimes(),user.getName()));}request.setAttribute("list", names);/*mv.addObject("list",l);*/mv.setViewName("searchFriend.jsp");return mv;}
}

用的springmvc框架,控制层处理获取所有待处理的业务逻辑,持久化的操作用了mybatis,数据库表的设计分为:好友列表表单和聊天信息表单,其中字段如图:这里写图片描述
这里写图片描述
加%号是为了和时间区分开,因为一开始数据库未设计好在获取聊天记录的时候又需要按照时间进行排序,因为再添加字段的话又需要在mapper中配置一些信息,因此为了减少工作量直接在%后面追加内容用以区分。
聊天原理:因为http是无状态的短链接,所以一次ajax请求结束后会自动断开链接,因为如果想持续保持通讯的话必须添加一个定时器来定时通过ajax从服务器取数据,达到通讯的目的,该方法的性能特别的差,不建议使用,因为之前并没有学习websocket又想着用自己所学的知识来实现这通讯功能因为并没有去考虑性能的问题,如果用websocket写的话性能会更好,因为可以通过socket代码块来操作传输层tcp的连接与断开,因为tcp协议是长连接,它并不像应用层的http协议在处理一次请求之后就断开并且所以的状态信息都被清空了,因为它也是无状态的短连接,而相反使用tcp可以避免这个问题,如果如果websocket来实现一对一通讯的话,把用户的id通过map进行存储,这样我们就可以通过key获取value来达到一对一的通讯,而前面做的websocket的时候存储用户的时候是用set存储然后再遍历set集合让各个客户端都可以接受到聊天信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“模块计算机类型“x64”与目标计算机类型“X86”冲突解决方案

最近在编译一款开源软件的时候&#xff0c;遇到了“模块计算机类型“x64”与目标计算机类型“X86”冲突的问题&#xff0c;网上查了好多资料&#xff0c;都是配置“链接器-》高级-》目标计算机”和选择X64平台编译器&#xff0c;可是怎么试都不行&#xff0c;最后发现是“命令行…

windows稀疏文件

稀疏文件(Sparse File), 指的是文件中出现大量的0数据&#xff0c;这些数据对我们用处不大&#xff0c;但是却一样的占用我们的空间&#xff0c;针对此&#xff0c;WINNT 3.51中的NTFS文件系统对此进行了优化&#xff0c;那些无用的0字节被用一定的算法压缩起来&#xff0c;使得…

选夫婿1

Problem Description 倾国倾城的大家闺秀潘小姐要选夫婿啦&#xff01;武林中各门各派&#xff0c;武林外各大户人家&#xff0c;闻讯纷纷前来&#xff0c;强势围观。前来参与竞选的男生藏龙卧虎&#xff0c;高手云集&#xff0c;才子遍布&#xff0c;帅哥纷纭&#xff0c;更不…

Qt实现Word文档界面样式--QtitanRibbon

QtitanRibbon - Microsoft Ribbon for Nokias Qt概念的实现 QtitanRibbon组件实现了Microsoft Ribbon for Qt的概念&#xff0c;设计用于任何使用Qt开发的商业应用。这个组件和Qt一道为获取一些应用提供了一个难得的机会&#xff0c;这些应用在全球三大主要平台Windows、Linux和…

选夫婿2

Problem Description 倾国倾城的大家闺秀潘小姐要选夫婿啦&#xff01;武林中各门各派&#xff0c;武林外各大户人家&#xff0c;闻讯纷纷前来&#xff0c;强势围观。前来参与竞选的男生藏龙卧虎&#xff0c;高手云集&#xff0c;才子遍布&#xff0c;帅哥纷纭&#xff0c;更不…

轻松反编译C#的DLL

深入了解Unity&#xff0c;需要知道它内部是怎样工作的&#xff0c;API的代码长什么样&#xff0c;本文以UnityEditor.dll为例&#xff0c;演示如何轻松搞定C#库的反编译。 使用的软件是jetbrains系的doPeek&#xff0c;.NET Reflector 9.0也能做同样的工作&#xff0c;但不太推…

Qt5中文乱码解决方案

升级到Qt5.X之后&#xff0c;原先解决的Qt显示中文乱码的方法突然不适用了&#xff0c;找了很多方式来解决这个问题 第一种&#xff1a; 在公司代码里看到的方法&#xff0c;先将对应的cpp文件用windows自带的记事本打开&#xff0c;另存为UTF-8格式&#xff0c;然后在代码中&a…

带你玩转Visual Studio——带你理解多字节编码与Unicode码

转自&#xff1a;http://blog.csdn.net/luoweifu/article/details/49382969 上一篇文章带你玩转Visual Studio——带你跳出坑爹的Runtime Library坑帮我们理解了Windows中的各种类型C/C运行时库及它的来龙去脉&#xff0c;这是C开发中特别容易误入歧途的一个地方&#xff0c;我…

如何快速高效读懂1本书

——半研墨拆书2《如何阅读1本书》 作为运营来讲&#xff0c;除了在实操中学习&#xff0c;还要扩充视角&#xff0c;开阔思维&#xff0c;建立更多解决问题的思考框架&#xff0c;这就要求我们&#xff0c;要多读书&#xff0c;还要会读书。就是说&#xff0c;我们在快速阅读的…

c#学习书籍

楼主这些年一直追随微软技术&#xff0c;也看了不少书籍&#xff0c;整理出一些个人认为不错的经典&#xff0c;推荐给各位阅读&#xff0c;以共同进步。 推荐顺序是由浅入深&#xff0c;深入浅出。 《Professional C#》&#xff0c;中文名《C#高级编程》&#xff0c;最新版本&…

查并集

The White Belt Good developers who are familiar with the entire stack know how to make life easier for those around them. 博客园首页新随笔联系订阅管理 随笔 - 159 文章 - 0 评论 - 0用于不相交集合的数据结构——查并集 不相交集合数据结构的概念和操作&#xff1…

给程序员的10条建议

1. 想清楚&#xff0c;再动手写代码 刚入行的新手&#xff0c;为了展示自己的能力&#xff0c;拿到需求迫不及待地就开始上手写代码&#xff0c;大忌&#xff01; 2. 不交流&#xff0c;就会头破血流 不爱说话和沟通&#xff0c;需求都理解错误了&#xff0c;最后做出来才发现…

传说中的800句记7000词

登录 | 注册 ZHB_McCoy的专栏 目录视图摘要视图订阅 一键管理你的代码 攒课--我的学习我做主 【hot】直播技术精选 id"cpro_u2392861_iframe" src"http://pos.baidu.com/sczm?sz300x250&rdid2392861&dc2&diu2392861&dri0&dis0&…

怎样才算得上合格的程序员

转自&#xff1a;http://blog.csdn.net/B9Q8e64lO6mm/article/details/78829370 最近同一部门另一个项目组的一位程序员被“主动离职”了&#xff0c;虽然我未曾与这个程序员共事过&#xff0c;但是听过一两次他的内部分享&#xff0c;感觉技术还是挺厉害的。后来与一个消息灵通…

c# MEF框架(一 MEF简介及简单的Demo)

转自&#xff1a;http://www.cnblogs.com/yunfeifei/p/3922668.html 在文章开始之前&#xff0c;首先简单介绍一下什么是MEF&#xff0c;MEF,全称Managed Extensibility Framework&#xff08;托管可扩展框架&#xff09;。单从名字我们不难发现&#xff1a;MEF是专门致力于解决…

c# MEF框架(二 MEF的导出(Export)和导入(Import))

转自&#xff1a;http://www.cnblogs.com/yunfeifei/p/3922891.html 上一篇学习完了MEF的基础知识&#xff0c;编写了一个简单的DEMO&#xff0c;接下来接着上篇的内容继续学习&#xff0c;如果没有看过上一篇的内容&#xff0c; 请阅读&#xff1a;http://www.cnblogs.com/yun…

c# MEF框架(三 导出类的方法和属性)

转自&#xff1a;http://www.cnblogs.com/yunfeifei/p/3927663.html 前面说完了导入和导出的几种方法&#xff0c;如果大家细心的话会注意到前面我们导出的都是类&#xff0c;那么方法和属性能不能导出呢&#xff1f;&#xff1f;&#xff1f;答案是肯定的&#xff0c;下面就来…

c# MEF框架(四 见证奇迹的时刻之实战应用)

转自 http://www.cnblogs.com/yunfeifei/p/3940075.html 前面三篇讲了MEF的基础和基本到导入导出方法&#xff0c;下面就是见证MEF真正魅力所在的时刻。如果没有看过前面的文章&#xff0c;请到我的博客首页查看。 前面我们都是在一个项目中写了一个类来测试的&#xff0c;但实…

c# MEF框架(四 MEF高级进阶)

转自&#xff1a;http://www.cnblogs.com/yunfeifei/p/3991330.html 好久没有写博客了&#xff0c;今天抽空继续写MEF系列的文章。有园友提出这种系列的文章要做个目录&#xff0c;看起来方便&#xff0c;所以就抽空做了一个&#xff0c;放到每篇文章的最后。 前面四篇讲了MEF的…

Unity3D求向量间的夹角

如下图 Vector3 srcPos new Vector3(0,0,0);Vector3 tarPos new Vector3(0,0,-1);Vector3 srcRot new Vector3(0,90,0);Quaternion srcQua Quaternion.Euler(srcRot);Vector3 direction tarPos - srcPos;Vector3 r Quaternion.Inverse(srcQua) * direction;Debug.Log(r);…