在WinForm
应用程序中,订阅OnPaint()
个活动时,PaintEventArgs
会提供一个ClipRectangle
属性,用于定义要绘制的区域。
当表格垂直或水平调整大小时,它会给出最小的矩形。
但是当窗口在两个方向上调整大小时,需要绘制几个区域(一个在右侧,一个在底部)和OnPaint
事件合并它们。它产生一个与Form
大小相同的矩形(因此一切都是重绘的)。我想要的是单独的区域(图片上的两个矩形)
我知道GDI+
自动剪辑不需要绘制的内容(事物在两个矩形之外,而不仅仅是ClipRectangle
),但我想最小化GDI+
个调用最多(由于许多OnPaint
调用,我在GDI+
事件中绘制时已经出现性能问题,这不是过早的优化)
答案 0 :(得分:3)
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时,您就会知道用户正在拖动窗口边缘或角落。你可以用来优化绘画的知识,跳过昂贵的部分,使模态调整大小循环工作不佳。