悬浮窗口(智能隐藏和显示)的一种实现方案

悬浮窗口应该具有的特性

为了实现让用户能方便打开软件主窗口,又不对用户界面造成明显的视觉干扰,悬浮窗口应该有以下特点:

  • 和主窗口是二选一的关系,主窗口显示时自动隐藏,主窗口被全部遮挡时自动显示
  • 始终置前,不被其它窗口遮挡,全屏播放电影、截图软件截图等情形时,取消置前。
  • 支持全窗口拖动
  • 半透明效果,鼠标移上时全为不透明
  • 为了使隐藏和出现不显得突兀,支持淡入淡出效果
  • 点击悬浮窗时,呼出主窗口,并隐藏悬浮窗口

上述特点的实现方案

整个实现方案依赖于主窗口内的一个定时器(200ms),定时检查主窗口的显示状态以及悬浮窗口的顶置属性。

和主窗口是二选一的关系,主窗口显示时自动隐藏,主窗口被全部遮挡时自动显示

与主窗口二选一的显示,是通过定时检查主窗口的显示状态,来设置是否显示悬浮窗口。
如果主窗口未隐藏,并且没有被其它窗口完全遮挡(可以是一个或者多个窗口的组合),悬浮窗口不显示。

IsEntirelyCovered(HWND hWnd)(http://blog.csdn.net/harbinzju/article/details/6781646)函数可以判断一个窗口,是否被完全遮挡住,可能是被一个或者多个窗口遮挡。
实现思路:向上找到Z-Order大于目标窗口的窗口,将这些窗口逐一拼接,每拼接一个窗口后,判断一下目标窗口是不是被这个拼接后的区域覆盖。
这里用到的CRgn来自WTL的atlgdi.h,MFC中也有相似的类,都是对API的一个封装。

始终置前,不被其它窗口遮挡,全屏播放电影、截图软件截图等情形时,取消置前。

这个功能的实现同样依赖于主窗口的定时器,当定时器触发时,发现主窗口未显示,会调用悬浮窗的显示窗口方法,这里会重新设置置前属性。
在设置置属性之前,要判断是否有其它全屏的置前窗口遮挡了悬浮窗,如果有,不再去抢置前。这样就可以避免与截图和全屏播放电影冲突。
实现思路:向上找到Z-Order大于悬浮窗口的窗口,判断这个窗口是否为全屏。
IsFullScreen(HWND hWnd)函数可以判断窗口是否为全屏。

BOOL IsFullScreen(HWND hWnd)
{
    if (hWnd == NULL)
    {
        return FALSE;
    }

if (!::IsWindowVisible(hWnd))
    {
        return FALSE;
    }

int nScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);

CRect rcWnd;
    GetWindowRect(hWnd, &rcWnd);

if (rcWnd.top == 0 && rcWnd.left == 0 
        && rcWnd.Width() == nScreenWidth
        && rcWnd.Height() == nScreenHeight)
    {
        return TRUE;
    }

return FALSE;
}

支持全窗口拖动

窗口响应WM_NCHITTEST消息,固定返回HTCAPTION。

半透明效果,鼠标移上时全为不透明

设置WS_EX_LAYERED属性,使用UpdateLayeredWindow来绘制窗口。因为悬浮窗口一般比较简单,没有复杂的控件,甚至没有控件,所以此方案比较简单可行。
当鼠标移入和移出时,调用SetLayeredWindowAttributes来改变悬浮窗的透明度。

为了使隐藏和出现不显得突兀,支持淡入淡出效果

实现思路:开始淡入\淡出时,启动定时器(30ms),定期增加\减少窗口透明度,当增加至1(或者预设的最大透明度)\减小到0时,停止定时器。

http://blog.csdn.net/harbinzju/article/details/7022882

时间: 05-03

悬浮窗口(智能隐藏和显示)的一种实现方案的相关文章

js设置控件的隐藏与显示的两种方法

js设置控件的隐藏与显示,设置控件style的display和visibility属性就可以了,下面有个示例,需要的朋友可以参考下用JavaScript隐藏控件的方法有两种,分别是通过设置控件的style的“display”和“visibility”属性.当style.display="block"或style.visibility="visible"时控件或见,当style.display="none"或style.visibility=&qu

css鼠标悬浮控制元素隐藏与显示

