正在阅读:QQ窗体自动隐藏效果探究QQ窗体自动隐藏效果探究

2005-04-18 14:14 出处: 作者:cobi 责任编辑:huangpeidan

  在新的代码中,我们首先使用了三个新定义的全局变量,分别是:

Lst_Height : Integer;   //记录窗体隐藏前的高度
Lst_Width : Integer;        //记录窗体隐藏前的宽度
Rec_Position : Boolean; //是否启动窗体宽高记录标志

  然后加入了三个判断代码块。

  在第一个判断中首先判定窗体在移动前是否位于屏幕左右两边的隐藏区域。若为真,则判断窗体是否从隐藏区域向屏幕中央移动(注意,存在此判断的原因是因为我们还可能将窗体往屏幕两边推动)。若再为真,则恢复窗体隐藏前的大小;反之,强制设置矩形的Top和Bottom值并退出消息的处理。

  第二个判断在于记录窗体的宽高值。Rec_Position是记录窗体宽高的标志,它的值在第三个判断中进行设置。若窗体在移动前位于屏幕两边的隐藏区域,则Rec_Position为True,此时窗体的高度已经固定,记录已经无意义。所以只在Rec_Position为False时才需要记录窗体的宽高。

  第三个判断位于Fanchors值设置之后。它根据窗体的位置对矩形的显示效果进行判断处理。判断也是基于窗体是否位于屏幕两边进行,为True则设置矩形的高度并设置Rec_Position的值为True。

  在第三个判断中使用了一个新定义的过程SetBarHeight,其代码如下:

procedure TForm1.SetBarHeight;
var
  AppBarData : TAPPBARDATA;
begin
  AppBarData.cbSize := SIZEOF(AppBarData);
  If SHAppBarMessage(ABM_GETSTATE,AppBarData) AND ABS_AUTOHIDE) <> 0 then
  begin
    Cur_Top := 1;
    Cur_Bottom := Screen.Height - 1;
  end else
  begin
    SHAppBarMessage(ABM_GETTASKBARPOS,AppBarData);
    case AppBarData.uEdge of
      ABE_TOP :    begin
                     Cur_Top := AppBarData.rc.Bottom + 1;
                     Cur_Bottom := Screen.Height - 1;
                   end;
      ABE_LEFT :   begin
                     Cur_Top := 1;
                     Cur_Bottom := Screen.Height - 1;
                   end;
      ABE_RIGHT :  begin
                     Cur_Top := 1;
                     Cur_Bottom := Screen.Height - 1;
                   end;
      ABE_BOTTOM : begin
                    Cur_Top := 1;
                     Cur_Bottom:=Screen.Height -(AppBarData.rc.Bottom - AppBarData.rc.Top) - 1;
                   end;
    end;
  end;
end;

  SetBarHeight用于计算矩形高度,计算后的结果通过Cur_Top和Cur_Bottom两个全局变量给传递矩形的Top和Bottom参数。

  在该过程中使用了一个Windows API函数SHAppBarMessage。SHAppBarMessage的作用是向系统传递系统工具栏消息,其函数原型为:

WINSHELLAPI UINT APIENTRY SHAppBarMessage(DWORD dwMessage,   PAPPBARDATA pData);

  其中dwMessage是发送给系统的工具栏消息;pData是指向PAPPBARDATA结构的指针,PAPPBARDATA结构返回的内容依据发出的消息而定。

  在过程中,我们首先传递ABM_GETSTATE参数去获取系统工具栏的状态是自动隐藏还是总在最前显示。然后我们再利用ABM_GETTASKBARPOS参数去获取系统工具栏的位置,此时AppBarData的返回值中将会是系统工具栏的位置ABE_TOP、ABE_LEFT、ABE_RIGHT、ABE_BOTTOM四者之一。最后我们利用系统工具栏自身的拖动矩形参数计算出工具栏的高度。

  使用了SetBarHeight令窗体在屏幕两边随系统工具栏的位置和高度的改动而发生相应的变化。当然,你也可以直接给Cur_Top和Cur_Bottom这两个变量设置固定值以实现QQ效果。在测试中,Cur_Top可以是1,而Cur_Bottom则是Screen.Width – 30(Windows系统工具栏的高度在默认情况下是30,这是不随分辨率改变的)。

  由于要使窗体在屏幕两边的高度与位置可以随系统工具栏的位置和高度的改动而发生相应的变化,因此OnTimer事件中的处理也要相应的改动,主要是显示窗体的时候要注意对窗体Top和Height属性的设置必须跟随与系统工具栏的位置和高度相协调,代码如下:

……
    if akLeft in FAnchors then
    begin
      Left := -Width + cOffset;
      SetBarHeight;
      Top := Cur_Top;
      Height := Cur_Bottom;
    end;
    if akRight in FAnchors then
    begin
      Left := Screen.Width - cOffset;
      SetBarHeight;
      Top := Cur_Top;
      Height := Cur_Bottom;
    end;
……

  最后,为了保证窗体在屏幕两边隐藏后高度保持不变,我们再添加一个WMSizing过程对WM_Sizing消息进行拦截处理。WMSizing过程的代码如下:

procedure TForm1.WMSizing(var Msg: TMessage);
begin
  inherited;
  if (akRight in FAnchors) then
  begin
    with PRect(Msg.LParam)^  do
    begin
      Left := Screen.Width - Width;
      Top := Cur_Top;
      Right := Screen.Width;
      Bottom := Cur_Bottom
    end;
  end else if (akLeft in FAnchors) then
  begin
    with PRect(Msg.LParam)^ do
    begin
      Left := 0;
      Top := Cur_Top;
      Right := Width;
      Bottom := Cur_Bottom;
    end;
  end;
end;

  WM_Sizing消息的语法结构与WM_MOVING消息相似,也包含了一个对矩形的指针。通过该指针我们可以对矩形的Top、Left、Right和Bottom参数进行设置,从而保证矩形高度不受用户操作影响。

  至此,一个窗体自动隐藏的程序就基本完成了,其实际效果已经和QQ相当接近了。当然,从实际运行效果看还存在着一些小瑕疵,并且代码中并没有对窗体在隐藏后的宽度设置上进行处理,或者大家可以考虑继续进行完善此程序。

键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品