Using: Delphi XE2, VCL 32-bit application, Windows 8
I'm trying to paint the background of my frame onto a panel (I'm using TJvPanel, because it exposes the OnPaint event) which is a child control of the frame.
After reading this post and adding a canvas as a field, I am still not successful.
After calling ShowAddReceiptPanel, it should draw the frame's (TfrmMyFrame) window contents with all the controls already on it (which include a grid and a pagecontrol) on the foreground panel, grayscaled, after being processed by the ProEffectImage method, but instead it shows an opaque white background. Am I missing something?
Here's my code:
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;
The DC that you assign to your canvas handle is only valid during the PaintWindow call. You use it outside that function when it is not valid and hence the behaviour that you observe.
I think that you should be able to solve your problem by calling the PaintTo method. Create a bitmap of the right size and pass its canvas to PaintTo.