Win32 使HBITMAP显示成透明效果2

来源:互联网 发布:win10 iis7.5配置php 编辑:程序博客网 时间:2024/06/01 09:34

我之前写了一篇文章,关于如果将HBITMA(如Excel文件的图标)显示在界面上。

Win32 使HBITMAP显示成透明效果

由于有的HBITMAP有透明色,如果直接把这个HBITMAP画在界面上,透明的地方就会显示成黑色(也不一定是黑色)。当时我用的方法是把这个HBITMAP通过转换成GDI+的Image里面,然后把这个Image画在界面上,这样就可以去掉黑色。最近又发现了一个新的方法,主要的API就是AlphaBlend函数。

先看看效果图:


图一:直接用BitBlt把HBITMAP画到DC上面



图二:通过AlphaBlend将HBITMAP画到DC上面


关于AlphaBlend,MSDN上面的解释是:

The AlphaBlend function displays bitmaps that have transparent or semitransparent pixels.

BOOL AlphaBlend(     HDC hdcDest,  // handle to destination DC    int nXOriginDest,          // x-coord of upper-left corner    int nYOriginDest,          // y-coord of upper-left corner    int nWidthDest,            // destination width     int nHeightDest,           // destination height     HDC hdcSrc,                // handle to source DC     int nXOriginSrc,           // x-coord of upper-left corner     int nYOriginSrc,           // y-coord of upper-left corner     int nWidthSrc,             // source width    int nHeightSrc,            // source height     BLENDFUNCTION blendFunction  // alpha-blending function );

这里最关键的就是设置这个BLENDFUNCTION 函数了,它告诉了API如何混合Alpha。关于Alpha是怎么混合的,MSDN上面有详细说明

我写的代码如下:
case WM_PAINT:    {        RECT rc = { 0 };        GetClientRect(hWnd, &rc);        int x = (rc.right - 256) / 2;   // 画的图片在窗体中间        int y = (rc.bottom - 256) / 2;  // 画的图片在窗体中间        PAINTSTRUCT ps;        HDC hdc = BeginPaint(hWnd, &ps);        HDC hMemDC = CreateCompatibleDC(NULL);               // 创建一个兼容内存DC        HGDIOBJ hOldObj = SelectObject(hMemDC, g_hBitmap);   // 将g_bitmap选入到这个内存DC        // 如果用这句话的话,就会得到图一的效果        //BitBlt(hdc, x, y, ICON_WIDTH, ICON_HEIGHT, hMemDC, 0, 0, SRCCOPY);        BLENDFUNCTION ftn = { 0 };        ftn.BlendOp = AC_SRC_OVER;                           // 目前只能设置这个值        ftn.AlphaFormat = AC_SRC_ALPHA;                      // 也只能设置这个值        ftn.BlendFlags = 0;                                  // 必须为0        ftn.SourceConstantAlpha = 255;                       // 指定源图片的alpha        // 调用这个函数来进行Alpha混合        AlphaBlend(hdc, x, y, 256, 256, hMemDC, 0, 0, 256, 256, ftn);        SelectObject(hMemDC, hOldObj);        DeleteObject(hMemDC);        EndPaint(hWnd, &ps);    }    break;

如果把BLENDFUNCTION 的 SourceConstantAlpha 不设置为255,那么源HBITMAP是有一个透明度的,比如我把这个值设置为128后,得到的效果图如下:


图三:SourceConstantAlpha设置为128的效果

==================================================================

上面提取的图标的大小是256 * 256。
关于如何提取一个文件的图标,方法如下:

HBITMAP ExtractFileIcon(LPCTSTR pszPath, UINT nWidth, UINT nHeight){    HBITMAP hBitmpa = NULL;    if ( (NULL != pszPath) && (nWidth > 0.0) && (nHeight > 0.0) )    {        IShellItemImageFactory *psif = NULL;        SIZE size = { nWidth, nHeight };        HRESULT hr = ::SHCreateItemFromParsingName(pszPath, NULL, IID_PPV_ARGS(&psif));        if ( SUCCEEDED(hr) && (NULL != psif) )        {            psif->GetImage(size, SIIGBF_ICONONLY, &hBitmpa);        }        SAFE_RELEASE(psif);    }    return hBitmpa;}



原创粉丝点击