精华内容
下载资源
问答
  • 本程序主要提供爱好编码者进行学习参考,程序提供的消息提示和QQ的没多大区别,希望大家好好学习天天向上!
  • QQ系统消息生成器

    2012-12-13 12:55:12
    QQ系统消息生成器插件 ,模仿QQ系统消息发送消息,自动弹系统消息出窗口,消息内容和链接网站、发送频率时间可修改。仅供学习研究参考,请勿用于非法用途。
  • 模仿QQ的聊天室系统

    2013-01-11 12:56:03
    系统采用C#作为客户端,java作为服务器,服务器采用文件形式保存用户信息,实现的功能有:注册好友,添加好友,在线群聊,发送文件,离线接收消息,离线接收文件,好友上线,下线等都有消息声音提醒,高仿QQ好友...
  • Android studio模仿qq聊天

    2018-12-21 14:27:28
    使用Android Studio软件构建客户端,使用VS2015的C#语言构建服务器端,客户端进行消息的发送与接收,服务器端进行信息管理以及信息中转,客户端与服务器端联合使用,最终构成了一个简单的聊天系统
  • 模仿聊天室系统

    2013-01-15 11:13:24
    系统采用C#作为客户端,java作为服务器,服务器采用文件形式保存用户信息,实现的功能有:注册好友,添加好友,在线群聊,发送文件,离线接收消息,离线接收文件,好友上线,下线等都有消息声音提醒,高仿QQ好友...
  • QQ里面有一个非常炫酷的动画,就是它的消息提示的小红点是可以拖拽的。这个动画综合运用了绘图、手势拖拽和CAShapeLayer的基础知识,下面我们就通过一个小项目来模仿一下: QQ消息提示拖拽示例.gif 一、...


    QQ里面有一个非常炫酷的动画,就是它的消息提示的小红点是可以拖拽的。这个动画综合运用了绘图、手势拖拽和CAShapeLayer的基础知识,下面我们就通过一个小项目来模仿一下:


    QQ消息提示拖拽示例.gif

    一、添加消息按钮

      
      首先,你需要知道这个小红点其实是一个UIButton,因为这个button的形状和系统默认的不太一样,所以肯定会想到要自定义一个UIButton。先在Main.storyboard文件中的控制器里布局一个UIButton控件,然后新建一个继承自UIButton的ESTipsButton类来描述它:


    布局子控件.png

      将按钮的背景颜色设置成红色,并给它的Label随便设置一个白色的数字,为了便于后面的操作,我将这个按钮的尺寸设置的非常的大。先运行程序看一下:


    程序运行的初始效果.png

      从GIF图上可知,这个按钮应该是圆的,为此,来到ESTipsButton.m文件,对按钮进行初始化:

    // MARK:- 控件的初始化(Main.storyboard或者xib)
    - (void)awakeFromNib {
    
        [super awakeFromNib];
    
        /************************** 初始化按钮 **************************/
    
        // 初始化按钮
        [self setup];
    }
    
    // MARK:- 初始化控件(纯代码)
    - (instancetype)initWithFrame:(CGRect)frame {
    
        if (self = [super initWithFrame:frame]) {
    
            // 初始化按钮
            [self setup];
        }
    
        return self;
    }
    
    // MARK:-  初始化按钮(保证通过代码创建的tips按钮背景颜色、文字等和通过Main.storyboard创建的一样)
    - (void)setup {
    
        // 设置按钮的圆角
        self.layer.cornerRadius = self.bounds.size.width * 0.5;
    
        // 设置按钮背景颜色
        [self setBackgroundColor:[UIColor redColor]];
    
        // 设置按钮文字颜色
        [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    
        // 设置按钮文字大小
        self.titleLabel.font = [UIFont systemFontOfSize:40];
    }

      我们这个按钮是通过Main.storyboard加载的,所以应该在- awakeFromNib方法中对其进行初始化。有一个问题,就是我们在Main.storyboard文件中已经设置好了按钮的背景颜色、label文字的颜色和字体大小,为什么在初始化的时候还要重复操作一遍呢?这个主要是从封装的角度考虑的。因为以后按钮可能不只是从Main.storyboard或者xib文件中加载,也有可能是通过纯代码的方式加载,如果不在初始化的过程中再将它们设置一遍,那么通过纯代码的方式加载的按钮,其背景颜色、label的文字颜色和字体大小可能就不是预期结果了。运行程序看一下:


    将按钮设置成圆形.png

    二、让按钮可拖动

      
      我们已经办到让按钮呈现出圆形,接下来就是要让按钮可拖动。为此,来到- awakeFromNib方法和- initWithFrame:方法中,给按钮添加拖动手势(由于我们这个按钮是通过Main.storyboard文件加载的,只在- awakeFromNib方法中添加手势也是可以的):

    // MARK:- 控件的初始化
    - (void)awakeFromNib {
    
        [super awakeFromNib];
    
        /************************** 初始化按钮 **************************/
    
        // 初始化按钮
        [self setup];
    
        /************************** 添加手势 **************************/
    
        // 添加拖动手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
        [self addGestureRecognizer:pan];
    }
    
    // MARK:- 初始化控件
    - (instancetype)initWithFrame:(CGRect)frame {
    
        if (self = [super initWithFrame:frame]) {
    
            // 初始化按钮
            [self setup];
    
            /************************** 添加手势 **************************/
    
            // 添加拖动手势
            UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
            [self addGestureRecognizer:pan];
        }
    
        return self;
    }

      实现拖动手势时的方法- panGesture:。回顾一下我们在前面学习的手势拖动的方法,要实现手势拖动,首先必须获取当前手势所在的点;然后,再通过这个点获取相应的x轴和y轴的偏移量。有了偏移量之后,就可以通过CGAffineTransformTranslate ( )函数来设置按钮的transform属性了;最后,为了保证手势拖动的流畅,必须做复位操作:

    // MARK:- 实现手势拖动的方法
    - (void)panGesture:(UIPanGestureRecognizer *)pan {
    
        // 获取当前手势所在的点
        CGPoint currentPoint = [pan locationInView:self];
    
        // 让按钮根据手势移动做出平移(transform不会修改center的值,它修改的是frame的值)
        self.transform = CGAffineTransformTranslate(self.transform, currentPoint.x, currentPoint.y);
    
        // 复位操作
        [pan setTranslation:CGPointZero inView:self];
    }

      运行程序,看看能不能拖动屏幕上的按钮:


    让按钮随着手指的移动而移动.gif

      现在,我们可以办到让按钮随着手指的移动而移动了。不过,在手指移动过程中,这个按钮是有高亮状态的。实际上,QQ消息的高亮状态是没有的,所以,我们还需要去掉这个按钮的高亮状态:

    // MARK:- 取消按钮的高亮状态
    - (void)setHighlighted:(BOOL)highlighted {
    
        highlighted = NO;
    }

      再次运行程序,看一下高亮状态还有没有:


    去掉按钮的高亮状态.gif

    三、给按钮底部添加一个小圆

      
      看一下原始程序,当我们拖动按钮时,它底部应该是有一个小圆的。为此,我们先来添加这个小圆。这个小圆应该是程序一运行时就有的,它处在按钮的底部,并且尺寸和背景颜色与按钮一样。还有,底部这个小圆在其它方法中也会用到,应该在ESTipsButton的类扩展中声明一个属性来保存它:

    // 创建小圆
    UIView *smallCircle = [[UIView alloc] initWithFrame:self.frame];  // 小圆的位置和尺寸与按钮一致
    
    // 设置小圆的背景颜色
    smallCircle.backgroundColor = [UIColor redColor];
    
    // 设置小圆的圆角
    smallCircle.layer.cornerRadius = self.layer.cornerRadius;
    
    // 将smallCircle保存起来
    self.smallCircle = smallCircle;
    
    // 将小圆添加到控制器的view上(也就是按钮的父控件上)
    [self.superview addSubview:smallCircle];
    
    // 将小圆插入到按钮与控制器的view中间
    [self.superview insertSubview:smallCircle belowSubview:self];

      这个小圆比按钮后创建,将它添加上去的时候肯定是盖在按钮上面的,但是,我们的需求是,按钮必须在小圆上面。不过,好在- insertSubview: belowSubview:这个方法可以帮助我们调整按钮和它底部小圆之间的顺序。来运行程序看一下:


    给按钮底部添加一个小圆.gif

    四、计算两个圆之间的距离

      
      从原始的GIF图中我们可以看到,当我们拖动消息提示的小按钮时,底部的小圆会随着距离的增大而逐渐缩小。为此,我们首先要做的是,计算出按钮和它底部小圆之间的圆心距离。来到手势拖动的实现方法中,计算出按钮和小圆之间的圆心距离。为了保证代码的可读性,最好是做到分模块设计,将计算圆心距的代码抽出来单独作为一个方法:

    // MARK:- 计算按钮和它底部小圆之间的距离
    - (CGFloat)distanceBetweenSmallCircle:(UIView *)smallCircle andTipsButton:(UIButton *)tipsButton {
    
        // x轴方向上的偏移量
        CGFloat offsetX = tipsButton.center.x - smallCircle.center.x;
    
        // y轴方向上的偏移量
        CGFloat offsetY = tipsButton.center.y - smallCircle.center.y;
    
        // 两个圆形之间的距离
        return sqrt(offsetX * offsetX + offsetY * offsetY);
    }

      来到- panGesture:方法的底部,调用一下计算按钮和它底部小圆之间圆心距的方法:

    /************************** 计算两个圆之间的距离 **************************/
    
    CGFloat distance = [self distanceBetweenSmallCircle:self.smallCircle andTipsButton:self];

      为了验证计算结果,我们先打印一下distance,看看它有没有值:


    打印按钮与它底部小圆之间圆心的距离.gif

      从控制台打印出来的消息看,在手指拖动的过程中,这个distance的值一直是0!难道是我们的计算方法有误吗?其实并不是,只不过,通过transform属性所做的平移,它并不会修改控件center的值,它修改的是控件的frame。而为了计算出按钮和它底部小圆之间的圆心距,又必须要借助它们的center。为此,我们要使用新的方式来让按钮做出平移。先将self.transform = CGAffineTransformTranslate(self.transform, currentPoint.x, currentPoint.y);注释掉,然后获取按钮center的值,接着修改center的x和y的值,最后将修改过后的center赋值回去:

    CGPoint center = self.center;  // 取出按钮的center的值
    center.x += currentPoint.x;  // 修改center的x值
    center.y += currentPoint.y;  // 修改center的y值
    self.center = center;  // 将修改过后的center的值赋值回去

      运行程序,看看通过这种方式有没有让按钮随着手指的拖动做出平移,同时查看distance的值有没有变化:


    修改平移方式,计算出圆心距.gif

    五、让按钮底部小圆的半径随着圆心距的增大而缩小

      
      圆心距已经求出来了,接下来就是要让按钮底部的小圆随着圆心距的增大而缩小。这项功能还是和手指拖动有关,因此还是在- panGesture:方法中实现它:

    // 取出小圆的半径
    CGFloat smallR = self.smallCircle.bounds.size.width * 0.5;
    
    // 让小圆的半径随着距离的增大而缩小
    smallR -= distance / 10.0;
    
    // 重新设置smallCircle的bounds
    self.smallCircle.bounds = CGRectMake(0, 0, smallR * 2, smallR * 2);
    
    // 重新设置圆角半径
    self.smallCircle.layer.cornerRadius = smallR;

      在上述代码中,数字10并没有什么特殊的含义,只不过是为了让小圆的半径随着圆心距的增大而缩小所除的一个数字,你完全可以改成其它的。这个数字你可以自己去控制。运行程序看一下:


    让小圆的半径随着圆心距的增大而缩小.gif

      从图上可以看到,随着圆心距的增大,这个小圆缩小得非常的快。而且,当圆心距增大到一定的距离以后,这个小圆完全变成了一个正方形(小圆的半径为负值以后就变成了正方形)!这是为什么呢?回忆一下在《手势识别》中所学到的知识,这主要是因为没有执行"复位操作"的原因。因为- panGesture:这个方法调用得非常的频繁(按钮每移动一丁点,它就会被调用一次),而我们小圆的半径都是在上一次已经缩小过半径的基础上再次不断缩小的,所以小圆的半径最后会缩小得非常疯狂!我们需要的效果是,小圆的半径是在原始半径的基础上逐渐缩小(而不是在上一次已经缩小过的基础上再次不断缩小)。那么,有什么办法可以执行类似的"复位操作"呢?其实,小圆的半径最开始是和按钮的半径相等的,而按钮的半径在整个移动过程中是固定不变的。为此,只需要将取出小圆半径的代码从CGFloat smallR = self.smallCircle.bounds.size.width * 0.5;换成CGFloat smallR = self.bounds.size.width * 0.5;,问题就可以迎刃而解了。运行程序看一下:


    让小圆的半径随着圆心距的增大而不断缩小.gif

    六、描述拖动按钮时两个圆之间的不规则路径

      
      接下来要完成的操作是,当按钮与它底部小圆之间圆心距逐渐增大时,绘制它们之间像鼻涕一样不规则的图形。要完成绘图,首先要描述好路径,为此,我们先来分析一下。先看下面的图:


    粘性计算图.png

      只需要计算出上图中6个绿色点所在的点坐标,然后描述相应的路径就可以了。其中,A点到B点是一条直线,B点到C点是一条曲线,而P点是这条曲线的控制点;C点到D点又是一条直线,D点到A点同样是一条曲线,而O点是这条曲线的控制点。在上面的图中,小圆和大圆的圆心点坐标、两个圆的半径,以及两个圆心之间的距离都是已知的,只需要简单的三角函数知识就可以计算出A、B、C、D、O和P点的坐标。有了这些坐标,再描述相应的路径,那就是再简单不过的事情了:

    // MARK:- 描述两个圆之间的不规则路径
    - (UIBezierPath *)pathWithSmallCircle:(UIView *)smallCircle andTipsButton:(UIButton *)tipsButton {
    
        // 求点
        CGFloat x1 = smallCircle.center.x;
        CGFloat y1 = smallCircle.center.y;
    
        CGFloat x2 = tipsButton.center.x;
        CGFloat y2 = tipsButton.center.y;
    
        CGFloat d = [self distanceBetweenSmallCircle:smallCircle andTipsButton:tipsButton];
    
        if (d <= 0) {
    
            return nil;
    
        }
    
        CGFloat cosΘ = (y2 - y1) / d;
        CGFloat sinΘ = (x2 - x1) / d;
    
        CGFloat r1 = smallCircle.bounds.size.width * 0.5;
        CGFloat r2 = tipsButton.bounds.size.width * 0.5;
    
        CGPoint pointA = CGPointMake(x1 - r1 * cosΘ, y1 + r1 * sinΘ);
        CGPoint pointB = CGPointMake(x1 + r1 * cosΘ, y1 - r1 * sinΘ);
        CGPoint pointC = CGPointMake(x2 + r2 * cosΘ, y2 - r2 * sinΘ);
        CGPoint pointD = CGPointMake(x2 - r2 * cosΘ, y2 + r2 * sinΘ);
        CGPoint pointO = CGPointMake(pointA.x + d * 0.5 * sinΘ, pointA.y + d * 0.5 * cosΘ);
        CGPoint pointP = CGPointMake(pointB.x + d * 0.5 * sinΘ, pointB.y + d * 0.5 * cosΘ);
    
        // 描述路径
        UIBezierPath *path = [UIBezierPath bezierPath];
    
        // AB
        [path moveToPoint:pointA];  // 设置A为起点
        [path addLineToPoint:pointB];  // 添加一根线到B点
    
        // BC(曲线)
        [path addQuadCurveToPoint:pointC controlPoint:pointP];  // 添加一根曲线到C点,其中P点为控制点
    
        // CD
        [path addLineToPoint:pointD];  // 添加一根直线到D点
    
        // DA(曲线)
        [path addQuadCurveToPoint:pointA controlPoint:pointO];  // 添加一根曲线到A点,其中O点为控制点
    
        // 返回路径
        return path;
    }

    七、根据已描述的路径绘图

      
      路径已经描述好了,接下来就是在手指拖动的过程中,绘制不规则路径。所以,应该在- panGesture:方法中实现这个功能。

      要完成这个功能,先来学习一个新的知识点——CAShapeLayer。它是CALayer的一个子类,使用起来非常灵活,只要你描述好了路径,通过它可以画出各种形状的图形。照例还是进入它的头文件中看一下:


    CAShapeLayer.png

      与CAGradientLayer和CAReplicatorLayer比起来,它的内容稍微多那么一点点,不过也都很好理解。我们今天要用的是它的path属性。先调用我们在上面写的- pathWithSmallCircle: andTipsButton:方法,获取已经描述好的路径,然后再创建CAShapeLayer图层对象,并且将已获取到的路径传给CAShapeLayer对象的path属性,最后将CAShapeLayer图层对象插入到小圆的下面就可以了:

    // 获取path
    UIBezierPath *path = [self pathWithSmallCircle:self.smallCircle andTipsButton:self];
    
    // 创建形状图层
    CAShapeLayer *shpeLayer = [CAShapeLayer layer];
    
    // 将已经描述好的路径传给CAShapeLayer对象的path属性
    shpeLayer.path = path.CGPath;
    
    // 设置路径填充颜色
    shpeLayer.fillColor = [UIColor redColor].CGColor;
    
    // 将形状图层插入到最底下
    [self.superview.layer insertSublayer:shpeLayer above:0];

      来运行程序看一下效果:


    创建了太多CAShapeLayer图层对象.gif

      说好的鼻涕效果,为什么看起来特别像大姨妈?!还记得在上面说过的,- panGesture:这个方法调用非常频繁吗?我们将创建CAShapeLayer图层的代码放在这个方法里,导致了在手势拖动的过程中创建了无数个形状图层(从GIF图上可以看出创建了N个),我实际上,自始至终我们只需要一个。为此,我们需要对创建形状图层的代码进行懒加载。先在ESTipsButton的类扩展中声明一个shpeLayer属性,然后对它进行懒加载:

    // MARK:- 形状图层的懒加载
    - (CAShapeLayer *)shpeLayer {
    
        if (!_shpeLayer) {
    
            // 创建形状图层
            CAShapeLayer *shpeLayer = [CAShapeLayer layer];
    
            // 将形状图层插入到最底下
            [self.superview.layer insertSublayer:shpeLayer above:0];
    
            // 设置路径填充颜色
            shpeLayer.fillColor = [UIColor redColor].CGColor;
    
            _shpeLayer = shpeLayer;
        }
    
        return _shpeLayer;
    }

      来到- panGesture:方法,将之前创建形状图层的代码修改为下面这样的:

    // 获取path
    UIBezierPath *path = [self pathWithSmallCircle:self.smallCircle andTipsButton:self];
    
    // 将已经描述好的路径传给CAShapeLayer对象的path属性
    self.shpeLayer.path = path.CGPath;

      运行程序看一下:


    在手指拖动的过程中创建形状图层.gif

    八、手势拖动结束以后的处理

      
      从上面的GIF图可以看出,现在不管手指怎么拖,CAShapeLayer图层对象永远都只有一份了。可以去玩一下QQ的消息提示按钮,当你用手指进行拖动时,如果拖动距离没有超过一定距离,松开手指以后,提示按钮会回弹复位的。只有当你的手指拖动距离超过一定的范围之后,消息提示才会消失。下面我们来实现一下这些功能。

      先来实现当手指拖动的距离超过一定范围时,按钮底部的小圆完全消失。这个距离可以自己根据实际情况来调试,不过,其大小最好是要在让小圆的半径变成负数之前:

    // 当按钮与小圆之间的距离大于某个值时
    if (distance > 200) {
    
        // 隐藏小圆
        self.smallCircle.hidden = YES;
    
        // 删除形状图层
        [self.shpeLayer removeFromSuperlayer];
    }

      运行程序看一下:


    当圆心距超过一定范围时,让底部小圆隐藏.gif

      现在,当圆心距超过一定范围以后,底部的小圆是可以消失了,但是又出现两个问题。第一个问题是,当我们把按钮重新拖到靠近小圆原来所在的位置时,已经消失的图层对象又出现了。解决的办法就是,在给图层对象path属性传递已描述好的路径的地方加上一个判断:

    // 如果小圆没有被隐藏
    if (self.smallCircle.hidden == NO) {
    
        // 将已经描述好的路径传给CAShapeLayer对象的path属性
        self.shpeLayer.path = path.CGPath;
    }

      也就是说,当小圆处于非隐藏状态下时,才需要给shpeLayer的path属性传递已描述好的路径。第二个问题是,当手指拖动结束以后,按钮没有回弹或者消失。解决这个问题,需要对手势拖动的状态进行判断。当手势拖动结束以后,如果没有超过一定距离,就让按钮回弹复位;如果拖动距离超过一定的距离,就让按钮消失。来到- panGesture:方法中,对手势拖动的状态进行判断:

    // 当手势拖动结束时
    if (pan.state == UIGestureRecognizerStateEnded) {
    
        // 如果拖动的距离大于200
        if (distance < 200) {
    
            // 将形状图层从父控件中移除
            [self.shpeLayer removeFromSuperlayer];
    
            // 直接让按钮复位
            self.center = self.smallCircle.center;
    
            // 重新显示小圆,以便下次拖动按钮时可以重新绘制不规则图形
            self.smallCircle.hidden = NO;
    
        } else {
    
            // 创建UIImageView对象
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.bounds];
    
            // 用于存储播放动画的图片
            NSMutableArray *imageArr = [NSMutableArray array];
    
            for (int i = 0; i < 8; i++) {
    
                // 加载图片
                UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d", i + 1]];
    
                // 将图片添加到数组中
                [imageArr addObject:image];
            }
    
            // 设置图片动画
            imageView.animationImages = imageArr;
    
            // 设置动画执行时间
            imageView.animationDuration = 1;
    
            // 开始播放动画
            [imageView startAnimating];
    
            // 将图片添加到按钮上
            [self addSubview:imageView];
    
            // 动画播放的时长是1秒,动画完毕以后直接从父控件中删除按钮
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
                // 移除按钮
                [self removeFromSuperview];
    
            });
        }
    }

      上面对手势状态进行判断的代码非常简单,不做详细解释。其中,播放图片动画的基础知识在《UIImageView的帧动画》中已经演示过,而GCD定时器的使用在之前的篇幅中也多次用过。现在运行程序看一下效果:


    完成项目.gif

      从图中可以看出,当拖动距离没有超过一定范围就松手时,按钮是会回弹的。当拖动距离超过一定范围以后,按钮底部小圆消失,但是再把按钮拖回小圆之前所在的位置附近时,也没有出现重新绘制不规则图形的情形。最后,拖动距离超过一定范围之后,松开手,提示按钮完全消失。详细代码参见ESQQTips

    展开全文
  • 这里就直接进入正题,讲解如何实现贴图按钮的...如果鼠标在按钮区域,该函数返回按钮ID,在系统按钮区域,返回HTMINBUTTON,HTMAXBUTTON,HTCLOSE,方便直接发送系统命令,不在任何按钮,返回HTCAPTION,可以拖动窗口。
  • 仿QQ即时通信系统

    千次阅读 2018-07-12 22:45:04
    这学期学了网络编程,课设是让做一个通信系统,能力有限,想不出来自己能设计一个什么通信系统,就模仿腾讯的产品设计一个仿QQ的通信系统。PS:其实背景可以改一下,XX公司需要一个内部通信系统… 话不多说,先上...

    这学期学了网络编程,课设是让做一个通信系统,就模仿腾讯的产品设计一个仿QQ的通信系统。PS:用的时候,背景可以改一下,XX公司需要一个内部通信系统…

    话不多说,先上图片,再慢慢讲原理吧。


    效果示意图:

    用户登陆界面 主界面
    对话框服务器
    整体效果

    功能

    现阶段实现的功能有
    客户端: 登陆 注册 找回密码 上下线状态显示 发送文字消息等一些小的功能 。
    服务器:显示用户 日志管理等

    原理

    该系统是基于C/S架构的。大概意思就是客户端发送消息经过服务器转发给另外一个人,客户端的登陆,注册账号或者找回密码都是经过网络传到服务器,然后服务器操作SQL Server数据库进行增删查改。
    用到的数据库表。
    用户列表字段好友列表
    用户列表具体数据好友列表具体数据

    再细节的东西,编码我就不讲了,有啥细节我们可以讨论,代码注释比较全。

    总结

    这是第一个自己设计,自己编写的程序。感觉写出来一个完美的程序太累了,太不容易了。另外,敲代码还是需要用软件工程的知识来设计,要不然会走很多弯路。
    当然,个人水平有限,程序还有很多不完善,例如添加好友,用户上下线状态显示,传输文件,语音,视频等功能还没有写。后续会补充上。

    附上代码

    代码连接

    ps:参考的时候自己要配置好数据库,网络通信等

    最新代码链接(补充上了用户上下线功能)

    展开全文
  • 该示例主要使用了react,redux,iscroll,fetch等组件实现模仿实现PC微信聊天,实现了发送消息,模拟登录,临时使用fetch定时请求更新接收消息等功能,实时通讯功能还在持续更新实现中, 希望能对喜欢的React,对于...
  • 佳蓝仿QQ群在线聊天系统采用先进的数据传输原理,模仿QQ群界面。支持几千人同时在一个群里聊天交流,具有安全、快速、安全、稳定等特点   基本功能: ·仿QQ群聊天大厅(主要功能) ·群共享功能 ·好友功能,...
  • 基于webSocket实现聊天系统,ui设计模仿QQ。计划实现的功能分为如下几块: 注册登录 好友、群聊的添加,查询,删除 一对一在线聊天 分组在线群聊 聊天记录管理 个人信息管理 发送离线消息 思考中… 涉及到的技术:...

    1.概述

    基于webSocket实现聊天系统,ui设计模仿QQ。计划实现的功能分为如下几块:

    • 注册登录
    • 好友、群聊的添加,查询,删除
    • 一对一在线聊天
    • 分组在线群聊
    • 聊天记录管理
    • 个人信息管理
    • 发送离线消息
    • 思考中…

    涉及到的技术:vue,springboot,mybatis,mysql,redis,webSocket

    等全部完成了会将代码上传到github,有兴趣的可以关注一波。

    2.目前进展

    界面如下:

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3.未完待续

    目前只做了一部分前端的工作,webSocket聊天系统系列博客将会一直更新到项目完成为止。

    展开全文
  • 目前客户端程序的界面完全模仿腾讯的QQ(如果Tencent告我的话,我会马上改的:-)。 总之,如果你崇尚自由,对QQ的越来越多的广告骚扰感到深恶痛绝的话,MyICQ绝对是你很好的选择。 基本功能特点 --------------- 1) ...
  • TCP聊天系统开发心得

    千次阅读 2015-12-28 20:21:10
    最新做了一个基于TCP协议的模仿QQ聊天系统,用到的新的知识不是很多,都是以前开发项目的时候常用的知识点,该系统使用C++开发,采用MFC框架实现界面,网络那块只要是Socket的应用,因为登录功能和消息保存的功能,...

    最新做了一个基于TCP协议的模仿QQ聊天系统,用到的新的知识不是很多,都是以前开发项目的时候常用的知识点,该系统使用C++开发,采用MFC框架实现界面,网络那块只要是Socket的应用,因为登录功能和消息保存的功能,该系统还用到了SQL Server 2008来实现数据管理。

    因为用到的新的知识不是很多,加上有之前的项目开发经验,该系统我只用了一天时间就实现了要求的功能,主要是一对一、一对多、多对多(群聊)的聊天功能,还有就是消息的保存和删除,比较困难实现的是文件的传输功能,这个主要是因为要另外应用Socket来实现,所以代码量就增多了不少。

    虽然用到的新的知识不是很多,但其中开发过程中的细节还是值得总结一下,为以后开发项目提供经验。

    1.在实现消息保存功能的时候,想到的是QQ聊天记录是自动保存在登陆QQ的设备上的,电脑登陆就保存在硬盘上,手机登陆就保存在内存卡上,如果开通了QQ漫游功能,可以将聊天记录保存在腾讯服务器上。所以我就采用比较简单的方式,就是使用数据库,因为这样操作也便于管理消息记录。

    在这里,因为有一点之前没有接触,值得说明,向数据表中追加数据的SQL语句:

    update表名 set msg=msg+'%s' where [name]='%s'

    2.另外一点特别值得注意,在实现文件传输的时候,因为要首先发送文件名和大小信息,之前的代码:

    // file tansport msg

    else if (msg.Find(_T("fil")) == 0)// file tansport/from/msg

    {

    k = msg.ReverseFind('/');

    infor = msg.Right(length - k - 1);

    from = msg.Mid(4, k - 4);

    manager.AppendShakeRecv(from, _T("向你发送文件--")+infor);

    manager.FileRecv(from, infor);

    }

    其中的infor就是文件信息,因为发送的字符串以“/”为分隔符,例如:

    pri/小明/你好 表示一对一聊天:向小明发送“你好“,

    发送文件的时候以fil/小明/test.rar/267941

    表示向小明发送文件test.rar,大小为267941字节。

    服务器在解析消息的时候,要以“/”为分隔符截取字符串,因为文件信息为test.rar/267941这样增加了解析的难度,我在这里足足想了好几十分钟,也没实现截取,后来听了一个电话之后回来对着电脑,突然灵机一动,既然文件信息test.rar/267941为一个主体发送,我们最后收到之后才做近一步解析,所以就以test.rar|267941这样的方式发送,这样就不必再因为和前面的“/”的解析发生冲突,而近一步解析为文件名和大小就类似前面,问题一下子就解决了。

    总之一点,那就是很多时候换一种方式想问题,从整体到局部,从大到小,问题往往得到很好的解决。

    最后,还是说一下,开发项目很多时候代码也不是看得很懂,如果以后真的想往这些方向走的话,还是要注重代码的理解,但不懂不代表不可以做实战项目,整体上我们学会了,细节出问题的时候我们也能及时解决,这并不影响我们开发实战项目。做项目是需要及时总结和领会的,也是一条漫长的道路,需要及高难度的耐性和充沛的精力。

     

    展开全文
  • 个人在linux下用GTK写的模仿QQ聊天程序,包含客户一个服务器一个客户端,有私聊,发送系统消息,聊天记录,发送文件,发送电子邮件,用到的知识:C/C++,GTK,MYSQL,SOCKET,多线程,本程序仅用于学习交流,站在...
  • 编写qq刷屏软件

    2016-07-10 21:07:00
    使用pywin32,模仿按键操作“control+v”把内容复制到QQ的聊天窗口上,然后“enter”发送消息。 文件读取,把要刷屏的语言保存在本地的shuaping.txt中,一次性读取到列表中。然后一条一条的发送完成刷屏。 参考: ...
  • 1.实现了系统托盘的功能,来消息闪烁提示,点击打开聊天窗口,与原版QQ功能相近。 2.实现了当聊天窗口打开时,来消息自动跳至桌面顶端,同时托盘不再闪烁提示。 3.模仿消息盒子提示,当打开消息盒子开关时,所有将...
  • QQ(Android)v1.0

    2015-01-22 17:50:45
    MingQQ的界面模仿了AndroidQQ的基本功能,虽然体验性完全比不上QQ,但目前技术有限,只能做到现在这水平了,更好的界面用户体验留待以后再提升吧。 下拉刷新目前使用了第三方开源库Android-PullToRefresh,以后再...
  • QQ消息,电脑语音等等,其实这些有时候都没电话方便,电话也有他存在的道理,其实可以使劲打,一个月顶多两三百元的电话费,而且我最近也感受到了一个事情,相对而言电话费越多的人越是成功一些的人,电话费越少的,...
  • 这个项目做得比较早,当时是基于ionic1和angular1做的。做了四个tabs的app,首页模仿携程首页,第二页主要是phonegap调用手机核心功能,第三页模仿微信和qq聊天页,第四页...有二维码扫描功能,还做了类似qq消息可...
  • php网页聊天室源码

    2014-06-03 12:29:56
    仿QQ群在线聊天系统采用先进的数据传输原理,模仿QQ群界面。支持几千人同时在一个群里聊天交流,具有安全、快速、安全、稳定等特点 基本功能: ·仿QQ群聊天大厅(主要功能) ·群共享功能 ·好友功能,可在线...
  • 第二次作业

    2016-03-05 15:12:00
    QQ以前是模仿ICQ来的,是国际的一个聊天工具,后被指侵权,于是改名字为qq。早期qq因为捆绑tt浏览器被用户各种诟病,出现了各种qq第三方客户端。1999年2月腾讯公司即时通信服务开通,与无线寻呼、GSM短消息、IP电话...
  • 目前客户端程序的界面完全模仿腾讯的QQ。 基本功能特点 --------------- 1) 收发(离线)消息(如果客户端之间能直接通讯,则通过UDP协议发送,否则通过服务器中转) 2) 添加/删除好友(可以设置身份验证) 3) 服务器端...
  • C#聊天小软件(终结版,含源码)

    热门讨论 2009-05-31 08:44:41
    服务器端还可以给所有在线用户发送系统消息。 总代码一万两千多行(不包括系统生成的代码),其中客户端一万多行。 运行时需加载数据库,SQL2005;同时需把客户端的ServerIP.txt文件中的IP与服务器开通的IP一致;...
  • 系统消息: 定时投放一些广告,发通知等,形式可以丰富多样,图文并茂。 邮箱提醒: 新邮件提醒,一键登录。 网络硬盘: 随时上传个人资料,不会因为换电脑丢失。 超级换肤功能: 随便找张图片往软件上一拖,就是...
  • 微型博客,又叫“微博客(micro-bloging)”,是一种迷你型博客,是一种可以即时发布消息的类似博客的系统,它最大的特点就是即时性和随意性,你可以通过电脑、手机、IM软件(gtalk、MSN、QQ、skype)等途径,随时随地向...
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知给由recipient参数确定的e-...
  • java 一个消息发布网站.rar Java 数字签名、数字证书生成源码.rar Java 版的酒店系统,貌似完整.rar Java 电梯模拟程序 v2.0.rar Java 组播组中发送和接受数据实例 Java 飞机订票.rar Java 高考信息管理系统 SQL...
  • vc++ 开发实例源码包

    2014-12-16 11:25:17
    老版qq系统的实现。 MyIE3.0浏览器源代码 如题。完整的代码,重载控件实现,非常适合初学者。 MyPhpServer(原创,有实现的主要代码) 如题。 microcai-ibus-t9-输入法源码 如题,主要源码就几个,详细见代码。 ...

空空如也

空空如也

1 2 3 4
收藏数 61
精华内容 24
关键字:

模仿qq系统消息