请大家办我看看这个实现位图的淡入淡出的例程错在那里???

cowboy1114 2002-06-16 03:43:18

我们经常在AboutBox中显示一幅关于公司或自己讯息的位图,有没有想过让这幅位图有更酷的效果?比如加上淡入淡出效果?只要有了这个CAlphaCtrl控件就可以轻松实现。
CAlphaCtrl是从CStatic继承而来。使用时只要把CAlphaCtrl加入窗体,然后调用LoadAlphaBitmap(UINT uID, int iTimer)函数就可以实现位图的淡入淡出。其中uID是位图的资源ID,iTimer是位图显示时间间隔,值愈小显示愈快。
下面就来说一说CalphaCtrl是如何实现的。关键的一个实现函数是一个win32 API: AlphaBlend,此函数可以实现图像的透明显示,相关的参数和资料请自行参阅MSDN,值得注意的是使用此函数时要链接到msimg32.lib库。

第一步,我们先在CalphaCtrl类中增加几个Data Member:

CBitmap Bmp;
BOOL bCanPaint;
UINT nBmpID; int nTimer;

第二步,在CalphaCtrl类中增加一个Member Function:
void AlphaDisplay(CDC &pDC, CClientDC &dc, BLENDFUNCTION& rBlendProps, int width, int heigh, byte nLevel)
{
//nLevel是透明度,0表示不显示,255则完全显示
rBlendProps.SourceConstantAlpha = nLevel;
AlphaBlend( dc.m_hDC, 0, 0, width, heigh, pDC.m_hDC, 0, 0,
width, heigh, rBlendProps );
}
第三步,增加一个名为tdDisplay的全局函数,此函数为一个线程函数,用于位图的显示。

UINT tdDisplay(LPVOID lpParam)
{
CAlphaCtrl* AlphaCtrl = (CAlphaCtrl*)lpParam;
CClientDC dc(AlphaCtrl);

CDC pDC;
pDC.CreateCompatibleDC(&dc);
pDC.SelectObject(&AlphaCtrl->Bmp); BLENDFUNCTION rBlendProps;
rBlendProps.BlendOp = AC_SRC_OVER;
rBlendProps.BlendFlags = 0;
rBlendProps.AlphaFormat = 0;
BITMAP bmInfo;
::GetObject(AlphaCtrl->Bmp.m_hObject, sizeof(BITMAP), &bmInfo);
INT nWidth, nHeigh;
nWidth = bmInfo.bmWidth;
nHeigh = bmInfo.bmHeight;AlphaCtrl->SetWindowPos(NULL, 0, 0, nWidth, nHeigh,SWP_NOMOVE);
int i = 0;
while(i <= 255)
{
AlphaCtrl->AlphaDisplay(pDC, dc, rBlendProps, nWidth, nHeigh, i);
i += 5;
Sleep(AlphaCtrl->nTimer);
}
AlphaCtrl->bCanPaint = 1; //Make OnPaint Word
AfxEndThread(0);
return 0;
}
第四步,现在万事俱备,加上初始化函数:


BOOL LoadAlphaBitmap(UINT uID, int iTimer)
{
int i = Bmp.LoadBitmap(uID);

if(i)
{
AfxBeginThread(tdDisplay, this);
nBmpID = uID;
nTimer = iTimer;
return 1;
}
else
{
TRACE("Load Bitmap Failed\n");
return 0;
}

return 1;
}
最后,执行程序,打开你的对话框看一看那幅很酷的位图!

我们经常在AboutBox中显示一幅关于公司或自己讯息的位图,有没有想过让这幅位图有更酷的效果?比如加上淡入淡出效果?只要有了这个CAlphaCtrl控件就可以轻松实现。
CAlphaCtrl是从CStatic继承而来。使用时只要把CAlphaCtrl加入窗体,然后调用LoadAlphaBitmap(UINT uID, int iTimer)函数就可以实现位图的淡入淡出。其中uID是位图的资源ID,iTimer是位图显示时间间隔,值愈小显示愈快。
下面就来说一说CalphaCtrl是如何实现的。关键的一个实现函数是一个win32 API: AlphaBlend,此函数可以实现图像的透明显示,相关的参数和资料请自行参阅MSDN,值得注意的是使用此函数时要链接到msimg32.lib库。

