[仿QQ聊天工具系列一]关于停靠屏幕边缘时自动隐藏窗体的研究

      虽说腾讯公司的很多软件和游戏都是“参考”他人的,但它凭借着它庞大的用户量可以将该“山寨”版软件变成“官方”版,估计这是腾讯公司的一种战略方针,只要它拥有这么多的用户和资金,它就可以打垮这些软件归属的所谓的“官方”公司。不是每家公司都能做的像腾讯这么成功的,虽说我不是很苟同它的一部分“参考”文化,但它的成功是不可否认的。当然腾讯公司也有自己的创新,而且有些方面做的比所谓的“官方”软件好的多,如QQ就不必说了,还有QQ影音等等很多软件,虽然有些技术比不上其他公司的软件,但在用户体验方面做得非常好。用户体验是一款面向大众的好软件应该重点关注的方面,如果一款技术含量很高的软件,用户体验做得很糟糕,相信也不会有太多人想用。

      说了那么多,现在换我们来“参考”腾讯的聊天软件——QQ ,网上已经有很多高手做过聊天工具,但那个毕竟是别人的东西,想要进步还是得自己慢慢研究,加上一些的参考。写该文章只是希望记录下自己的研究足迹,高手莫拍砖,有错的地方也希望能指出,有什么需要改进的地方希望能指点,新入门的同志也可以多一份参考的资料。

      其实这个功能实现起来比较简单,只是有一些细节方面容易忽略而导致效果不是很好。在实现功能之前先把几个概念搞清楚,并且把一些关键的地方总结一下,并把坐标系统一:

1.窗体的客户区域(this.ClientRectangle):对于WinForm的窗体,窗体的客户区域是除掉窗体边界之后剩下的那部分区域,亦即将FormBorderStyle属性设置成None时所剩下的那部分。可以用Rectangle formRect=this.RectangleToScreen(this.ClientRectangle)来将this.ClientRectangle区域的Location属性的坐标系转换成屏幕坐标系,并用formRect来存储相对于屏幕坐标系的窗体客户区域。

2.客户区坐标系:该坐标系是以客户区的左上角为原点,是相对于客户区的逻辑坐标,可以用Point clientPoint=this.PointToClient(Point p)来将p坐标转换成客户区坐标系的坐标并返回给clientPoint。

3.屏幕坐标系:该坐标系是以显示屏的左上角为原点,是相对于屏幕的绝对坐标,可以用Point screenPoint=this.PointToScreen(Point p)来将p坐标转换成屏幕坐标系的坐标并返回给screenPoint。

4.获取鼠标光标的坐标:如果是鼠标事件中的话可以用e.Location来获取,其他情况可以用Cursor.Position或者Control.MousePoint来获取,经实验表明这几个属性获取的坐标都是相对于屏幕坐标系的,当然如果不放心可以用this.PointToScreen(Point p)方法将其转换成相对于屏幕坐标系的坐标

5.需要用到的事件:MouseMove鼠标事件,Move窗体事件,MouseLeave窗体事件,注意:MouseMove鼠标事件和MouseEnter窗体事件类似,都是进入窗体客户区才触发事件,窗体边界不属于窗体客户区,所在鼠标在边界处是无法触发事件的。对于MouseLeave窗体事件,如果鼠标移动到了窗体边界(如上所述边界不属于客户区),则相当于鼠标离开了窗体,则会触发该事件,如果窗体中有其它控件,则当鼠标移动到这些控件的时候也相当于鼠标离开了窗体,也会触发该事件,所以要考虑相应的情况来设置鼠标在一定范围内时不隐藏窗体,当鼠标离开该范围时且窗体this.Top等属性值小于某个值时,窗体可以自动隐藏。

6.无边界窗体和有边界窗体:QQ程序是无边界的,因此才可以做一些皮肤界面效果,对于无边界窗体,它是不可以拖动和改变大小的,除非自己定义事件来完成这些功能,这次研究的自动隐藏的窗体是有边界的(this.FormBorderStyle=FormBorderStyle.Sizable)。

7.定义自动隐藏枚举类型:

 internal  enum ShrinkType:byte
    {
        ShrinkNone=0,
        ShrinkTop,
        ShrinkBottom,
        ShrinkLeft,
        ShrinkRight
    }
本文只展示停靠屏幕上方时自动隐藏窗体,当鼠标移到该隐藏的窗体边缘时又会自动显示窗体,鼠标移开时又会自动隐藏窗体。屏幕其它方向的可类似实现。

下面为实现该功能的代码:     

       private void MainForm_Move(object sender, EventArgs e)
        {     
            if (this.Top == 0 )
            {
                this.Top = -this.Height+10;
                this.mShrink = ShrinkType.ShrinkTop;
            }          
        }

        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
           
            switch (mShrink)
            {
                case ShrinkType.ShrinkTop:
                    {                      
                        this.Top = -2;                        
                        this.mShrink = ShrinkType.ShrinkNone;
                        break;
                    }
                default: break;
            }
        }

        private void MainForm_MouseLeave(object sender, EventArgs e)
        {
            if (ShrinkType.ShrinkNone==mShrink)
            {
                        if (this.Top <= 5)
                        {
                            Rectangle formRect =this.RectangleToScreen(this.ClientRectangle);
                            Point mousePoint = Cursor.Position;//Control.MousePosition;
                            if (mousePoint.Y<=formRect.Location.Y)
                            {
                                this.Top = -2;
                                return;
                            }
                            else if (mousePoint.X<=(formRect.Location.X-2)||mousePoint.X>=(formRect.Location.X+formRect.Width+2)||mousePoint.Y>=(formRect.Location.Y+formRect.Height+2))
                            {
                                this.Top = 0;
                            }
                        }
            }             
                 
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值