Change MDI parent background

Posted in Forms

The decision consists in interception of the WM_ERASEBKGND, WM_VSCROLL and WM_HSCROLL messages and carry out draw of area by using DrawImage procedure or InvalidateRect procedure. CreateWnd procedure uses SetWindowLong procedure for installation of new procedure of a window. Don't forget to remove line Application.CreateForm(TForm2, Form2) from project file and line var Form2: TForm2 from unit2.pas file.

type
  TForm1 = class(TForm)
  ...
  private
    { Private declarations }
  public
    procedure ClientWndProc(var Message: TMessage);
    procedure DrawImage;
    { Public declarations }
  protected
    procedure CreateWnd; override;
  end;

var
  Form1: TForm1;
  NewClient, OldClient: TFarProc;
  MyDC: hDC;

implementation

uses unit2;

{$R *.DFM}

procedure TForm1.CreateWnd;
begin
  inherited CreateWnd;
  NewClient:=MakeObjectInstance(ClientWndProc);
  OldClient:=Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
  SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(NewClient));
end;

procedure TForm1.DrawImage;
{ This procedure tiles the image on the form's client area }
var
  i, j: Integer;
  WndRect, ImageRect: TRect;
  Rows, Cols: Integer;
begin
  GetWindowRect(ClientHandle, WndRect);
  ImageRect:=Image1.ClientRect;
  Rows:=WndRect.Bottom div ImageRect.Bottom;
  Cols:=WndRect.Right div ImageRect.Right;
  with Image1 do
    for i:=0 to Rows+1 do
      for j:=0 to Cols+1  do
        BitBlt(MyDC, j*Picture.Width, i*Picture.Height, Picture.Width,
          Picture.Height, Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;

procedure TForm1.ClientWndProc(var Message: TMessage);
begin
  case Message.Msg of
    WM_ERASEBKGND:
    begin
      CallWindowProc(OldClient, 
                     ClientHandle, 
                     Message.Msg, 
                     Message.wParam, 
                     Message.lParam);
      MyDC:=TWMEraseBkGnd(Message).DC;
      DrawImage;
      Message.Result:=1;
    end;
    WM_VSCROLL, WM_HSCROLL:
    begin
      Message.Result := CallWindowProc(OldClient, 
                                       ClientHandle, 
                                       Message.Msg,
                                       Message.wParam, 
                                       Message.lParam);
      InvalidateRect(ClientHandle, nil, True);
      end;
    else
      Message.Result := CallWindowProc(OldClient, 
                                       ClientHandle, 
                                       Message.Msg, 
                                       Message.wParam, 
                                       Message.lParam);
  end;
end;