简介及相关信息:
以前的问题标题:
窗口在调整大小时会产生闪烁(慢重绘)效果。
我要在主窗口的WM_PAINT处理程序中实现一个复杂的绘图。我提交了一张下面的图片。

标志标记为1和2,使用GDI+绘制。标志标记为1,是metafile,标志用2标记为PNG。
如果我遗漏了第二个徽标的绘图,我的窗口就不会闪烁,但是如果我将第二个徽标的绘图添加到我的WM_PAINT中,则会出现以下效果,如下图所示(这只是一个用油漆制作的素描,但希望它能使事情变得更清晰):

重新油漆的速度似乎很慢。
重要注意:这一效果发生在子窗口上,背景画得很好。
以防万一,有关子窗口的信息如下:
所有5个子窗口都是静态控件。
带有蓝色梯度的静态控件在WM_CTLCOLORSTATIC中使用WM_CTLCOLORSTATIC使用双重缓冲进行绘制。
橙色静态控件是subclassed,是ownerdrawn。
注意:我必须说,这是我第一次使用GDI+__。
在我的WM_PAINT处理程序中,我制作了兼容的内存DC,这是双缓冲所必需的,如下所示:
HDC hdc = BeginPaint( hwnd, &ps), hdcMemImg, MemDC;
MemDC = CreateCompatibleDC(hdc); // back buffer.兼容位图有主窗口的工作区的尺寸。
正如我已经说过的,一切看起来都很好,因为我使用GDI和双缓冲来绘制/绘制。
当我需要绘制标记为1和2的徽标时,我会使用以下代码:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Image image(L".\\resources\\BG.emf"), image1(L".\\resources\\RGF.png");
switch(msg)
{
case WM_ERASEBKGND:
return (LRESULT)1;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps), hdcMemImg, MemDC;
MemDC = CreateCompatibleDC(hdc); // back buffer.
// CreateCompatibleBitmap and other usual stuff
/******************** left logo *******************/
Graphics graphics( MemDC );
//============= aspect ratio ================//
UINT o_height = image.GetHeight(),
o_width = image.GetWidth();
INT n_width = 80;
INT n_height = 100;
double ratio = ( (double)o_width ) / ( (double)o_height );
if (o_width > o_height)
{
// Resize down by width
n_height = static_cast<UINT>( ( (double)n_width ) / ratio );
}
else
n_width = static_cast<UINT>(n_height * ratio);
//========== ensure high graphic quality ======================//
graphics.SetSmoothingMode( SmoothingModeHighQuality );
graphics.SetInterpolationMode( InterpolationModeHighQualityBicubic );
graphics.DrawImage( &image, r.left + 5, r.top + 10, n_width, n_height );
/******************** right logo *******************/
Graphics graphics1( MemDC );
//============= aspect ratio ================//
o_height = image1.GetHeight(),
o_width = image1.GetWidth();
n_width = 90;
n_height = 100;
ratio = ( (double)o_width ) / ( (double)o_height );
if (o_width > o_height)
{
// Resize down by width
n_height = static_cast<UINT>( ( (double)n_width ) / ratio );
}
else
n_width = static_cast<UINT>(n_height * ratio);
//=========== ensure high graphic quality ============//
graphics1.SetSmoothingMode( SmoothingModeHighQuality );
graphics1.SetInterpolationMode( InterpolationModeHighQualityBicubic );
graphics1.DrawImage( &image1, r.right - r.left - 90, r.top + 10, n_width, n_height );
// Then do BitBlt of MeDC to hdc, and clean it up如果需要额外的代码片段,请询问,我将编辑我的文章,但是现在,为了保持文章的简短和简洁,它们被省略了。
我在Windows上工作,使用C++和纯Win32 API。
我的CPU是单核的( 2,67 GHz ),我有768 MB的内存。
重要更新:
当我打开Task Manager的时候,我可以看到我的应用天空的内存消耗是火箭。
它永远不会掉落,它总是会生长,特别是当我调整窗户的尺寸时。
关于我为解决这一问题所作努力的详细说明见下文。
我已经决定采纳更有经验和更好的开发人员的建议,并将提供到演示项目的链接。
一个注意事项:自从VS的速成版没有资源编辑器以来,就使用ResEdit从http://www.resedit.net/创建了资源文件和资源头。
下面是到演示项目的链接(所有必要的评论和解释都在项目注释中):http://www.uploadmb.com/dw.php?id=1382012579。
我解决问题的努力:
在互联网上浏览,所以存档、CodeProject和CodeGuru,我没有看到问题--似乎(我也相信),GDI+和GDI中双重缓冲的原则是一样的。
重要更新:
我从http://vld.codeplex.com/下载了http://vld.codeplex.com/,按照他们的指示,但是VLD没有检测到任何内存泄漏。
此外,我做了一个项目的副本,并删除了静态控件,只留下窗口的背景,以方便我的调试。
上述内存消耗仍在发生。
只有当我不画徽标的时候,它才会停止。
问题:
由于这是我第一次使用GDI+,在释放/删除某些GDI+对象或类似的东西(所有用于在WM_PAINT中绘图的GDI+代码都提交了)时,是否遗漏了什么?
再次,我相信我的其他绘画代码工作良好,但我会张贴它,如果需要。
更新:
关于上面提供的更新,我应该做些什么来解决上面描述的内存消耗过大的问题?
有人能回顾一下上面提供的小型演示项目,并尝试给我一些有用的建议吗?
谢谢。
致以问候。
发布于 2013-11-01 12:16:38
这个问题在这个链接中得到了很详细的解释:http://www.codeproject.com/Questions/666738/Window-produces-flicker-like-slow-repainting-like。
如果这个链接死了,这就是我必须做的:
Image对象具有全局性;第三个动作是最重要的,因为每次调用主窗口的过程时,我都会反复加载巨大的图像,这最终会完全消耗内存。
希望这能对将来的人有所帮助。
发布于 2013-10-11 08:18:06
不要使用GDI+的多个Graphics对象。请注意,在您将位图复制回真实的DC之后,解构这个Graphics对象也会运行。硫酸钠也可能引起副作用。
将Graphics对象的所有使用放在自己的块中,以便在将mem复制回油漆DC之前进行解构。
https://stackoverflow.com/questions/19310407
复制相似问题