第一步:打开Delphi(Delphi 1,2,3都可以),创建一个新的工程。 
    第二步:将Form1的FormStyle设置为fsMDIForm,设置成MDI的主窗口。 
    第三步:在Form1上增加一个Image元件,并选择要设置的背景到Image的Picture中。 
    第四步:在Form1的Private中定义: 
        FClientInstance, 
        FPrevClientProc : TFarProc; 
        PROCEDURE ClientWndProc(VAR Message: TMessage); 
    第五步:在实现(implementation)中加入上述过程的具体内容: 
PROCEDURE TForm1.ClientWndProc(VAR Message: TMessage); 
VAR 
  MyDC : hDC; 
  Ro, Co : Word; 
begin 
  with Message do 
    case Msg of 
      WM_ERASEBKGND: 
        begin 
          MyDC := TWMEraseBkGnd(Message).DC; 
          FOR Ro := 0 TO ClientHeight DIV Image1.Picture.Height DO 
            FOR Co := 0 TO ClientWIDTH DIV Image1.Picture.Width DO 
              BitBlt(MyDC, Co*Image1.Picture.Width, Ro*Image1.Picture.Height, 
                Image1.Picture.Width, Image1.Picture.Height, 
                Image1.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY); 
          Result := 1; 
        end; 
    else 
      Result := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam); 
    end; 
end;     第六步:在Form1的创建事件中加入: 
   FClientInstance := MakeObjectInstance(ClientWndProc); 
   FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)); 
   SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));      上面的步骤已经完成了MDI主窗口背景图案的设置,下面可以增加一个MDIChild窗口,实现MDI程序。    第七步:新增加一个Form,并将FormStyle设置为fsMDIChild。以上是我给MDI主窗口加背景的步骤,可是运行时ClientWndProc过程的Image1.Picture.Height总是会变成0值,使得ClientHeight DIV Image1.Picture.Height被0除出错!!!!
那位能试试看后告诉我为什么呢?谢谢了!

解决方案 »

  1.   

    因为ClientWndProc之前你的Image的图片还没加载
    WM_ERASEBKGND: 
            begin 
              MyDC := TWMEraseBkGnd(Message).DC;
    --
             if not Assigned(Image1.Picture.Graphic) then Image1.Picture.LoadFromFile(.....);-- 
              FOR Ro := 0 TO ClientHeight DIV Image1.Picture.Height DO 
                FOR Co := 0 TO ClientWIDTH DIV Image1.Picture.Width DO 
                  BitBlt(MyDC, Co*Image1.Picture.Width, Ro*Image1.Picture.Height, 
                    Image1.Picture.Width, Image1.Picture.Height, 
                    Image1.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY); 
              Result := 1; 
            end; 
      

  2.   

    你在form1中放一个panel.并让它充满form1,然后把image放在panel上,其它照旧
      

  3.   

    在mdi的主窗体上放panel再放image,主窗体调用的窗体显示不出来,会被panel挡住。
      

  4.   

    我都糊涂了,我是静态加载图象的,而且image1.stretch:=true;的。
      

  5.   

    解决方案步骤:
    1、循环多余!
    2、用StretchBitBlt
    3、还需要处理WM_VSCROLL和WM_HSCROLL消息,才能把“MDI背景”做好DWGZ 的if Assigned(...) 写法很好,但是也多余
      

  6.   

    private
        { Private declarations }
        FOldClientProc, FNewClientProc: TFarProc;
        procedure ClientWndProc(var Message: TMessage);
      protected
        procedure createwnd; override;implementationprocedure TMainForm.createwnd;
    begin
      inherited CreateWnd;
      FNewClientProc := MakeObjectInstance(ClientWndProc);
      FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
      SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FNewClientProc));
    end;procedure TMainForm.ClientWndProc(var Message: TMessage);
    var
      cr: TRect;
      mydc: HDC;
    begin
      case Message.Msg of
        WM_ERASEBKGND:
          begin
            CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,
              Message.wParam, Message.lParam);
            mydc := TWMEraseBkGnd(Message).DC;
            GetWindowRect(ClientHandle, CR);
            with image1 do
              BitBlt(mydc, ((CR.Right - CR.Left) - Picture.Width) div 2,
                ((CR.Bottom - CR.Top) - Picture.Height) div 2,
                Picture.Graphic.Width, Picture.Graphic.Height,
                Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
            Message.Result := 1;
          end;
        wm_vscroll, wm_hscroll:
          begin
            message.Result := callwindowproc(foldClientProc, ClientHandle,
              Message.Msg,
              Message.wParam, Message.lParam);
            invalidaterect(clienthandle, nil, True);
          end;
      else
        Message.Result := CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,
          Message.wParam, Message.lParam);
      end; 
    end;
      

  7.   

    XingXingKuaiLe(星星) :
        我用你的这段代码试了一下,程序不出错了,可是运行后,图片没有显示出来,关闭MDI主窗口时还报了个地址错误!
      

  8.   

    DWGZ:
        我的图片是静态放置的,也要这样写吗????
        我现在还是糊涂了!!!我按你的方法再试一下!
      

  9.   

    1.关于MDI主窗体背景新解
      在Form中添加Image控件 
       设BMP图象 
       name为 IMG_BK 
       在Foem的Create事件中写入 
       Self.brush.bitmap:=img_bk.picture.bitmap;
      

  10.   

    啊!我知道是什么原因了,你们不要怪我啊,是我放的图片类型不对,
    我放的是JPG图象总是不行,可是换了BMP就可以了!
    你们也没有说啊
      

  11.   

    jacky_shen(jacky) :
        你的方法也很好,简单又便捷!好了,我现在就揭贴了,谢谢你们大家的帮助!
      

  12.   

    我试过了调试了下第一次不会第二次画的时候就会原来当MDI窗体重画背景的时候把Image1 Erase掉了不知我的理解是否正确,换成下面
    另外的你的程序在主窗体Destroy的时修改应再把FPrevClientProc还原回来并且释放资源我就不写了unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, jpeg;type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        BitMap: TBitMap;
        FPrevClientProc, FNewClientProc: TFarProc;
        procedure ClientWndProc(var Message: TMessage);
      protected
        procedure createwnd; override;  end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.createwnd;
    begin
      inherited CreateWnd;
      FNewClientProc := MakeObjectInstance(ClientWndProc);
      FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
      SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FNewClientProc));
    end;procedure TForm1.ClientWndProc(var Message: TMessage);
    VAR 
      MyDC : hDC; 
      Ro, Co : Word;
    begin
      with Message do 
        case Msg of
          WM_ERASEBKGND: 
            begin 
              MyDC := TWMEraseBkGnd(Message).DC;
              FOR Ro := 0 TO (ClientHeight DIV BitMap.Height) do
                FOR Co := 0 TO (ClientWIDTH DIV BitMap.Width) DO
                  BitBlt(MyDC, Co*BitMap.Width, Ro*BitMap.Height,
                    BitMap.Width, BitMap.Height,
                    BitMap.Canvas.Handle, 0, 0, SRCCOPY);
              Result := 1;
            end;
        else 
          Result := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam);
        end;
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      BitMap := TBitmap.Create;
      BitMap.LoadFromFile('F:\1.bmp');
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      BitMap.Free;
    end;end.