在 Winforms 中,可以創建一個不是矩形的區域并以這種方式使其無效:
Region region = new Region(new Rectangle(...));
region.Union(new Rectangle(...));
Invalidate(region);
然后,在OnPaint()事件中,只會再次繪制上面無效的區域:
protected override void OnPaint(PaintEventArgs e)
{
//will only repaint the region invalidated above
//even if ClipRectangle area is bigger than that
e.Graphics.FillRectangle(Brushes.Blue, e.ClipRectangle);
}
內部OnPaint()事件,有沒有辦法檢查給定的矩形是否與無效區域相交?
我可以使用,rectangle.Intersect(e.ClipRectangle)但這可能會產生誤報。
編輯:似乎我想要的可以使用GetUpdateRgn Win32 函式(AFAIK 沒有直接的 Winforms 等效函式)
uj5u.com熱心網友回復:
private List<Rectangle> rectangleList;
當您無效時,您設定您的矩形串列:
rectangleList = getRectangles(...);
Region region = new Region(new Rectangle(...));
foreach(Rectangle rect in rectangleList)
{
region.Union(rect);
}
Invalidate(region);
在paint方法中,檢查矩形串列中的矩形是否相交,然后清除它:
protected override void OnPaint(PaintEventArgs e)
{
bool intersection = false;
foreach(Rectangle rect in rectangleList)
{
if(e.ClipRectangle.Intersect(rect)
{
intersection = true;
break;
}
}
if(intersection)
{
rectangleList.Clear();
DoIntersectionStuff();
}
else
{
DoNonIntersectionStuff();
}
}
uj5u.com熱心網友回復:
我回答我自己的問題:
可以通過呼叫GetUpdateRgn()WM_PAINT 事件中的函式,在BeginPaint()呼叫之前獲取更新區域。要知道矩形是否在區域內,請使用IsVisible()方法。這是一個 GDI api 呼叫(與 不同Rectangle.Intersect()),因此它通常與直接呼叫 GDI 繪圖函式一樣慢(例如DrawText():),并在必要時讓 GDI 完成丟棄作業。
private Region region;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_PAINT:
region = null;
IntPtr hrgn = CreateRectRgn(0, 0, 0, 0);
try
{
int result = GetUpdateRgn(Handle, hrgn, false);
if (result == SIMPLEREGION || region == COMPLEXREGION)
{
region = Region.FromHrgn(hrgn);
}
}
finally
{
DeleteObject(hrgn);
}
break;
}
base.WndProc(ref m);
}
protected override void OnPaint(PaintEventArgs e)
{
var rectangle = ...
if (region != null && region.IsVisible(rectangle))
{
//...
}
}
這是本機 win32 函式宣告:
[DllImport("gdi32.dll")]
static extern IntPtr CreateRectRgn(int left, int top, int right, int bottom);
[DllImport("user32.dll")]
static extern int GetUpdateRgn(IntPtr hWnd, IntPtr hRgn, bool bErase);
[DllImport("gdi32.dll")]
static extern bool DeleteObject(IntPtr hObject);
const int WM_PAINT = 0x000F;
const int SIMPLEREGION = 2;
const int COMPLEXREGION = 3;
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/377597.html
