Winapi 使用BitBlt在图片背景上滚动文本

Winapi 使用BitBlt在图片背景上滚动文本,winapi,gdi+,sprite,gdi,bitblt,Winapi,Gdi+,Sprite,Gdi,Bitblt,我的用户控件旨在作为平滑的垂直文本滚动条进行操作。 它使用textrender.DrawText仅将文本(要滚动)渲染到控件的表面一次。 然后,它启动一个计时器,在它的每个滴答声中,位BLIT(BitBlt)将整个客户端矩形向上一个像素。控件的设备上下文是BitBlt操作的源和目标,如下所示: Protected Sub handleTimerTick(ByVal sender As System.Object, ByVal e As System.EventArgs) Dim oG A

我的用户控件旨在作为平滑的垂直文本滚动条进行操作。 它使用
textrender.DrawText
仅将文本(要滚动)渲染到控件的表面一次。 然后,它启动一个计时器,在它的每个滴答声中,位BLIT(
BitBlt
)将整个客户端矩形向上一个像素。控件的设备上下文是
BitBlt
操作的源和目标,如下所示:

Protected Sub handleTimerTick(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim oG As Graphics = Me.CreateGraphics()
    Dim sHdc As IntPtr = oG.GetHdc()
    Dim iRes As Integer = BitBlt(sHdc, 0, 0, Me.ClientRectangle.Size.Width, Me.ClientRectangle.Size.Height, sHdc, 0, 1, SRCCOPY)
    oG.ReleaseHdc(sHdc)
    oG.Dispose()
End Sub
这成功地实现了所需的滚动效果,但仅当控件的背景为纯色时(例如
Me.BackColor=color.Gray

如果我将图片设置为控件的背景
BitBlt
将滚动背景以及显示在其上的文本。当然,我只希望文本被滚动,背景图像保持静止

我发现以下线索,建议使用
TransparentBlt
而不是
BitBlt
来忽略背景为纯色的均匀颜色:

该解决方案表明,这不适用于使用彩色背景的现有案例

请注意文本本身为纯色统一颜色


非常感谢您的建议。如果有任何问题,我使用的是VB.NET 2005。

如果在文本移动时背景应该保持不变,我建议您维护两个单独的位图:一个包含背景图像,和第二个包含在透明背景上的文本

然后,在每个计时器刻度上,首先绘制背景位图,然后在所需偏移位置绘制文本位图


我不明白为什么您需要为此p/调用
BitBlt
函数。等效的GDI+函数有什么问题吗?

非常感谢Cody的回答,它已经被.NET Framework包装成了
Graphics.DrawImage
<代码>图形。DrawImage似乎消耗了更多的CPU周期。我假设它不使用硬件加速(即,它使用CPU而不是GPU)。此外,
TextRenderer.DrawText
在目标DC是控件曲面和位图时具有不同的性能,因此我必须将文本直接渲染到曲面而不是位图。你能详细说明一下你的第一个建议吗?我曾经尝试过从位图到控件的表面进行点位闪烁,但是绘制了一个黑色矩形…我很确定所有这些问题都来自混合GDI和GDI+。我从未见过
textrender.DrawText
显示不同的行为,无论是在控件表面还是位图上绘制。如果有什么不同的话,在屏幕外绘制位图应该会更快。谢谢科迪。我使用的唯一GDI/GDI+函数是textrender.DrawText,没有其他函数。通过“不同的表现”,我指的是呈现文本质量的差异。我确实使用TextRenderer.DrawText实现了滚动程序,将文本直接渲染到控件的表面,效果很好,但占用了相当多的CPU时间。我已经实现了您建议的解决方案,在控件的表面上逐点显示两个单独的位图-一个背景位图,另一个渲染文本位图。位闪烁在ticker的tick handling函数中执行,而不是在
OnPaint
事件处理程序中执行(该处理程序不绘制任何内容)。这确实有效(文本在所需的背景图像上滚动),但文本经常闪烁。你能告诉我为什么吗?@Bliss可能是因为你直接画到了控件上。解决闪烁的典型方法是添加第二个屏幕外位图作为缓冲区。将中间项绘制到此缓冲区以构建图像,然后将整个缓冲区blit到控件上。这叫做“双缓冲”,也许你听说过?你说这比较慢。我无法想象如何,但我无法反驳。虽然这与您所问的问题是分开的,但使用相同的DC作为源和目标很可能会遇到问题。这就像试图在缓冲区内移动内存,因为您必须非常小心覆盖的顺序,以避免在重叠区域中涂抹。您可能应该将文本呈现给内存DC一次,然后根据需要将其blit到控件的DC。