在网页开发中经常有需求是鼠标移动到一个元素A身上时,另外一个元素B显示. 如下图 当鼠标移到图片上时,相关的描述从下方显示出来. css实现原理与情景: A 是 B 的父元素 B 默认隐藏 B{opacity:0,transition: all 0.3s: transform: translateY(100%)} 当鼠标在A上时,即 A:hover状态,B显示 css实现即 A:hover B{opacity:1,translateY(0)} 示例代码: html <li class="r

jquery控制元素的隐藏和显示的几种方法。

组织略显凌乱,请耐心看! 使用jquery控制div的显示与隐藏,一句话就能搞定,例如: 1.$("#id").show()表示为display:block, $("#id").hide()表示为display:none; 2.$("#id").toggle()切换元素的可见状态.如果元素是可见的,切换为隐藏的:如果元素是隐藏的,则切换为可见的. 3.$("#id").css('display','none');//隐藏 $(

鼠标滑过时显示图片内容隐藏和鼠标滑过图片隐藏内容显示的两种小方法

1.鼠标滑过时显示图片,内容隐藏,下面以一个小日历的做法展示 <div class="date7"> <a href=""><div class="date7a"><span class="abcabc">30</span></div></a> <a href=""><div class="dat

[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

原文:[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 周银辉 现象: 大家可以试试下面这个很有趣但会带来Defect的现象:当我们将子窗口按照ShowDialog()的方式显示出来的时候,很明显该窗口是模式化的(即主窗口等待该窗口的返回,主窗口将不相应用户输入),但如果此时将子窗口的Visibility设置成Visibility.Hidden来隐藏窗口,然后再将Visibility设置成Visibility.Visible来

MFC 工具栏隐藏与显示

最近在学MFC,看的是孙鑫的VC++视频,感觉还不错.在看到第九节课的时候,讲到工具栏的时候,做了个小功能:工具栏的隐藏和显示,但是有个bug就是一个悬浮的工具栏隐藏后再显示,就会变成停靠状态.这里我又把工具栏的隐藏与显示又实现了一遍,去掉了这个bug,做到跟MFC中自带的菜单栏中视图->工具栏菜单项一样的功能. 其实,关于工具栏的隐藏与显示问题,只需要考虑三种状态:(1)在停靠状态下工具栏的显示与隐藏:(2)在悬浮状态下工具栏的显示与隐藏:(3)在悬浮状态下,通过点击关闭按钮去关闭工具栏,然后

WindowManager和WindowManager.LayoutParams的使用以及实现悬浮窗口的方法

写Android程序的时候一般用WindowManager就是去获得屏幕的宽和高,来布局一些小的东西.基本上没有怎么看他的其他的接口. 这两天想写一个简单的类似于Toast的东西,自定义布局,突然发现,原来Toast的时间是不能自己定义的,只有两个固定的时间,分别是2秒和3.5秒.我的需求是自定义显示的时间,这个显然不能满足我的需求.但是它是如何做到显示一个View凌驾于现有的所有的View之上的呢? 我们Android平台是一个又一个的Activity组成的,每一个Activity有一个或者多

Atitit. 悬浮窗口的实现 java swing c# .net c++ js html 的实现

Atitit. 悬浮窗口的实现 java swing c# .net c++ js html 的实现 1. 建立悬浮窗口引用代码 1 1.1. 定义悬浮窗口,设置this主窗口引用,是为了在悬浮窗口中双击可缩小还还原主窗口.以及悬浮窗口右键菜单"显示主界面"中需要还原主窗 1 1.2. //设置主窗口关闭时,先关闭悬浮窗口.and系统托盘 1 1.3. 注入系统托盘图标,退出的时候儿也退出系统托盘 2 2. 悬浮窗口结构and重大的点 2 2.1. 要去掉标题栏: 2 2.2. Opa

如何用C#做一个悬浮窗口程序

用C#做一个像FlashGet的悬浮窗口,其实很简单,不像以前需要调用很多系统API.大致的步骤如下. 首先是主窗体部分,即要判断窗体的状态来决定是否显示悬浮窗口. 局部成员声明: private FormWindowState fwsPrevious; private frmTopMost myTopMost; 主窗体的Load事件: private void frmMain_Load(object sender, System.EventArgs e) { // Save window st