我们知道位图中大多都有alpha信息(图像通道),专用于位图的透明
今天使用的这个函数AlphaBlend——从名字上看,是"Alpha混合"的意思——那么既然是Alpha,也就和位图的透明相关了
OK,我们先来看看msdn中对于这个函数的说明:
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 );
前10个参数,应该不言而喻,我在这里着重讲一下最后一个参数blendFunction,它是BLENDFUNCTION类型的变量——继续看msdn:
typedef struct _BLENDFUNCTION { BYTE BlendOp; BYTE BlendFlags; BYTE SourceConstantAlpha; BYTE AlphaFormat; }BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
1>参数BlendOp,混合操作,这个目前有且仅有一种方式AC_SRC_OVER,它表示源位图通过基于alpha信息放到目标位图上
2>参数BlendFlags,混合标记,只能是0
3>参数SourceConstantAlpha,大致上表示位图的透明度(0~255)。如果为0,就是完全透明;如果是255,就不透明
4>参数AlphaFormat,如果设定为AC_SRC_ALPHA,那么你的位图必须是32位的;如果你的位图不是32位的(一般24位居多,RGB),就不要用它,直接赋0就行了
另外,这个函数包含在msimg32.lib这个库文件中,使用它时,记得导入这个库:
//导入msimg32.lib库
#pragma comment(lib, "msimg32.lib")
…………………………………………………………………………
有了这些基础知识后,接下来,介绍一下今天程序实现的功能:
通过滚动鼠标中键(滚轮),来控制位图的透明度——向后滚动,越来越透明;反之,越来越不透明
还是先来看看程序运行效果:
下面进入代码阶段:(贴出主要代码,内含注释)
1>初始化操作
case WM_CREATE:
//加载位图信息
hBmp = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
MAKEINTRESOURCE(IDB_BITMAP1));
{
BITMAP bmp;
GetObject(hBmp, sizeof(BITMAP), &bmp);
sBmp.cx = bmp.bmWidth;
sBmp.cy = bmp.bmHeight;
}
//初始化混合结构体成员
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = bTrans;
bf.AlphaFormat = 0;
return 0 ;
2>绘制透明位图
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBmp);
AlphaBlend(hdc, 0, 0, sBmp.cx, sBmp.cy,
hdcMem, 0, 0, sBmp.cx, sBmp.cy, bf);//绘制指定透明度的位图
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
return 0;
3>响应鼠标滚轮消息,来控制透明度
case WM_MOUSEWHEEL:
//修改透明度(0~254)
if(GET_WHEEL_DELTA_WPARAM(wParam) > 0 && bTrans <= 234)
{
bTrans += 20;
bf.SourceConstantAlpha = bTrans;
InvalidateRect(hwnd, NULL, FALSE);//加深 , 就不重绘背景
}
if(GET_WHEEL_DELTA_WPARAM(wParam) < 0 && bTrans >= 20)
{
bTrans -= 20;
bf.SourceConstantAlpha = bTrans;
InvalidateRect(hwnd, NULL, TRUE);//加浅 , 需要重绘背景
}
return 0;
有些朋友可能在处理这个消息时,编译器可能会提示错误,解决方案参见我的博文:
OK,今天儿就到此为止了
源代码及相关资源下载