【问题标题】:GDI+ Graphics object does not reflect to window resizeGDI+ 图形对象不反映窗口调整大小
【发布时间】:2011-10-23 14:50:13
【问题描述】:

我遇到了以下问题。我正在使用本机 GDI+ 在 Windows 窗体的面板表面上绘图(绘图算法在本机 DLL 内,由 P/Invoke 调用)。一切都很好,但直到一个人改变面板的大小。如果它被缩小,它被正确渲染。但是,如果它被放大,只有面板区域中与其原始大小相对应的部分会被 GDI+ 重绘。

为什么会这样?当面板调整大小时,我真的必须每次都创建新的 Graphics 对象吗?

【问题讨论】:

  • 代码可能使用了 Graphics::FromHWND()。存储该对象并在以后重用它是一个常见的错误。仅在 Windows 要求您绘制时,使用您在事件参数中获得的 Graphics 对象。它总是有一个适当的剪辑区域。
  • 为什么会这样?我必须在绘图时创建许多 GDI+ 对象,所以我存储它们并在以后重用 - 以及图形对象本身。 AFAIR,我在 MSDN 文档的某个地方读到,应该这样做是为了防止不必要的(就性能而言代价高昂)内存操作。
  • 您找到了原因,Graphics 对象不再匹配窗口的状态。您假设创建它的成本很高。不是,它只需要几十微秒。保留它只是昂贵的,不必要地使用内存。 Anyhoo,您需要在窗口状态更改时重新创建它。
  • 很遗憾您以评论而不是常规答案的形式回答,因为我现在不能接受它(当然就stackoverflow而言):)

标签: winforms resize gdi+ hwnd


【解决方案1】:

Hans Passant 在评论中回答:

You found out why, the Graphics object no longer matches the state of the window. You are assuming that it is expensive to create. It isn't, it only costs couple of dozen microseconds. It is only expensive to keep it around, needlessly using memory. Anyhoo, you need to recreate it when the window state changes.

【讨论】:

    【解决方案2】:

    假设您在面板的绘制事件中进行绘图...如果不是这样,请告诉我。

    尝试在面板调整大小时调用 .Invalidate。

    【讨论】:

    • 我正在使用重写的 OnPaint 方法进行绘制。添加 Invalidate 不会改变任何东西,重绘区域仍然裁剪为窗口的原始大小。需要明确的是:控件本身正在重绘。问题是,重绘区域被裁剪为控件的原始大小。
    猜你喜欢
    • 1970-01-01
    • 2017-03-25
    • 2023-03-06
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 2010-12-21
    • 2016-09-14
    • 1970-01-01
    相关资源
    最近更新 更多