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

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

  保持渐变时间为常量的方法是固定持续时间——假设为 3,000 毫秒——然后根据实际逝去的时间计算 alpha 值,假设第一次迭代发生在 t 20 毫秒。那么你可以用的 alpha 值为 20*255/3000 = 1 (取最近似的一个整数)。然后根据当前时间计算的 alpha 值立即进行另一次渐变。如果逝去的时间超过一半,你最终的 alpha 值是 .5。通过用实际逝去的时间计算 alpha 值,你可以保证渐变总是按时完成,但缺点是较大的图像无法平滑地完成渐变,因为它们的迭代过程更少,在 AlphaBlend 中花的时间更多。
逆风编程精品
  所有这些实现难易程度不一。Figure 3Figure 4 是详细代码。当 CPictureView::OnUpdate 获得 PREOPENDOC 通知时,保存旧图像之后,它将数据成员 m_iStartTime 置为当前时钟时间。时钟时间是自该进程启动后的“时钟嘀嗒”数。每秒嘀嗒数为 CLOCKS_PER_SEC(通常为 1,000)。当 OnUpdate 返回时,控制传回到文档和 MFC,它调用视图的 OnInitialUpdate 函数,该函数调用 OnUpdate,它重画窗口。最后,Windows 向你的视图发送 MW_PAINT 消息,MFC 通过调用视图的虚拟 OnDraw 方法处理该消息。这是 MFC 的基本常识:在某个视图中,绘图在 OnDraw 进行,而不是 OnPaint 中。CPictureView 是这样绘制的:

void CPictureView::OnDraw(CDC* pDC)

{

    CPicture* ppic = // get current picture

    if (m_iStartTime) {

        // do blend

    } else {

        // render as normal

        ppic->Render(pDC,rc);

    }

}

  我省略了渐变的细节,主要突出 CPictureView 如何用 m_iStartTime 作为标志来确定是否渐变。以下是实现渐变需要的基本步骤。

  1. 创建一个内存 DC;
  2. 在该内存 DC 中绘制位图;
  3. 计算渐变的 alpha 值;
  4. 在该内存 DC 中 AlphaBlend 位图;
  5. 将结果拷贝到屏幕(BitBlt);

在画面以外的内存 DC 中进行渐变然后拷贝到屏幕这一步是很重要的;否则用户将会看到一闪而过的中间图像。因为 AlphaBlend 需要设备上下文,而不是 CPicture 对象,首先绘制新图像(所以我调用 CPicture::Render ),然后在其上渐变旧图像要方便一些。所以我用的 alpha 值与先从旧的图像开始显示所用的 alpha 值相反转(1-alpha) ,换句话说,不是先从旧图像开始,然后在上面以越来越多的效果渐变新图像。我是先从新图像开始,然后在上面以越来越少的效果渐变旧图像。很聪明,不是吗?网格效果处理方法一样。以下是计算 AlpahBlend alpha 值的关键代码行:

int alpha = ((clock() - m_iStartTime) * 255) / BLEND_DURATION; 

alpha = max(255-alpha,0);

  渐变之后,如果计算的 alpha 值大于 0,那么就需要处理更多的渐变效果。所以 OnDraw 调用 Invalidate(FALSE) 在不擦除背景的情况下而重画窗口。Windows 发送另一个 WM_PAINT 消息——只是要等到当前消息处理完成。这样一来(使 WM_PAINT 为有效消息),没有阻塞。在渐变期间,用户仍然能使用应用程序。你可以在渐变期间改变窗口大小来证明这一点。CPictureView 在新的窗口尺寸下保持渐变。
  如果算出的 alpha 值为 0,渐变完成。计时器停止。这时,OnDraw 调用辅助函数 StopBlending,该函数删除旧图像并将 m_iStartTime 设置为 0,暗示 OnDraw 停止渐变。现在当视图需要绘制时,OnDraw 通过调用 CPicture::Render 进行常规绘制,直接呈现新图像,不发生渐变。
  如果你使用活动模板库(ATL)CImage 类来保存图像(而不是用 CPicture,这是我很久以前实现的一个类,当时 CImage 还未出现),你可以用 CImage::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++

  热门关键字: