使用C ++和.NET我有数据流我想显示作为滚动图像。 每次我得到一些新的数据我想将其先前的内容添加为新行(128x1像素),并滚动到一边。
我当时的第一个问题涉及刺呈现整个数据的每个我得到了一个新的行时间设定。 这个工作,但速度太慢,所以我想它可能会更有意义写信给某种形式的缓冲区(可能是位图?)。 问题是,我不知道怎样才能做到这一点; Graphic
对象让你很愉快地画,但我不能看到一个明显的方式来告诉我的控制使用Bitmap
对象,因为它的缓冲? 同样的,我看不到的方式来画上一个位图,我可以再写入到屏幕上。
这必须是可能的,但我的谷歌,富失败我迄今...
[EDIT1]只是为了澄清,所述数据是频谱图。 下图显示的那种,我想实现的事情:
替代文字http://www.geekops.co.uk/photos/0000-00-02%20(Forum%20images)/ScrollingGraphicsAlgorithmExplanation.png
我绘制的有关资料在彩车的数组。 没有什么限制我多少会得到的,所以我只是想,因为它脱落情节的侧忘记的数据。
我目前正在从继承System::Windows::Forms::UserControl
,但可以切换到别的东西,如果有一个更好的变质?
看看的滚屏 win32的方法。 您可以在屏幕上滚动的现有数据,然后只绘制新的数据。 这是非常快的。
位图bmpImage =新位图(512512);
对(INT iRow = 0; iRow <512; iRow ++)
{
for (int iCol = 0; iCol <512; iCol++)
{
Color clr;
bmpImage.SetPixel(iCol, iRow, clr);
}
}
(图像)bmpImage.save()
我不是很清楚你想画(某种程度的控制在对话框?),但在猜测它应该工作一样的东西到底是什么:
class Foo {
...
Gdiplus::Bitmap* m_pBitmap;
};
void Foo::DrawItem(LPDRAWITEMSTRUCT lpDraw) {
// update bitmap if needed
if(some_condition_requiring_bitmap_redraw) {
// do expensive drawing into bitmap
Gdiplus::Graphics graphics(m_pBitmap);
}
// create a graphics object to draw the control from the bitmap
Gdiplus::Graphics graphics(lpDraw->hDC);
graphics.DrawImage(m_pBitmap, ...);
}
这是一个非常粗略的猜测也无妨。 该DRAWITEM通话可能看起来完全不同,如果你使用.NET(我不熟悉...),但基本的逻辑应该是大致相同的。
根据究竟是什么你的数据是,它可能不是高效的同时绘制1个像素行。 你可能会更好拉大面积只显示所需的它位 - 尽管这显然将取决于您的数据是如何的用武之地。
你也可能需要做一些更新到您的位图“滚动”的内容。 我会离开,你:-)
尝试以下方法:
- 启动一个新的VC ++ WinForms应用程序。
- 添加一个名为“频谱”该项目的用户控件
- 计时器控件添加到“频谱”的用户控制和设置的“已启用”属性设置为true
- 以下私有变量添加到“频谱”用户控制
private:
Graphics ^m_gfxBuffer;
Graphics ^m_gfxOriginal;
Bitmap ^m_bmpBuffer;
Bitmap ^m_bmpOriginal;
m_bmpBuffer = gcnew Bitmap(this->ClientSize.Width, this->ClientSize.Height);
m_gfxBuffer = Graphics::FromImage(m_bmpBuffer);
m_bmpOriginal = gcnew Bitmap(this->ClientSize.Width, this->ClientSize.Height);
m_gfxOriginal = Graphics::FromImage(m_bmpOriginal);
this->SetStyle(::ControlStyles::AllPaintingInWmPaint | ::ControlStyles::DoubleBuffer | ::ControlStyles::UserPaint | ::ControlStyles::OptimizedDoubleBuffer, true);
this->UpdateStyles();
array<unsigned char, 1> ^bytes = gcnew array<unsigned char, 1>(m_bmpBuffer->Height * 3);
Random ^r = gcnew Random();
r->NextBytes(bytes);
m_gfxOriginal->DrawImage(m_bmpBuffer, -1, 0);
int y = 0;
for (int i = 0; i < m_bmpOriginal->Height * 3; i += 3)
{
m_bmpOriginal->SetPixel(m_bmpOriginal->Width - 1, y++, ::Drawing::Color::FromArgb(255, bytes[i], bytes[i + 1], bytes[i + 2]));
}
m_gfxBuffer->DrawImage(m_bmpOriginal, 0, 0);
e->Graphics->DrawImage(m_bmpOriginal, 0, 0);
this->Invalidate(false);
- 保存项目
- 清洁和重建
- 运行项目
- 关闭正在运行的表
- 频谱用户控件现在应该在“工具箱”
- 从“工具箱”拖到窗体它,你应该看到了各种各样的滚动随机颜色的光谱图。
这应该给你一个位图缓存控制的总体思路。 这里的关键是在构造函数中“的SetStyle”通话并以-1的油漆事件的偏移位图。
你必须妥善处理图形和位图对象以及处理销毁,并在resize事件重建他们。
希望这可以帮助。 让我知道事情的后续。