给MDI主窗口加背景  
 
在MDI程序中,由于MDI的主窗口一般的功能是提供子窗口显示的位置和提供菜单、工具条、状态条等,而窗口的客户区则一般不会有其它的用途,如果在这里画上一些软件的标志、公司的标志或者其它的背景图案的话,不仅可以使MDI的主窗口更加充实、美观,而且还可以更加突出公司的形象和增加公司标志在客户心中的地位。
    由于MDI主窗口的特性,使用普通OnPaint和使用TImage等方法都不会产生作用。下面将用编写一个简单的MDI程序来介绍如何实现。
    第一步:打开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。
    现在你可以编译运行这个程序,你会发现,Image元件并不会在Form上显示出来,但是整个Form的客户区域被Image中的图像所铺满。

解决方案 »

  1.   


        在MDI程序中,由于MDI的主窗口一般的功能是提供子窗口显示的位置和提供菜单、工具条、状态条等,而窗口的客户区则一般不会有其它的用途,如果在这里画上一些软件的标志、公司的标志或者其它的背景图案的话,不仅可以使MDI的主窗口更加充实、美观,而且还可以更加突出公司的形象和增加公司标志在客户心中的地位。     由于MDI主窗口的特性,使用普通OnPaint和使用TImage等方法都不会产生作用。下面将用编写一个简单的MDI程序来介绍如何实现。     第一步:打开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。
      

  2.   

    你把楼上的程序稍微修改一下不就是了。
    他有个循环就是为了连续画的,你把这个循环去掉不就行了。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, (ClientWidth - Image1.Picture.Width) /2 , (ClientHeight - Image1.Picture.Height) /2 , 
                    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;
      

  3.   

    BitBlt(MyDC, (ClientWidth - Image1.Picture.Width) div 2 , (ClientHeight - Image1.Picture.Height) div 2 ,忘了pascal的整数除法是 div了
      

  4.   

    delphi 6 中可以直接放image控件,可上面却一块?
    ================================================================CSDN 论坛助手 Ver 1.0 B0402提供下载。 改进了很多,功能完备!★  浏览帖子速度极快![建议系统使用ie5.5以上]。 ★  多种帖子实现界面。 
    ★  保存帖子到本地[html格式]★  监视您关注帖子的回复更新。
    ★  可以直接发贴、回复帖子★  采用XML接口,可以一次性显示4页帖子,同时支持自定义每次显示帖子数量。可以浏览历史记录! 
    ★  支持在线检测程序升级情况,可及时获得程序更新的信息。★★ 签名  ●  
         可以在您的每个帖子的后面自动加上一个自己设计的签名哟。Http://www.ChinaOK.net/csdn/csdn.zip
    Http://www.ChinaOK.net/csdn/csdn.rar
    Http://www.ChinaOK.net/csdn/csdn.exe    [自解压]
      

  5.   


    procedure TMainFrm.DrawStretched;//拉伸
    var
      CR: TRect;
    begin
      GetWindowRect(ClientHandle, CR);
      StretchBlt(FDrawDC, 0, 0, CR.Right, CR.Bottom,
                 imgMain.Picture.Bitmap.Canvas.Handle, 0, 0,
                 imgMain.Picture.Width, imgMain.Picture.Height, SRCCOPY);
    end;procedure TMainFrm.DrawCentered;//局中
    var
      CR: TRect;
    begin
      GetWindowRect(ClientHandle, CR);
      with imgMain do
        BitBlt(FDrawDC, ((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);
    end;procedure TMainFrm.DrawTiled;//平铺
    var
      Row, Col: Integer;
      CR, IR: TRect;
      NumRows, NumCols: INteger;begin
      GetWindowRect(ClientHandle, CR);
      IR := imgMain.ClientRect;
      NumRows := CR.Bottom div IR.Bottom;
      NumCols := CR.Right div IR.Right;
      with imgMain do
        for Row :=0 to NumRows+1 do
          for Col :=0 to NumCols+1 do
            BitBlt(FDrawDC, Col*Picture.Width, Row*Picture.Height,
                            Picture.Width, Picture.Height,
                            Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
    end;procedure TMainFrm.ClientWndProc(var Message: TMessage);
    begin
      case Message.Msg of
      WM_EraseBKGnd:
        begin
          CallWindowProc(FoldClientProc, ClientHandle, Message.Msg,
                         Message.WParam, Message.LParam);
          FDrawDC := TWMEraseBKGnd(Message).DC;
          DrawStretched;  //拉伸
          //DrawCentered;   //居中
          //DrawTiled;      //平铺
          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;procedure TMainFrm.FormCreate(Sender: TObject);
    begin
      FNewClientProc := MakeObjectInstance(ClientWndProc);
      FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
      SetWindowLong(ClientHandle,GWL_WNDPROC,LongInt(FNewClientProc));
    end;
      

  6.   

    lxlsky(lxl)调用的方法把图像拉大到form1整个client区,只要不拉它(这更容易),并使其居中就行了.