zoukankan      html  css  js  c++  java
  • 实现控件的透明背景

    很多情况下,我们需要控件的背景是透明的,就是要求直接看到控件父窗口的背景颜色、背景位图,比如标签控件、单选Radio控件、复选Check控件,通常都要求在父窗口的背景上进行绘制。然而要求控件的画布透明,这个技术在GDI的文档中没有看到Microsoft作任何说明,当然还是有别的办法。

    其一:如果程序支持桌面主题服务的话,则可调用主题服务的API来实现背景。我们先看看这个API:

    HRESULT DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc);

    这个函数就是专门用来绘制父窗口的背景的,其中的hwnd参数是子窗口的句柄,hdc也时子窗口的画布句柄,prc是子窗口需绘制的区域,这个函数实际是把父窗口的背景拷贝到子窗口上来,以这种方法达到透明。

    其二:如果程序不支持桌面主题服务,则不能使用上面的方法,比如程序运行在Windows 2000上。这时我们可以向父窗口发送WM_PAINT消息,不过此消息所附带的wParam参数是一个画布句柄:

    HDC dc = GetDC(NULL);

    HWND cWnd = ...;//子窗口句柄

    HWND pWnd = ...;//父窗口句柄

    RECT cRect;

    GetClientRect(cWnd, &cRect);

    HBITMAP bitmap = CreateCompatibleBitmap(dc, cRect.right, cRect.bottom);

    ReleaseDC(dc);

    HDC memDC = CreateCompatibleDC(NULL);

    HGDIOBJ oldBitmap = SelectObject(memDC, bitmap);

    //此处可以调用SetClipRect()等函数来限制绘制范围

    SendMessage(pWnd, WM_ERASEBKGND, (WPARAM)memDC, 0); 

    SendMessage(pWnd, WM_PAINT, (WPARAM)memDC, 0);

    //至此memDC上已经保存了父窗口的背景内容

    //用户可以调用BitBlt(...)等函数拷贝memDC的内容到子窗口的某个区域,这样就达到了透明效果;

    SelectObject(memDC, oldBitmap);

    DeleteDC(memDC); 

    DeleteObject(bitmap);

    上面的办法当然有限制,因为不是所有的父窗口都可以接受这种特殊的WM_PAINT消息功能,不过MSDN中提到大多数控件都有这个功能,大家要注意读它的文档内容。

    其三:如果上面的办法都不行的话,就剩下最笨的办法了,用GDI函数涂刷子窗口的背景,但你事先就要知道父窗口的背景颜色、背景位图等信息。比如拿父窗口的颜色来填充子窗口的背景,可以调用FillRect()等:

    //-------------------父窗口的背景是颜色的情况

    COLORREF pColor = ...;//父窗口的颜色

    HDC cDC = ...;//子窗口的画布句柄

    RECT cRect = ...;//子窗口需刷新的区域 

    HBRUSH brush = CreateSolidBrush(pColor);

    FillRect(cDC, &cRect, brush);

    DeleteObject(brush);

    //-------------------父窗口的背景是位图的情况

    HBITMAP pBitmap = ...;父窗口的背景位图

    HDC cDC = ...;//子窗口的画布句柄

    RECT cRect = ...;//子窗口需刷新的区域 

    POINT rp;

    SetBurshOrgEx(cDC, x, y, &rp);如果是位图刷子,则还需要调整画布的刷子原点偏移确保无缝

    HBRUSH brush = CreatePatternBrush(pBitmap);

    FillRect(cDC, &cRect, brush);

    DeleteObject(brush);

    SetBurshOrgEx(cDC, rp.x, rp.y, NULL);还原画布的刷子偏移

  • 相关阅读:
    并查集_贪心_求无向图最短连通路径_最小生成树(kruskal)
    01背包&&完全背包_顺序枚举和逆序枚举的问题_一维数组
    week7_简单题_C_水题_hdu_5578+F_贪心_hdu_5583
    计量经济学_大纲
    概率专题_概率/ 数学_基础题_ABEI
    动态规划_01背包_从Dijikstra和Floyd入手,彻底理解01背包
    动态规划_基础_最长公共子序列_多种方法_递归/dp
    动态规划_基础_分治思想_从归并排序到任意子区间序列求和_滑动窗口+递推
    分治思想_归并排序_各种写法和思路(待续)
    递归基础_整数划分类问题_ 多状态转移复杂递推
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3742716.html
Copyright © 2011-2022 走看看