Delphi 如何访问TFrame';什么是帆布?

Delphi 如何访问TFrame';什么是帆布?,delphi,tframe,Delphi,Tframe,使用:Delphi XE2、VCL 32位应用程序、Windows 8 我试图将帧的背景绘制到一个面板上(我使用TJvPanel,因为它公开了OnPaint事件),该面板是帧的子控件 在阅读并添加画布作为字段之后,我仍然没有成功 调用ShowAddReceiptPanel后,它应该在前台面板上绘制框架的(TfrmMyFrame)窗口内容,其中包含已存在的所有控件(包括网格和页面控件),经过ProEffectImage方法处理后为灰度,但它会显示不透明的白色背景。我错过什么了吗 这是我的密码: t

使用:Delphi XE2、VCL 32位应用程序、Windows 8

我试图将帧的背景绘制到一个面板上(我使用TJvPanel,因为它公开了OnPaint事件),该面板是帧的子控件

在阅读并添加画布作为字段之后,我仍然没有成功

调用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;

分配给画布句柄的DC仅在PaintWindow调用期间有效。当它无效时,您在该函数之外使用它,从而导致您观察到的行为


我认为你应该能够通过调用这个方法来解决你的问题。创建一个正确大小的位图,并将其画布传递给PaintTo

A
t框架
没有画布。您可以像
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;

t框架
上访问
Canvas
的一个简单方法是使用
Align:=alClient
并使用其
Canvas
属性在其顶部添加一个
TPaintBox


我希望这种方法在将来也能与任何版本的Delphi一起使用,因此使用它来代替
PaintWindow
方法,这似乎很棘手。

析构函数中的if分配测试可以而且应该被删除。只需拨打免费电话,包括和指定支票。谢谢!免费包括一个指定的检查-他们什么时候引入该功能的?呃,在Delphi1中。我建议你:你只想画背景吗?或者是框架的孩子们。需要画框架的孩子们。前面板将显示其下方的黑白图像-这就是全部目的。我的第二段应该涵盖它。请您给出一个代码示例,因为我对发送消息完全陌生。还有,在我现有代码的上下文中,我应该把这个调用放在哪里?是否有painto的变体,它只绘制一个矩形(TRect),而不是整个画布?我需要省略框架顶部的一个矩形区域(包含标题面板)。GetWindowDC并不总是返回相同的DC。Oops,
GetWindowDC
确实返回非客户端部分。不仅仅是DC可以由用户提供。与“在我的位图上绘制”一样。但是,这并不能访问TFrame上的画布-它可以访问TFrame上的TPaintBox,这根本不是一回事。
TPaintBox.Canvas
在我看来是画布,就像在
PaintWindow
中创建的
Canvas
一样。我第一次使用了
PaintWindow
方法,但是遇到了字体自动更改的问题。因此,我转而使用
tpaitbox
,它很简单,并且不使用围绕Delphi代码的windowsapi。