gpt4 book ai didi

c# - 如何在 OnPaint() 事件中获取需要绘制的确切区域?

转载 作者:行者123 更新时间:2023-11-30 12:11:59 26 4
gpt4 key购买 nike

WinForm 应用程序中,当订阅 OnPaint() 事件时,PaintEventArgs 提供一个 ClipRectangle 属性定义要绘制的区域。

当表单垂直或水平调整大小时,它会给出要绘制的最小矩形。

enter image description here

但是当窗口在两个方向上调整大小时,有几个区域需要绘制(一个在右边,一个在底部)和OnPaint事件合并它们。它会生成一个与 Form 大小相同的矩形(因此所有内容都会重绘)。我想要的是单独的区域(图片上的两个矩形)

enter image description here

我知道 GDI+ 会自动剪辑不需要绘制的内容(东西在两个矩形之外,而不仅仅是 ClipRectangle),但我想最小化GDI+ 调用最多(我在 OnPaint 事件中绘制时已经遇到性能问题,因为许多 GDI+ 调用,这不是过早的优化)

最佳答案

Windows 中的绘画由 WM_PAINT 消息处理程序启动。它必须调用 BeginPaint() 以获取有关需要绘制的内容的信息。它返回一个 PAINTSTRUCT 类型的结构,它看起来像这样:

typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint; // <=== here
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;

rcPaint 成员是您从 Graphics.ClipRectangle 获得的成员。 Graphics.Clip 和 Graphics.ClipBounds 属性不相关,它们仅在您通过分配 Clip 属性有意剪辑自己时才起作用。

显然,Windows 本身不会让您了解您的要求。 rcPaint 是一个 RECT,一个简单的矩形。 Windows 只跟踪脏矩形,而不是区域。 InvalidateRect() 添加的新矩形与现有矩形合并,您确实很容易得到整个客户区。

解决此问题的唯一合理方法是注意 ResizeBegin 和 ResizeEnd 事件。当您获得 ResizeBegin 时,您就知道用户正在拖动窗口边缘或角落。可用于优化绘画的知识,跳过使模态调整大小循环效果不佳的昂贵位。

关于c# - 如何在 OnPaint() 事件中获取需要绘制的确切区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14382631/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com