2013-01-17 53 views
4

WinForm申請中,當訂閱OnPaint()事件時,PaintEventArgs提供了定義要繪製的區域的ClipRectangle屬性。如何獲得需要在OnPaint()事件中繪製的確切區域?

當窗體被垂直或水平調整大小時,它會給出要繪製的最小矩形。

enter image description here

但是,當在兩個方向上需要被延伸(一個在右邊,一個在底部)和OnPaint事件將它們合併,有幾個地區的調整窗口。它會產生一個與Form大小相同的矩形(因此一切都會重繪)。我想有個別地區分開(兩個在圖片矩形)是

enter image description here

我知道GDI+自動剪輯​​什麼不需要被延伸(東西兩個矩形之外,不只是ClipRectangle),但我想(我已經有性能問題,因爲許多GDI+電話OnPaint事件繪圖時,以儘量減少在最大GDI+呼叫,這是不是

回答

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時,您知道用戶正在拖動窗口邊緣或角落。您可以使用這些知識來優化繪畫,避免使用模塊化調整大小循環的昂貴位。

+1

就像這個答案很清楚,因爲它也解釋了事情是如何在低層完成的。還有:基本上你是告訴我這是不可能的,因爲windows/gdi的工作方式?基本上這很糟糕,感覺像是一個很大的限制。 – tigrou