第一步,我们先在CalphaCtrl类中增加几个Data Member:

CBitmap Bmp;
BOOL bCanPaint;
UINT nBmpID; int nTimer;

第二步,在CalphaCtrl类中增加一个Member Function:
void AlphaDisplay(CDC &pDC, CClientDC &dc, BLENDFUNCTION& rBlendProps, int width, int heigh, byte nLevel)
{
//nLevel是透明度,0表示不显示,255则完全显示
rBlendProps.SourceConstantAlpha = nLevel;
AlphaBlend( dc.m_hDC, 0, 0, width, heigh, pDC.m_hDC, 0, 0,
width, heigh, rBlendProps );
}
第三步,增加一个名为tdDisplay的全局函数,此函数为一个线程函数,用于位图的显示。

UINT tdDisplay(LPVOID lpParam)
{
CAlphaCtrl* AlphaCtrl = (CAlphaCtrl*)lpParam;
CClientDC dc(AlphaCtrl);

CDC pDC;
pDC.CreateCompatibleDC(&dc);
pDC.SelectObject(&AlphaCtrl->Bmp); BLENDFUNCTION rBlendProps;
rBlendProps.BlendOp = AC_SRC_OVER;
rBlendProps.BlendFlags = 0;
rBlendProps.AlphaFormat = 0;
BITMAP bmInfo;
::GetObject(AlphaCtrl->Bmp.m_hObject, sizeof(BITMAP), &bmInfo);
INT nWidth, nHeigh;
nWidth = bmInfo.bmWidth;
nHeigh = bmInfo.bmHeight;AlphaCtrl->SetWindowPos(NULL, 0, 0, nWidth, nHeigh,SWP_NOMOVE);
int i = 0;
while(i <= 255)
{
AlphaCtrl->AlphaDisplay(pDC, dc, rBlendProps, nWidth, nHeigh, i);
i += 5;
Sleep(AlphaCtrl->nTimer);
}
AlphaCtrl->bCanPaint = 1; //Make OnPaint Word
AfxEndThread(0);
return 0;
}
第四步,现在万事俱备,加上初始化函数:


BOOL LoadAlphaBitmap(UINT uID, int iTimer)
{
int i = Bmp.LoadBitmap(uID);

if(i)
{
AfxBeginThread(tdDisplay, this);
nBmpID = uID;
nTimer = iTimer;
return 1;
}
else
{
TRACE("Load Bitmap Failed\n");
return 0;
}

return 1;
}
最后,执行程序,打开你的对话框看一看那幅很酷的位图!

问题:
编译时会在 AfxBeginThread(tdDisplay, this);这一句报错!!!
...全文
126 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lemon_2000 2002-06-16
  • 打赏
  • 举报
回复
MFC 区分两种类型的线程:用户界面线程和辅助线程。用户界面线程通常用于处理用户输入及响应用户生成的事件和消息。辅助线程通常用于完成不需要用户输入的任务(如重新计算)。
MFC 通过参数重载提供两个版本的 AfxBeginThread:一个用于用户界面线程,另一个用于辅助线程。若要启动用户界面线程,请调用 AfxBeginThread,提供下列信息: 从 CWinThread 派生的类的 RUNTIME_CLASS.

CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
CWinThread* AfxBeginThread(
CRuntimeClass* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);

AfxBeginThread(tdDisplay, this);  this:CAlphaCtrl*
this 为类窗口指针,CAlphaCtrl<-CStatic<-CWnd<-CCmdTarget<-CObject
它要响应命令消息,应该属于用户界面线程,不要用辅助线程。
duiduiblues 2002-06-16
  • 打赏
  • 举报
回复
LoadAlphaBitmap不在类中,何来this!
yz95 2002-06-16
  • 打赏
  • 举报
回复
把AfxBeginThread(tdDisplay, this);
改为AfxBeginThread(tdDisplay, (HWND)this);
要是不行就该成
HWND hWnd = GetSafeHwnd();
AfxBeginThread(tdDisplay,hWnd);

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