使用: Delphi XE2,VCL32位应用程序,Windows8
我正在尝试将框架的背景绘制到一个面板上(我使用的是TJvPanel,因为它公开了OnPaint事件),它是框架的子控件。
在阅读了this post并添加了一个画布作为字段后,我仍然没有成功。
调用ShowAddReceiptPanel后,它应该在前景面板上绘制框架的(TfrmMyFrame)窗口内容,其中所有控件(包括网格和页面控件)在ProEffectImage方法处理后都是灰色的,但它显示的是不透明的白色背景。我是不是遗漏了什么?
下面是我的代码:
type
TfrmMyFrame = class(TFrame)
pnlHdr: TPanel;
pnlAddNewBG: TJvPanel;
procedure pnlAddNewBGPaint(Sender: TObject);
private
{ Private declarations }
FBGImg: TProEffectImage;
Fcnvs: TCanvas;
procedure PaintWindow(DC: HDC); override;
procedure ShowAddReceiptPanel;
procedure HideAddReceiptPanel;
procedure ResizePanel_pnlAddNewBG;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
constructor TfrmMyFrame.Create(AOwner: TComponent);
begin
inherited;
FBGImg := TProEffectImage.Create(nil);
Fcnvs := TCanvas.Create;
end;
destructor TfrmMyFrame.Destroy;
begin
if Assigned(FBGImg) then
FBGImg.Free;
if Assigned(Fcnvs) then
Fcnvs.Free;
inherited;
end;
procedure TfrmMyFrame.ShowAddReceiptPanel;
begin
ResizePanel_pnlAddNewBG;
pnlAddNewBG.Visible := True;
end;
procedure TfrmMyFrame.PaintWindow(DC: HDC);
begin
inherited;
Fcnvs.Handle := DC;
end;
procedure TfrmMyFrame.pnlAddNewBGPaint(Sender: TObject);
var
l, t, w, h: Integer;
srct, drct: TRect;
begin
// Copy Frame canvas to BGImg bitmap
l := 0;
t := pnlHdr.Height;
w := ClientWidth;
h := ClientHeight - t;
srct := TRect.Create(l, t, w, h);
FBGImg.Width := w;
FBGImg.Height := h;
drct := TRect.Create(l, t, w, h);
FBGImg.Canvas.CopyMode := cmSrcCopy;
FBGImg.Canvas.CopyRect(drct, Fcnvs, srct);
// FBGImg.Picture.SaveToFile('c:\tmp\a.bmp');
FBGImg.Effect_AntiAlias;
FBGImg.Effect_GrayScale;
// Draw BGImg onto Option panel
TJvPanel(Sender).Canvas.CopyMode := cmSrcCopy;
TJvPanel(Sender).Canvas.Draw(0, 0, FBGImg.Picture.Graphic);
end;
procedure TfrmMyFrame.ResizePanel_pnlAddNewBG;
var
x1, y1, x2, y2: Integer;
bmp: TBitmap;
begin
x1 := 0;
y1 := pnlHdr.Height;
x2 := ClientWidth;
y2 := ClientHeight - y1;
pnlAddNewBG.SetBounds(x1, y1, x2, y2);
end;发布于 2013-04-05 18:55:47
分配给画布句柄的DC仅在PaintWindow调用期间有效。当它无效时,你可以在该函数外部使用它,因此你观察到的行为。
我认为您应该能够通过调用PaintTo方法来解决您的问题。创建一个大小合适的位图,并将其画布传递给PaintTo。
发布于 2013-04-05 19:16:15
TFrame没有画布。您可以像TCustomControl那样创建/添加一个,但您不必这样做。画布只是Windows设备上下文的一个方便的包装器。每当必须(部分)重绘帧时,都会调用PaintWindow例程。该参数显示了DC,或者您可以使用GetDC获得一个DC。
那么伪代码将如下所示:
procedure TfrmMyFrame.PaintWindow(DC: HDC);
begin
- Resize BG image and hide it (otherwise image itself will be copied too)
- Paint the frame's contents to the image with:
Self.PaintTo(FBGImg.Canvas.Handle, 0, 0)
- Process the special effects on FBGImg
- Paint the image onto DC with:
BitBlt(DC, 0, 0, ClientWidth, ClientHeight, FBGImage.Canvas.Handle, 0, 0, SRCCOPY);
end;发布于 2015-02-06 23:29:58
访问TFrame上的Canvas的一种简单方法是使用Align := alClient并使用其Canvas属性在其上添加一个TPaintBox。
我希望这个方法可以在任何版本的Delphi中工作,也是在将来,因此可以使用它来代替PaintWindow方法,后者似乎很棘手。
https://stackoverflow.com/questions/15831932
复制相似问题