zoukankan      html  css  js  c++  java
  • 悬浮窗口(智能隐藏和显示)的一种实现方案

    悬浮窗口应该具有的特性

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

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

    上述特点的实现方案

    整个实现方案依赖于主窗口内的一个定时器(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

  • 相关阅读:
    Win10桌面点右键一直卡顿转圈怎么解决
    Ubuntu 中检查笔记本 CPU 的温度
    aria2的安装与配置
    Downloading Vim
    如何在Ubuntu 18.04上安装Python 3.8
    理解 chroot
    Ubuntu快捷方式存放的位置
    安装ubuntu双系统后,找不到windows启动项的解决方法
    socks5 协议简介
    mybatis源码1.3 MapperMethod
  • 原文地址:https://www.cnblogs.com/findumars/p/5460101.html
Copyright © 2011-2022 走看看