• 如何让窗口控件半透明(控件在Paint自己时,首先向主窗口询问,获取主窗口上控件所在区域的背景图)


    在网上关于窗口视觉效果,有2个问题被问得最多:
    第一个是如何让窗口边框有阴影效果?
    第二个是如何让窗口控件有半透明效果?

    对于第一个问题,我们的答案是用双层窗口模拟或是用Layered Window。
    在XP下可以直接在注册窗口类时用CS_DROPSHADOW风格,系统就会自动让你的窗口附加上阴影效果,实际上系统也是通过双层窗口来实现的;当然我们也可以用自己的窗口来模拟阴影效果,只要让阴影窗口永远跟随我们的目标窗口就可以了。
    如果用Layered Window, 我们只要一个窗口,通过让窗口支持Alpha通道,最后UpdateLayeredWindow, 即可实现阴影效果。

    对于第二个问题,我们通常的答案是用双层窗体或是DirectUI。
    因为Windows绘画是以DC为单位,而主窗口和内部控件是居于不同的DC, 所以他们不能半透明融合在一起。
    另外只有Pop up的窗口才能支持Layered Window,所以只有Pop up的窗口才能实现半透明效果,所以我们通常用双层窗口来模拟控件的半透明,也就是说窗口上面的控件其实是通过一个Pop up窗口模拟出来的。所以用这种方式实现控件的半透明效果,性能比较差,也只能实现一些简单的界面。
    还有一种控件半透明的方式是用DirectUI,所有的窗口控件都通过在主窗口上绘画模拟出来,实现半透明效果自然也很容易了。

    所以既要实现窗口的阴影效果,又要让内部控件半透明,最终极的方式还是用WS_EX_LAYERED风格的DirectUI窗口。

    其实另外还有一种既不用DirectUI,也不用双层窗口,也能实现控件半透明的方法。
    该方法的关键是控件在Paint自己时,首先向主窗口询问,获取主窗口上控件所在区域的背景图,然后控件先将此背景画到自己的DC上,然后在再画自己,这样可以让控件看起来像是直接画在主窗口上一样。
    当然该方法也只能针对一些简单的UI,如果子窗口层次很多,或是控件个数很多,都会有性能影响。

    核心代码如下:

    HBRUSH AtlGetBackgroundBrush(HWND hWnd, HWND hwndParent)
    {
       CWindow wnd = hWnd;
       CWindow wndParent = hwndParent;
       CClientDC dcParent = wndParent;
       CRect rcParent;
       wndParent.GetWindowRect(&rcParent);
       CDC dcCompat1;
       dcCompat1.CreateCompatibleDC(dcParent);
       CBitmap bmpCompat1;
       bmpCompat1.CreateCompatibleBitmap(dcParent, rcParent.Width(), rcParent.Height());
       HBITMAP hOldBmp1 = dcCompat1.SelectBitmap(bmpCompat1);
       wndParent.SendMessage(WM_PRINTCLIENT, (WPARAM) (HDC) dcCompat1, (LPARAM)(PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT));
       CRect rcWin;
       wnd.GetWindowRect(&rcWin);
       CDC dcCompat2;
       dcCompat2.CreateCompatibleDC();
       CBitmap bmpCompat2;
       bmpCompat2.CreateCompatibleBitmap(dcCompat1, rcWin.Width(), rcWin.Height());
       HBITMAP hOldBmp2 = dcCompat2.SelectBitmap(bmpCompat2);
       CRect rcSnap = rcWin;
       ::MapWindowPoints(NULL, wndParent, (LPPOINT) (LPRECT) &rcSnap, 2);
       dcCompat2.BitBlt(0, 0, rcWin.Width(), rcWin.Height(), dcCompat1, rcSnap.left, rcSnap.top, SRCCOPY);
       HBRUSH hBrush = ::CreatePatternBrush(bmpCompat2);
       dcCompat1.SelectBitmap(hOldBmp1);
       dcCompat2.SelectBitmap(hOldBmp2);
       return hBrush;
    }


    下面是一个简单的Demo:


    Demo源代码: TransparentControl Demo

    注:Demo上的文字因为是直接用GDI画的,所以没有支持Alpha通道

    http://www.cppblog.com/weiym/archive/2012/08/23/187998.html

  • 相关阅读:
    C#图片存到资源文件,以及调用图片
    error C2039: “create”: 不是“cocos2d::GLView”的成员,出错解决办法
    error LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1600”不匹配值“1800”
    vs2013激活码
    AppDelegate.h文件
    AppDelegate.cpp文件详解
    【最终版】Cocos2d-x&JS v3.7 发布!
    cocos2d-x 3.0 示例代码分析3:BaseTest
    vue li click
    me
  • 原文地址:https://www.cnblogs.com/findumars/p/5803853.html
Copyright © 2020-2023  润新知