2012-04-11 3 views
3

Все демо-код GDIPlus Я могу найти ничьи без аннулирования. Итак, как вы аннулируете прямоугольник в API GDIPlus при рисовании с помощью MouseMove с TImage в TScrollbox?Как InvalidateRect With GDIPlus

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 с Delphi 2010.

ответ

6

Команда InvalidateRect не имеет ничего общего с GDI +. Это команда, которая сообщает ОС, что некоторая часть окна недействительна и должна быть перекрашена. Когда ОС в следующий раз решит перекрасить это окно, программа может спросить ОС, сколько из окна требуется для рисования.

Ваш код вызывает InvalidateRect, а затем он рисует ту же часть окна. Окно по-прежнему недействительно, поэтому ОС предложит вашей программе перекрасить эту область позже, когда вы выполните следующее: wm_Paint.

Я не знаю, почему вы ожидаете, что ваше изображение будет выглядеть иначе, и это не имеет никакого отношения к аннулированию окна прокрутки. Похоже, вы нажали на глаз персонажа, и потащили мышь вниз и направо, по часовой стрелке.

При каждом движении мыши вы рисуете новую строку от исходной пинты до текущей позиции мыши. Вы рисуете линию непосредственно на отображаемом в данный момент растровом изображении, а затем попросите элемент управления изображением перерисовать себя. Он подчиняется и рисует растровое изображение - это растровое изображение, которое вы только что добавили еще одну строку.

Я подозреваю, что вы предназначены случиться были для каждого движения мыши, чтобы привести один черной линии появляться над иначе незапятнанными изображениями. InvalidateRect не поможет. Вам нужно перерисовать исходное изображение по сравнению с предыдущей позицией линии и нарисовать новую строку. InvalidateRect не поможет вам «отменить» предыдущую графическую операцию. Он просто сообщает ОС, что некоторая часть окна должна быть перекрашена когда-нибудь. Он не говорит, какие цвета эти недействительные пиксели должны быть перекрашены с. Вот что такое wm_Paint.

+0

Спасибо за ответ. Я понимаю, что вы мне говорите, но я до сих пор не знаю, как это исправить. Больше советовать? – Bill

+0

Вместо того, чтобы рисовать в растровое изображение, нарисуйте его в окне прокрутки. Это оставляет растровое изображение нетронутым. Недействительность старой области. Обновите, чтобы изображение закралось по старой строке. Затем нарисуйте новую строку. Если вам нужна дополнительная помощь, задайте новый вопрос о том, что вы действительно пытаетесь сделать. –

+0

@Rob, * вместо того, чтобы рисовать в растровое изображение, рисовать в поле прокрутки *, 'TScrollBox' не имеет холста, на котором вы можете рисовать. И это даже не будет хорошей идеей, если вы рассмотрите прокрутку контента. Наверное, вы имели в виду * вместо того, чтобы рисовать изображение, рисовать в растровое изображение, не так ли? – TLama

Смежные вопросы