本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接,严禁用于任何商业用途。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net
背景图片的载入是通过BitBlt函数实现的。为了实现图片的渐变效果,利用背景图片与黑色图片的融合得到。通过对透明程度的设置,可以达到背景图片的渐变。
一、需要的头文件与库文件
AlphaBlend函数需要msimg32.lib库的支持
#pragma comment (lib,"msimg32.lib")//透明显示库 |
二、一个结构体和两个重要函数
结构体BLENDFUNCTION用于指定两个DC的融合方式。通常情况下,只有SourceConstantAlpha是可以任意设定的,它决定了透明程度,取值范围为0~254。当取255时,表示利用源图像的每个象素点自带的Alpha值融合(前提是每个象素自带Alpha值,故一般不使用)
typedef struct _BLENDFUNCTION { BYTE BlendOp; //Default: AC_SRC_OVERAC_SRC_ALPHA BYTE BlendFlags; //Must be zero BYTE SourceConstantAlpha; BYTE AlphaFormat; //Default: AC_SRC_ALPHA }BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION; |
BitBlt函数用于从源DC拷贝位图到当前DC,最后一个参数通常为SRCCOPY:从原始位图拷贝到目标位图
BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop ); |
AlphaBlend函数用于两个DC的位图的融合。融合方式如下:
Dst.Red = Src.Red * ConstantAlpha + (1 - ConstantAlpha) * Dst.Red
Dst.Green = Src.Green * ConstantAlpha + (1 - ConstantAlpha) * Dst.Green
Dst.Blue = Src.Blue * ConstantAlpha + (1 - ConstantAlpha) * Dst.Blue
当源DC为需要显示的背景图案,目标DC为某种纯色(即图案隐去后的背景)时,通过Alpha值的逐渐增大,就可以实现。
AlphaBlend( HDC hdcDest, //目标DC int nXOriginDest, int nYOriginDest, int nWidthDest, int hHeightDest, HDC hdcSrc, //源DC int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, BLENDFUNCTION blendFunction //融合方式 ); |
三、环境上下文DC的建立
环境的建立是通过下面两个几个函数实现的:
BOOL CreateCompatibleBitmap(CDC* pDC,int nWidth, int nHeight); //建立兼容位图 BOOL LoadBitmap(UINT nIDResource ); //载入位图 virtual BOOL CreateCompatibleDC(CDC* pDC); //建立兼容DC CBitmap* SelectObject(CBitmap* pBitmap); //把位图选如环境 |
利用第一个函数可以建立一个背景色为黑色的兼容位图,第二个函数可以载入背景位图。第三个函数是建立兼容DC。第四个函数可以把前面已经建立或载入的位图选入建立好的兼容DC中。这样可以建立一个纯黑色DC环境DCScr,与一个背景图案DC环境DCDst。通过AlphaBlend函数的融合,可以创造出一个所需明暗程度的DC环境,最后通过BitBlt函数可以把这个环境放入当前显示DC环境中。
注意:设备环境上下文要先创建再选入位图,然后才能使用BitBlt函数。因为BitBlt函数是用来使两个环境上下文叠加的函数。
三、源码:
为了实现渐变的效果,建立了定时器1,时间设定为100ms。所需的两个DC环境与透明度作为全局变量,因为透明度的类型为byte型只能表示0~255,为了实现透明度越界后定时器1停止的功能,定义个一个int型变量m_show来同步反映透明度的取值。位图的建立与载入、环境的建立、位图的选入和定时器1的设定等初始化代码放在了一个初始化函数里实现。
进入定时器1后,每次进入定时器m_show与透明度都会同步增加,当m_show超过255时,透明度就不会再增加了,这时会显示一些欢迎文字,并关闭定时器1
//******* load head file and lib files *****
#include #pragma comment (lib,"gdi32.lib") #pragma comment (lib,"msimg32.lib")//透明显示库
//******* Global Variables ***** CDC myDCSrc,myDCDst; int m_show; //透明度 BLENDFUNCTION bfn;
//******* Initial Function ***** void CTestDlg::myInitial() { myDCSrc.CreateCompatibleDC(0); myDCDst.CreateCompatibleDC(0);//创建DC环境
CBitmap bitSrc,bitDst; bitSrc.LoadBitmap(IDB_BITMAP_START); bitDst.CreateCompatibleBitmap(&myDCDst, 800,600);//创建与载入位图
myDCSrc.SelectObject(bitSrc); myDCDst.SelectObject(bitDst);//把位图选入DC环境 bfn.BlendOp = AC_SRC_OVER; bfn.BlendFlags = 0; bfn.SourceConstantAlpha = 0; bfn.AlphaFormat = 0;//设置BLENDFUNCTION结构体
m_show = 0;//设置透明度
SetTimer(1,100,NULL);//打开定时器1 }
//******* OnTimer Function ***** void CTestDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if (nIDEvent==1) { CClientDC dc(this); AlphaBlend(myDCDst, 0, 0, 800, 600,
myDCSrc, 0, 0, 800, 600, bfn); //半透明处理 dc.BitBlt(0, 0, 800, 600, &myDCDst, 0, 0, SRCCOPY); bfn.SourceConstantAlpha += 50; m_show += 50; if (255 < m_show) { dc.SetTextColor(RGB(255, 0, 0)); //设置字体颜色为红色 dc.SetBkMode(TRANSPARENT); //设定背景色显示方式为无色 dc.TextOut(300, 200, "Hello World!!");
KillTimer(1); } } CDialog::OnTimer(nIDEvent); } |
本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接,严禁用于任何商业用途。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net
阅读(4774) | 评论(0) | 转发(0) |