Delphi下QQ窗体自动隐藏探索

Delphi下QQ窗体自动隐藏探索,第1张

Delphi下QQ窗体自动隐藏探索,第2张

首先,提出的问题

熟悉QQ使用的朋友都知道,当QQ表单区域超过屏幕四边时,表单会自动“消失”,只剩下表单一面的一小部分暴露在桌面上。当您将鼠标移动到暴露的部分时,表单将再次完全显示在隐藏位置;但是,当鼠标离开表单区域时,表单将再次隐藏。

通过分析隐藏的整个过程,可以得出两个猜想:第一,窗口隐藏的处理与窗口的移动过程有关;第二,表单隐藏的触发条件。

第一种猜测可以通过拦截窗体移动时生成的Windows消息来实现。至于第二种推测,如何表达“窗体区域已超出屏幕可视范围”这一条件,是其实现的关键。

二、基本分析

我们先来关注一下Windows移动的过程和效果。当用鼠标移动窗体时,窗体本身并不会随着鼠标的移动而立即改变位置;相反,鼠标拖动的是一个与表单大小相同的透明区域(具体来说,是一个带虚线边框的矩形),如图1所示。当鼠标释放矩形时,窗体本身会出现在矩形的最后一站,从而完成整个移动过程,如图2所示。(注意:在Windows 2000和XP环境下,如果在显示属性中选择了“拖动时显示表单内容”的显示效果选项,则无法观察到上述过程。)


对于QQ表单,其移动过程同上,但有一点不同。当我们将矩形移动到屏幕的四边,并且它的一部分已经超出时,矩形将自动停留在超出的位置,并被完整显示。此时,无论我们如何尝试在beyond方向上移动矩形,矩形都只会保持在那个位置,如图3所示。当释放鼠标时,表单的隐藏效果出现,如图4所示。


从上面的过程可以推断,隐藏条件被触发后,矩形本身即使还在移动的过程中也已经被锁定了,所以窗体位置的判断就发生在移动的过程中,也就是说我们要拦截和处理的Windows消息是WM_MOVING。其次,在移动的过程中,首先改变位置的是矩形,而不是形体本身。因此,隐藏的关键是判断和设置矩形参数。

我们可以先关注一下WM_MOVING消息的语法结构:

WM _ moveing
WPARAM WPARAM
LPARAM LPARAM,

其中,没有使用WPARAM,而LPARAM是一个指向RECT结构的指针。RECT结构包含四个参数,左、上、右和下,用于描述矩形的左上角和右下角。" rect记录窗体相对于屏幕的当前位置;当你想改变拖动矩形的位置时,程序本身必须改变rect结构中每个成员变量的相关值”。所以我们可以看到,我们要处理的矩形其实已经在WM_MOVING消息中提到了,我们要处理的是LPARAM指向的rect结构的相关参数。

接下来,我们将设置一个由隐藏条件激活的计时器,以监视鼠标相对于表单的位置。因为隐藏窗体的隐现是由鼠标激活的,如果在窗体上方检测到鼠标,就意味着窗体处于显示状态;反之,形式是隐藏的。我们只需要在相关判断下添加表单的Top和Left属性的赋值,就可以实现若隐若现的效果。

至此,自动隐藏效果的实现分析基本完成。但是需要注意的是,我们在WM_MOVING消息的拦截中判断隐藏条件,通过定时器的OnTimer事件来处理隐藏效果。这一隐含条件是否得到满足,将是这两个过程中传递的关键。同时,我们不仅需要知道是否满足隐藏条件,还需要知道表单隐藏在屏幕的哪一侧。为此,我们需要定义一个集合来描述表单的隐藏位置,例如:

type
HidePosKind = (hpTop,hpLeft,hPBottom,HP right);
type
THidePos = HidePosKind的集合;

然而,类似的集合在Delphi中已经存在,比如TAnchors集合。TAnchors集最初用于指示控件如何锚定到其父控件的位置。这里,我们借用它来描述窗体对屏幕的隐藏位置。

TAnchors集合还包含四个值,定义如下:

type TAnchorKind = (akTop,akLeft,akRight,AK bottom);
type tan chors = tan chor kind的集合;

在代码的实现中,我们将定义一个TFAnchors类型的全局变量来描述表单的隐藏位置。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » Delphi下QQ窗体自动隐藏探索

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情