プロジェクト(TFrame
の子孫)にフレームがあり、その上に何かをペイントしたいと思います。
フォーラムからわかるように、それを行う一般的な方法はPaintWindow
メソッドをオーバーライドすることです。
私はこれをクリーンなプロジェクトで試しました:
type
TMyFrame = class(TFrame)
private
FCanvas: TCanvas;
protected
procedure PaintWindow(DC: HDC); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy(); override;
end;
implementation
{$R *.dfm}
constructor TMyFrame.Create(AOwner: TComponent);
begin
inherited;
FCanvas := TCanvas.Create();
end;
destructor TMyFrame.Destroy();
begin
FCanvas.Free();
inherited;
end;
procedure TMyFrame.PaintWindow(DC: HDC);
begin
inherited;
FCanvas.Handle := DC;
FCanvas.Pen.Width := 3;
FCanvas.Pen.Color := clRed;
FCanvas.MoveTo(0, 0);
FCanvas.LineTo(ClientWidth, ClientHeight);
FCanvas.Pen.Color := clGreen;
FCanvas.MoveTo(ClientWidth, 0);
FCanvas.LineTo(0, ClientHeight);
end;
ただし、フレームをメインフォームに配置した後、フレームのプロパティで有効にするまで、デバッガーはこのメソッドを入力しませんでしたDoubleBuffered
。の値はParentBackground
結果に影響しませんでした。
WM_PAINT
ハンドラーをオーバーライドすると、問題も解決されます。
type
TMyFrame = class(TFrame)
protected
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
...
procedure TMyFrame.WMPaint(var Message: TWMPaint);
begin
inherited;
FCanvas.Handle := GetDC(Handle);
FCanvas.Pen.Width := 3;
FCanvas.Pen.Color := clRed;
FCanvas.MoveTo(0, 0);
FCanvas.LineTo(ClientWidth, ClientHeight);
FCanvas.Pen.Color := clGreen;
FCanvas.MoveTo(ClientWidth, 0);
FCanvas.LineTo(0, ClientHeight);
ReleaseDC(Handle, FCanvas.Handle);
end;
DoubleBuffered
このコードは、またはに割り当てられた値に関係なく、常に交差線を描画しますParentBackground
。
しかし、/の代わりに/を使用しようとするとBeginPaint
、EndPaint
問題GetDC
がReleaseDC
返されました。
procedure TMyFrame.WMPaint(var Message: TWMPaint);
var
PS: PAINTSTRUCT;
begin
inherited;
FCanvas.Handle := BeginPaint(Handle, PS);
FCanvas.Pen.Width := 3;
FCanvas.Pen.Color := clRed;
FCanvas.MoveTo(0, 0);
FCanvas.LineTo(ClientWidth, ClientHeight);
FCanvas.Pen.Color := clGreen;
FCanvas.MoveTo(ClientWidth, 0);
FCanvas.LineTo(0, ClientHeight);
EndPaint(Handle, PS);
end;
FCanvas.Handleはゼロ以外ですが、結果は空白のフレームになります。この場合、何も変更しないDoubleBuffered
か設定します。ParentBackground
多分私はそれらを間違って呼んでいますか?
このフレームで有効にしたくないので、ここで/でWM_PAINT
ハンドラーを使用します。また、他のプログラマーが私のフレームをプロジェクトに組み込んだ後に誤って無効にし、私と同じ頭痛の種になるのではないかと心配しています。GetDC
ReleaseDC
DoubleBuffered
DoubleBuffered
しかし、フレームの表面にペイントするためのより安全で正しい方法があるのではないでしょうか。