1

简介及相关资料:

问题的前标题:

窗口在调整大小时会产生类似闪烁(慢速重绘)的效果

我有一个复杂的绘画要在我的主窗口的WM_PAINT处理程序中实现。我已经提交了一张图片波纹管。

在此处输入图像描述

标有 1 和 2 的徽标是使用 绘制的GDI+。标记为 1 的metafile徽标是 ,标记为 2 的徽标是PNG

如果我省略了第二个标志的绘制,我的窗口不会闪烁,但是如果我在我的 中添加第二个标志的绘制WM_PAINT,就会出现以下效果,如下图所示(这只是在 Paint 中制作的草图,但希望它会澄清事情):

在此处输入图像描述

好像重绘很慢。

重要提示:此效果发生在子窗口上,背景绘制正确。

以防万一,有关子窗口的信息:

所有 5 个子窗口都是静态控件。

带有蓝色渐变的静态控件使用双缓冲绘制,使用GDI, in 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 XP 上工作,使用 MS Visual Studio C++ 和纯 Win32 API。

我的 CPU 是单核 (2,67 GHz),我有 768 MB 的 RAM。

重要更新:

当我打开时Task Manager,我可以看到我的应用程序的内存消耗猛增。

它永远不会下降,它总是会增长,尤其是当我调整窗口大小时。

可以在下面找到我为解决这个问题所做的努力的详细描述。

我决定听取更有经验和更好的开发人员的建议,并将提供演示项目的链接。

注意:由于 VS 的 Express 版没有资源编辑器,因此资源文件和资源头是使用ResEdit从这里http://www.resedit.net/创建的。

这是演示项目的链接(所有必要的评论和解释都在项目评论中):http ://www.uploadmb.com/dw.php?id=1382012579 。

我为解决问题所做的努力:

通过 Internet、SO 存档、CodeProject 和 CodeGuru 浏览,我无法看到问题所在 - 似乎(我也相信)双缓冲的原理GDI+GDI相同的。

重要更新:

我已经VLDhttp://vld.codeplex.com/下载,按照他们的说明进行操作,但VLD没有检测到任何内存泄漏。

另外,我已经制作了项目的副本并删除了静态控件,只留下了窗口的背景以方便我的调试。

上面描述的内存消耗仍然会发生。

它似乎只有在我不绘制徽标时才会停止。

问题:

由于这是我第一次使用,鉴于释放/删除某些对象或类似的东西(所有用于绘制的代码都已提交)GDI+,我是否缺少某些东西?GDI+GDI+WM_PAINT

同样,我相信我的其他绘画代码效果很好,但如果需要,我会发布它。

更新:

关于上面提供的更新,我应该如何解决上面描述的内存消耗过多的问题?

有人可以查看上面提供的小型演示项目,并尝试给我有用的建议吗?

谢谢你。

问候。

4

2 回答 2

1

问题已通过此链接中的详细解释得到解决:http: //www.codeproject.com/Questions/666738/Window-produces-flicker-like-slow-repainting-like

如果该链接失效,这就是我必须做的:

  1. 将我的左侧徽标调整为适当的尺寸;

  2. 删除一些我错过的内存泄漏;

  3. 使Image对象全局化;

第三个动作是最重要的,因为每次调用主窗口的过程时我都会重复加载巨大的图像,最终完全消耗内存。

希望这对将来的人有所帮助。

于 2013-11-01T12:16:38.127 回答
0

不要使用多个 GDI+ 的 Graphics 对象。另请注意,在您将位图复制回真实 DC 后,此 Graphics 对象的解构会运行。Thios 也可能引起副作用。

将所有使用的 Graphics 对象放在自己的块中,以便在将 mem DC 复制回绘图 DC 之前进行解构。

于 2013-10-11T08:18:06.087 回答