2012-04-11 14 views
3

我可以在不失效的情況下找到所有GDIPlus演示代碼。那麼,如何在TScrollbox上使用帶有TImage的MouseMove進行繪製時,如何使GDIPlus API中的矩形無效?如何使用GDIPlus進行InvalidateRect

function NormalizeRect (R: TRect): TRect; 
begin 

    // This routine normalizes a rectangle. It makes sure that the Left,Top 
    // coords are always above and to the left of the Bottom,Right coords. 

    with R do 
    begin 

    if Left > Right then 
     if Top > Bottom then 
     Result := Rect (Right, Bottom, Left, Top) 
     else 
     Result := Rect (Right, Top, Left, Bottom) 
    else if Top > Bottom then 
     Result := Rect (Left, Bottom, Right, Top) 
    else 
     Result := Rect (Left, Top, Right, Bottom); 

    end; 

end; 

procedure TFormMain.Image1MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
begin 
    if Line1.Down then 
    begin 
    GPPointStart := MakePoint (X, Y); 
    end; 
end; 

procedure TFormMain.Image1MouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer); 
var 
    graphics: TGPGraphics; 
    pen: TGPPen; 
    SolidBrush: TGPSolidBrush; 
    rgbTriple: windows.RGBTRIPLE; 
    iRect: TRect; 
begin 
    if Line1.Down then 
    begin 
    if ssLeft in Shift then 
    begin 
     iRect := NormalizeRect (Rect (X, Y, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height)); 
     InvalidateRect (ScrollBox1.Handle, @iRect, TRUE); 
     graphics := TGPGraphics.Create (Image1.Picture.Bitmap.Canvas.Handle); 
     graphics.Flush (FlushIntentionFlush); 
     GPPointEnd := MakePoint (X, Y); 
     rgbTriple := ColorToRGBTriple (ColorBox1.Selected); 
     pen := TGPPen.Create (MakeColor (StrToInt (Alpha1.Text), rgbTriple.rgbtRed, rgbTriple.rgbtGreen, rgbTriple.rgbtBlue) 
     ); 
     pen.SetWidth (StrToInt (Size1.Text)); 
     graphics.DrawLine (pen, GPPointStart.X, GPPointStart.Y, GPPointEnd.X, GPPointEnd.Y); 
     graphics.Free; 
     Image1.Refresh; 
    end; 
    end; 
end; 

這是什麼樣子: enter image description here

使用GDIPlus圖書館從http://www.progdigy.com與2010年德爾福

回答

6

InvalidateRect命令無關與GDI +。這是一個命令,告訴操作系統窗口的某個部分無效並應重新繪製。當操作系統接下來決定重新繪製窗口時,程序可以詢問操作系統有多少窗口需要繪畫。

你的代碼是調用InvalidateRect,然後它畫在窗口的相同部分。但是,該窗口仍然無效,因此當您下一步處理wm_Paint消息時,操作系統會要求您的程序稍後重新繪製該區域。

我不知道爲什麼你會希望你的圖像看起來有什麼不同,它與無效的滾動框無關。它看起來像你點擊角色的眼睛,並順時針拖動鼠標和右側。

在每次鼠標移動時,都會繪製一條從原點到當前鼠標位置的新線條。您直接在當前顯示的位圖上繪製線條,然後讓圖像控件重繪自己。它服從並繪製位圖 - 您剛添加另一行的位圖。

我懷疑你發生是每個鼠標的移動導致一個黑線出現在原本未受污染的圖像。 InvalidateRect對此沒有幫助。您需要重繪原始圖像上一行的位置,然後繪製新行。 InvalidateRect不能幫助您「撤消」以前的圖形操作。它只是告訴操作系統某個時間窗口的某個部分應該重新繪製。它沒有說明那些失效的像素應該用重新粉刷。這就是wm_Paint的用途。

+0

感謝您的回答。我明白你在告訴我什麼,但我仍然不知道如何解決它。還有什麼建議? – Bill 2012-04-11 21:00:33

+0

不是繪製到位圖,而是繪製到滾動框。這使得位圖不受影響。使舊線區失效。刷新以在舊線上繪製圖像。然後畫出新的線。如果您需要更多幫助,請提出一個關於您真正想要做什麼的新問題。 – 2012-04-11 21:14:44

+0

@Rob,*不是繪製到位圖,而是繪製到滾動框*,「TScrollBox」沒有可以繪製的畫布。當你考慮內容滾動時,它甚至不是一個好主意。我想你的意思是*而不是繪製到圖像,繪製到位圖*不是嗎? – TLama 2012-04-11 22:47:48