2014-12-28 3 views
0

즉석에서 폼을 만들고 캔버스에 그릴 수는 있지만 그렇게 할 수는 없습니다. 출력이 없으면 오류가 생성되지 않습니다.캔트가 폼의 캔버스에 씁니다.

다음은, 컨트롤을 클릭 주위의 양식을 이동할 때 캔버스는 모든 시간을 다시 그려야하는 간단한 테스트 코드

procedure TForm11.Button1Click(Sender: TObject); 
var 
    Fm: TForm; 
    R: TRect; 
begin 
    try 
    Fm := TForm.Create(nil); 
    Fm.Position := poScreenCenter; 
    Fm.Caption := 'Test'; 
    Fm.Width := 600; 
    Fm.Height := 400; 
    Fm.Color := clGreen; 

    Fm.Canvas.Font.Color := clBlack; 
    Fm.Canvas.Font.Size := 12; 
    Fm.Canvas.Pen.Color := clBlack; 
    Fm.Canvas.Pen.Width := 5; 
    Fm.Canvas.Brush.Color := clRed;; 
    Fm.Canvas.Brush.Style := bsSolid; 

    R.Left := 10; 
    R.Top := 10; 
    R.Width := 100; 
    R.Height := 100; 

    Fm.Canvas.TextOut(200, 10, 'Hello'); 
    Fm.Canvas.Rectangle(R); 

    Fm.ShowModal; 
    finally 
    Fm.Free; 
    end; 
end; 
+0

[델파이 7에 캔버스 기능을 사용할 수있게되지 않음 (http://stackoverflow.com/q/7147045/1699210는) – bummi

+0

WM_ERASEBKGRND은 사람 –

답변

6

입니다. 귀하의 경우에는 이미지를 그 으십시오. 그러나 그 후에는 양식이 표시되고 드로잉을 덮어 쓰면서 다시 그려집니다. 드로잉을 유지하기 위해 폼을 OnPaint 이벤트로 그릴 수 있습니다.이 이벤트는 폼을 다시 그릴 때마다 호출됩니다.

procedure TForm11.Button1Click(Sender: TObject); 
var 
    Fm: TForm; 
begin 
    Fm := TForm.Create(nil); 
    try 
    Fm.Position := poScreenCenter; 
    Fm.Caption := 'Test'; 
    Fm.Width := 600; 
    Fm.Height := 400; 
    Fm.Color := clGreen; 
    Fm.OnPaint := MyFormPaint; 

    Fm.ShowModal; 
    finally 
    Fm.Free; 
    end; 
end; 

procedure TForm11.MyFormPaint(Sender: TObject); 
var 
    Fm: TForm; 
    R: TRect; 
begin 
    FM := TForm(Sender); 

    Fm.Canvas.Font.Color := clBlack; 
    Fm.Canvas.Font.Size := 12; 
    Fm.Canvas.Pen.Color := clBlack; 
    Fm.Canvas.Pen.Width := 5; 
    Fm.Canvas.Brush.Color := clRed;; 
    Fm.Canvas.Brush.Style := bsSolid; 

    R.Left := 10; 
    R.Top := 10; 
    R.Width := 100; 
    R.Height := 100; 

    Fm.Canvas.TextOut(200, 10, 'Hello'); 
    Fm.Canvas.Rectangle(R); 
end; 

또 다른 해결책은, 비트 맵의 ​​캔버스에 그것을립니다 TImage의의 Picture 속성에 그 비트 맵을 할당하고, 폼에 TImage의를 표시하는 것입니다. 그런 다음 폼을 다시 칠할 필요가있을 때마다 각 컨트롤이 다시 그려지며 이미지는 비트 맵을 다시 그리기 때문에 볼 수 있습니다.

procedure TForm11.Button1Click(Sender: TObject); 
var 
    Fm: TForm; 
    Img: TImage; 
    B: TBitmap; 
    R: TRect; 
begin 
    Fm := TForm.Create(nil); 
    try 
    Fm.Position := poScreenCenter; 
    Fm.Caption := 'Test'; 
    Fm.Width := 600; 
    Fm.Height := 400; 

    // Add an image. Make the form the owner. That way, it is automatically 
    // discarded when you free the form in the `finally` block. 
    Img := TImage.Create(Fm); 

    // Make the form the parent too, and make sure the image covers the form. 
    Img.Parent := Fm; 
    Img.Align := alClient; 

    // Get bitmap of the picture. This will automatically create 
    // a bitmap for it too, which is managed by the image. 
    // You just have to give it the right dimensions. 
    B := Img.Picture.Bitmap; 
    B.Width := Fm.ClientWidth; 
    B.Height := Fm.ClientHeight; 

    // The image is not transparent, so you'll have to draw the green background too. 
    B.Canvas.Brush.Color := clGreen; 
    B.Canvas.FillRect(B.Canvas.ClipRect); 

    // Draw on the canvas of the bitmap. 
    B.Canvas.Font.Color := clBlack; 
    B.Canvas.Font.Size := 12; 
    B.Canvas.Pen.Color := clBlack; 
    B.Canvas.Pen.Width := 5; 
    B.Canvas.Brush.Color := clRed;; 
    B.Canvas.Brush.Style := bsSolid; 

    R.Left := 10; 
    R.Top := 10; 
    R.Width := 100; 
    R.Height := 100; 

    B.Canvas.TextOut(200, 10, 'Hello'); 
    B.Canvas.Rectangle(R); 

    Fm.ShowModal; 
    finally 
    Fm.Free; 
    end; 
end; 
+0

Golez 트롤처럼 보인다 - 귀하의 답변에 대한 감사가, 두 번째는 내 취향. 나는 이미 그 경로를 내려 가기 시작했지만 비트 맵 너비와 높이를 올바르게 설정하지 않았기 때문에 아무 것도 표시되지 않았습니다. – EssexPAL

+0

반갑습니다. 나는이 예제를 만들었을 때 처음에는 잊어 버렸지 만 다행스럽게도 그 문제에 이전에 부딪 혔고 그것을 해결하는 방법을 기억했습니다. TImage는 그림을 표시하는 방법 일 뿐이며 이미지/그림/비트 맵의 ​​크기는 자동으로 이미지 자체로 조정되지 않습니다. – GolezTrol

+1

@EssexPAL이 대답을 받아 들여야한다고 생각하지 않습니까? (더 자세히 읽으십시오 : [누군가 내 질문에 대답 할 때 무엇을해야합니까?] (http://stackoverflow.com/help/someone-answers)) –

관련 문제