2011-01-14 13 views
1

こんにちはすべて TWinControlから派生した新しいコンポーネントを作成しました。 TPanelに貼り付けて、パネルのPaintToという手続きを呼び出そうとしました。その結果、パネルとキャプションが表示され、コンポーネントはキャンバスにまったく塗りつぶされません。これについて何をすべきですか?私のコンポーネントでPaintToが動作しない

ソース(親愛なるダビデは尋ねたとして)の一部:あなたは本当に今までPaintToを呼び出すか、上書きする必要はありません

Procedure TApListBox.Paint; 
var 
    C: TCanvas; 
    B: TBitmap; 
    ItemClient: TPoint; 
Begin 
    Try 
    If (FUpdating > 0) Then 
     Exit; 
    Try 
     BeginUpdate; 
     B := TBitmap.Create; 
     B.Width := Width; 
     B.Height := Height; 
     With B.Canvas Do Begin 
     Lock; 
     // Begin : 
     ItemClient := Point(IVisPanel + 3, 2); 

     // Draw Items 
     PaintItems(B.Canvas, ItemClient); 
     Unlock; 
     End; 

     C := TCanvas.Create; 
     C.Handle := GetWindowDC(Self.Handle); 
     C.Lock; 
     inherited; 
     C.Draw(1, 1, B); 
     If (RenameEdit.Visible) Then 
     RenameEdit.Repaint; 
    Finally 
     C.Unlock; 
     ReleaseDC(0, C.Handle); 
     C.Free; 
     B.Free; 
     Dec(FUpdating); 
    End; 
    Except 
    End; 
End; 
+0

コントロールはどのようにして塗装されますか? –

+0

パネル、そのキャプション、*と*あなたのコントロールがペイントされていない場合、どうしてあなたのコントロールではなく、パネルに問題があると思いますか? –

+0

「キャンバス」のオーバーロードを使用していますか?または、 'DC'オーバーロードを使用してCanvasのハンドルを渡している場合は、キャンバスをロックしていますか? –

答えて

1

WM_PAINTメッセージを処理するメソッドでは、WM_PAINTがMessage.DCパラメータにGDIハンドル(HDC)を指定するため、Canvasを直接使用することはできません。

は期待通りにそれを扱うは、TGraphicControlから、このコードスニペットで、例えば、見てみましょう:

procedure TGraphicControl.WMPaint(var Message: TWMPaint); 
begin 
    if Message.DC <> 0 then 
    begin 
    Canvas.Lock; 
    try 
     Canvas.Handle := Message.DC; 
     try 
     Paint; // this is where the painting is done, using a "locked" Canvas 
     finally 
     Canvas.Handle := 0; 
     end; 
    finally 
     Canvas.Unlock; 
    end; 
    end; 
end; 

をだからあなたのWM_PAINTの実装方法をチェックして、このコード体系に従ってください。

上記の「ペイント」メソッドの代わりに、キャンバスプロパティを使用して独自の描画コードを配置します。

"PaintTo"メソッドが正常に動作します。

もう1つの可能性は、Message.DCハンドルを使用して直接Windows API図面を使用することです。しかし、上記の方法では、通常のCanvasを使用できるようになりました。 ;)

すべての場合、WM_PAINTは、Delphiコンポーネントがペイントを実装する場所ではなく、オーバーライドされたPaintメソッドのみを実装する場所です。したがって、コンポーネントがTGraphicControlから継承し、すべての描画コードをオーバーライドされたPaintメソッドに入れてください。

2

代わりに、オーバーライドされたPaintメソッドでペイントを100%行う必要があります。ペイントはいつでも実行でき、コンポーネントは必要に応じてペイントできる必要があります。 WindowsがWM_PAINTメッセージを送信すると、VCLはコンポーネントのPaintメソッドの呼び出しに変換されます。

コンポーネントがいつでも必要なものをペイントできることを確認し、はオーバーライドされたペイントメソッドでペイントをすべて行います。

+1

JavidがPaintToで彼のペイントを実装していたという気持ちは私には分かりませんでした。私は彼がキャンバスに描くように彼のコントロールを得たいと思ったので、彼がPaintToを呼んでいたと感じていました(これがPaintToがそこにいる理由です)。しかし私は間違っている可能性があります! –

+0

Davidが正しいです。私のコントロールは完璧に機能します。 PaintToのみを使用することはできません。 – Javid

+0

PaintToは、レポートを作成する際に非常に便利なことがあり、一部のコンポーネントをメタファイルのコンテンツに埋め込むことがあります。しかし、あなたは、WM_PAINTがDelphiコンポーネントがペイントを実装する場所ではなく、オーバーライドされたPaintメソッドのみを実装するべきであるという事実について正しいです。 –

1

ベースクラスはTCustomControlで、TWinControlではありません。前者はコントロールのキャンバスを設定しますので、Paintをオーバーライドして適切にペイントできます。

あなた自身がwm_Paintを扱うことを強く求めている場合は、WParamパラメータを表示コンテキストとして使用することを忘れないでください。正式には、そのパラメータは使用されていませんが、VCL(およびいくつかの一般的なコントロール)はDCに対してそれを使用します。これにより、wm_PrintClientメッセージの実装が簡単になります。

関連する問題