您的位置:逆风者 VC++ 正文
 添加时间:2007-09-01 原文发表:2007-08-31 人气:250 来源:vckbase.com

本文章共5267字,分4页,当前第2页,快速翻页:
 

当 alpha 为 0 时,你得到的是背景(图像完全透明);当 alpha 为 1 时,你得到非透明图像(完全不透明)。实际有透明效果的 alpha 值是一个 8 位的字节表示的值,范围从0-255,0 和 1 只是表示透明和非透明两个极端。它们都是可用的 alpha 值,但大多数应用程序不需要;多数应用程序使用一个常量 alpha 值来处理整个对象,如一幅图像。例如,你可能想让一幅特定的图像以25%的透明度显示。
逆风者
  AlphaBlend 函数类似老的 BitBlt 和 StretchBlt,但它仅仅实现渐变。发音为“blit”,这个术语是从古老的 PDP-10 BLT (块转移)指令派生而来,这个指令用于将大块内存从一个位置转移到另一个位置。AlphaBlend 的细节如 Figure 1 所示,参数简单明了,但是用 AlphaBlend 来实现渐变很繁琐,因为只调用一次是不行的,必须重复调用来产生渐变效果,用一个定时器和 0-255 之间不同的 alpha 值来控制。
  为了展示 AlphaBlend 实际的工作过程,我编写了一个程序 BlendView,该程序基于我的一个图像查看程序,参见 2002 年 3 月刊的专栏文章。BlendView 可以查看各种图像文件(BMP、JPG、GIF 以及其它任何 GDI 支持的格式),但是当你打开一幅新图像时,原来的图像会渐变成新图像,如 Figure 2 所示。


Figure 2 原图像


Figure 2 渐变的图像


Figure 2 最终的图像

  为了将一幅图像渐变为另一幅,你需要两幅图像,当用户打开一个新文档时,MFC 要做的第一件事情是销毁旧的那个对象。所以你考虑在 MFC 加载新图像前将旧图像保存在某个地方。因为渐变效果概念上属于视图处理(绘制图像范畴),所以我把处理过程放在在视图(View)中。也就是说在视图中保存旧图像。但视图如何知道何时要保存图像呢?你当然得告诉它。幸运的是,CDocument 具备一个方法,你可以用它来随时通知视图发生了什么。这个方法就是 CDocument::UpdateAllViews:

// in Doc.cpp:

BOOL CPictureDoc::OnOpenDocument(LPCTSTR lpszPathName)

{

    UpdateAllViews(NULL, PREOPENDOC, this);

    return m_pict.Load(lpszPathName);

}

PREOPENDOC 是我自己的枚举代码,在 doc.h 中定义。当你调用 UpdateAllViews 时,将自己的“提示代码”(一个32位整数)随一个指针传递到“提示对象”,该对象可以是任何 CObject 派生的 MFC 类。这里我传的是文档本身。注意我是在加载新图像之前调用 UpdateAllViews,而旧图像仍然有效。视图处理通知消息保存该图像:

void CPictureView::OnUpdate(CView* pSender, 

LPARAM lHint, CObject* pHint)

{

    if (lHint==CPictureDoc::PREOPENDOC) {

        SaveDocImage((CPictureDoc*)pHint);

    }

}

  相同的 OnUpdate 函数处理所有文档的通知消息,所以你得检查发送了哪个通知消息。一般情况下,提示代码和提示对象背后的工作原理是文档以提示方式提供信息,告诉视图它需要更新屏幕的哪一部份。对于 CPictureView 来说,如果提示代码是 PREOPENDOC,那么 CPictureView则调用一个辅助函数 SaveDocImage 来保存当前图像。Figure 3 是 SaveDocImage 的代码,它创建一个位图和内存设备上下文(DC),然后在内存设备上下文中呈现图像,在文档摧毁原来图像后有效地进行渐变拷贝。
  现在,当用户打开一个新文件,文档通知视图以及 OnUpdate 处理例程以位图形式保存图像。渐变是怎么做出来的呢?它需要重复调用 AlphaBlend 从老图像渐变成新图像。最显而易见的方法是设置一个定时器。假设你想用三秒来渐变。为了用 100 步来实现渐变,你可以将定时期设置成 3000/100=30毫秒。但问题是 AlphaBlend实际上花了大量的时间来处理渐变。而且,所花的时间依赖于图像的大小。较大的图像渐变的时间较长。如果你使用定时器来做,最后得到的幻灯效果是较小的图像更快,较大的图像更慢——可能不是你想要的结果。
 

本文章更多内容<<上一页 - 1 - 2 - 3 - 4 - 下一页>>
相关文章

关于CEdit控件的透明 --作者:monsoon
think window procedure
DCT快速变换
如何提取网页中所有链接
用C#语言实现http协议下的多线程文件传输
如何选中其他程序ListView控件中的某个Item
在VC中调用 WebService (非托管)
自动查找并删除VC生成的临时文件
一步步制作真彩工具条
如何定制浮动工具条
关于调试时输出的字符串信息
SendMessage和PostMessage,total ordering
用udp协议通讯示例
用VC 制作QQ自动登陆软件
MFC程序员的WTL指南: Part II - WTL 界面基
COM 组件设计与应用(十)——IDispatch 接
一个简单的读写注册表实例
利用辅助线程更新用户界面UI
如何更改其它程序 ListView 控件中某个 Ite
如何在NT下获取进程的路径

相关评论


本文章所属分类:首页 VC++

  热门关键字: