转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
QQ窗体自动隐藏效果探究         ★★★★

QQ窗体自动隐藏效果探究

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2515 更新时间:2009/4/23 18:26:52
   if akRight in FAnchors then Left := Screen.Width - Width;

   if akBottom in FAnchors then Top := Screen.Height - Height;

 end else

 begin

   if akLeft in FAnchors then Left := -Width + cOffset;

   if akTop in FAnchors then Top := -Height + cOffset;

   if akRight in FAnchors then Left := Screen.Width - cOffset;

   if akBottom in FAnchors then Top := Screen.Height - cOffset;

  end;

end;

在这里,我们首先定义一个常量cOffset去表示窗体隐藏后显露部分的大小。然后我们利用WindowFromPoint这个Windows API函数检测鼠标是否位于窗体之上。接下来的判断就是处理在显示和隐藏状态下窗体Left和Top属性值的设置。注意,针对Fanchors中存在不同值的情况,窗体Left和Top的设置是各不相同的,但是这些设置只有顺序上的差异而并没有优先级别的差异。(为什么要提到这一点呢?)

最后需要注意的是:在本事件中Top、Left、Width和Height都是窗体Form1的属性值。

好了,有关窗体隐藏的核心代码已经介绍完毕了,不过要达到预期效果,窗体Form1在创建时还必须做一些准备工作,代码如下:

procedure TForm1.FormCreate(Sender: TObject);

begin

  Timer1.Enabled := False;

  Timer1.Interval := 200;

  FormStyle := fsStayOnTop;

end;

这里的代码相对简单,不过值得指出的是对Form1的FormStyle属性的设置。FormStyle为fsStayOnTop时可保证了Form1始终位于最前显示。从效果角度看,当系统工具栏为“总在最前显示”时是最为明显的,因为若窗体移动到系统工具栏上时也不会被其所遮盖。

四、进一步完善

上面的代码已经基本实现了窗体的自动隐藏效果,但是我在介绍代码的时候有两个问题是被提出但没有被解答的。

首先是为什么触发隐藏时Fanchors中将至少有一个值而不多于两个值呢?注意代码中对Fanchors的赋值是通过四个判断进行的,那么如果触发隐藏的话,Fanchors中将毫无疑问会有一个值存在,但这种情况是针对隐藏发生在屏幕的四边而言。当窗体被推入到屏幕的四角时,那么Fanchors中便将会有两个值存在。那此时窗体会隐藏到什么地方呢?

实际的效果告诉我们,窗体会被隐藏到屏幕的四角上。此时若我们试图让窗体重新显示,你便会发现窗体在不断的闪烁。为什么呢?这就是第二个问题提出的原因了。因为对窗体显示或隐藏的处理是根据Fanchors中的值作出的。当Fanchors中有两个值的时候,就将会引发对窗体属性的两次设置。而因为设置语句只有顺序差异而没有优先级差异,那么OnTimer事件中每次都会对窗体进行两次的属性值设置,从而导致我们看到闪烁的显示效果。

怎么去解决这个问题呢?我们再观察一下QQ的处理。在2003 II版的QQ里面,窗体的隐藏效果作了一定的调整:当窗体在屏幕左右两边隐藏时,它会自动充满屏幕的左右两边且高度不可改变;当窗体脱离屏幕两边的隐藏区域后,窗体的大小会恢复为隐藏前的大小。(注意:窗体并非是完全充满屏幕的两边。QQ在处理这个效果时可能只注意了系统工具栏总在最前显示且位于屏幕下方的情况,所以其充满的区域也只是屏幕顶端到系统工具栏上方的一段空间。)这样的处理可以令窗体即使被推入到屏幕四角,也可以保证只会对其中的一个隐藏方向进行处理,从而避免了前面出现的闪烁现象。

结合前面的分析,要实现如上的效果还是从拦截WM_MOVING消息入手。重写后的WMMOVING过程如下:

procedure TForm1.WMMOVING(var Msg: TMessage);

begin

 inherited;

 with PRect(Msg.LParam)^ do

 begin

   if (akLeft in FAnchors) or (akRight in FAnchors) then

   begin

     if (Left > 0) and (Right < Screen.Width) then

     begin

       if rec_Position then

       begin

         Bottom := top + Lst_Height;

         Right := Left + Lst_Width;

         Height := Lst_Height;

         Width := Lst_Width;

       end;

     end else

     begin

       SetBarHeight;

       Top := Cur_Top;

       Bottom := Cur_Bottom;

       exit;

     end;

   end;

 

   Left := Min(Max(0, Left), Screen.Width - Width);

……

 

   if not Rec_Position then

   begin

     Lst_Height := form1.Height;

     Lst_Width := form1.width;

   end;

 

   FAnchors := [];

……

 

   if (akLeft in FAnchors) or (akRight in FAnchors) then

   begin

     Rec_Position := True;

上一页  [1] [2] [3] [4]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台