2016-01-27 23 views
0

當我看着TWinControl時,CanvasclBtnFace填充,然後調用WM_PAINT。這導致我不需要的不可避免的閃爍。此外,給定的畫布允許繪製滾動條,使滾動條在WM_PAINT事件之後重繪,並創建更多閃爍。Delphi創建繪畫事件畫布問題

GetMetrics和內部滾動條信息給出了真正的畫布大小。糾正我,如果我錯了,但我明白一個HDC是窗體上有一個矩形畫布上打印的句柄。所以我想:

  1. 如何創建一個新的HDC具有較小的寬度和高度,而不是移動左上角。如果可能,我想通過不使用WM_ERASEBKGND消息來刪除閃爍,並且不通過分配新大小的HDC而不通過滾動條打印,然後使用正確的HDC設置Delphi畫布手柄。

  2. 使用Windows位圖,我不知道是否應該使用並將位圖畫布大小設置爲BitBlt()複製爲TWinControl(下)。

    DC := GetDC(0); 
    MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom); 
    ReleaseDC(0, DC); 
    MemDC := CreateCompatibleDC(0); 
    OldBitmap := SelectObject(MemDC, MemBitmap); 
    try 
        DC := BeginPaint(Handle, PS); 
        Perform(WM_ERASEBKGND, MemDC, MemDC); 
        Message.DC := MemDC; 
        WMPaint(Message); 
        Message.DC := 0; 
        BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY); 
        EndPaint(Handle, PS); 
    finally 
        SelectObject(MemDC, OldBitmap); 
        DeleteDC(MemDC); 
        DeleteObject(MemBitmap); 
    end; 
    

我不知道該怎麼選擇是在一個無閃爍效果更好,如何實現它在Delphi。

+1

因此,您正在編寫一個自定義的TWinControl,並且您顯示的代碼塊是paint方法?你如何使這個問題更清楚一點,這是一團糟。或者你在Paintbox中繪畫? –

+1

你正在推翻一些東西。如果你所說的是真實的,那麼所有標準控件都會有閃爍現象,正如你所描述的那樣。那明顯是錯的。不管是什麼導致你的閃爍問題可能在你自己的繪圖代碼中,而不是在TWinControl如何管理它的Canvas中。請顯示您遇到問題的實際代碼。 –

+1

我們需要一個[mcve]給你提供幫助 –

回答

1

...的Canvas被削除與clBtnFace ...

的背景顏色是可調節的設置Brush.Color

然後調用WM_PAINT。這導致不可避免的閃爍...

這可以通過繞過WM_ERASEBKGND消息來阻止。

如何創建一個寬度和高度較小的新的HDC

這是不可能的。設備上下文沒有大小。它只受託管它的窗口限制。

指定的畫布允許在滾動條上繪圖,使滾動條在WM_PAINT事件之後重繪。

原生滾動條由系統在WM_NCPAINT中繪製。如果你可以畫出它們,那麼你已經獲得了整個窗口的設備上下文,而不是客戶端空間。

但總的來說,解決方案非常簡單:不要超出窗口的客戶區域。

作爲提示:我建議您從TCustomControl而不是TWinControl獲得控件,因爲該類已經有一個可以繪製的畫布,可以消除所有的WinAPI代碼。

+0

是TCustomControl的後裔,Remy Lebeau我不知道從哪裏開始,我不知道API調用,當我讀到原始或範圍時,我不知道這意味着什麼。 WM_ERASEBKGND消息是我需要擺脫的! NGLN。我可以使用標準的RecreateWin,並且我的手柄堅如磐石,但是如我所解釋的那樣,它會嚴重閃爍。事實上,我已經在mousedown和keydown上使用了帆布手柄,但不推薦它。您不能在繪畫事件中創建的線程運行句柄。 –

+0

我仍然有兩個設計選項,使用空白畫布和複製,或者在填充之前填充它,然後將其重新填充。 –

+0

也'DC:= GetDC(0);'使用0不會讓我感覺到。 –