楼上的说的对,要是做的话我也可以做的出。但是对这个概念感觉不是很清楚,请高手来<br>解释一下吧。我把程序贴上来<br>unit MainFrm;<br><br>interface<br><br>uses Windows, SysUtils, Classes, Graphics, Forms, Controls, Menus,<br> StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, JPeg;<br><br>type<br> TMainForm = class(TForm)<br> mmMain: TMainMenu;<br> mmiFile: TMenuItem;<br> mmiNew: TMenuItem;<br> mmiClose: TMenuItem;<br> N1: TMenuItem;<br> mmiExit: TMenuItem;<br> mmiImage: TMenuItem;<br> mmiTile: TMenuItem;<br> mmiCenter: TMenuItem;<br> mmiStretch: TMenuItem;<br> imgMain: TImage;<br> procedure mmiNewClick(Sender: TObject);<br> procedure mmiCloseClick(Sender: TObject);<br> procedure mmiExitClick(Sender: TObject);<br> procedure mmiTileClick(Sender: TObject);<br> private<br> FOldClientProc,<br> FNewClientProc: TFarProc;<br> FDrawDC: hDC;<br> procedure CreateMDIChild(const Name: string);<br> procedure ClientWndProc(var Message: TMessage);<br> procedure DrawStretched;<br> procedure DrawCentered;<br> procedure DrawTiled;<br> protected<br> procedure CreateWnd; override;<br> end;<br><br>var<br> MainForm: TMainForm;<br><br>implementation<br><br>uses MdiChildFrm;<br><br>{$R *.DFM}<br><br>procedure TMainForm.CreateWnd;<br>begin<br> inherited CreateWnd;<br> // Turn the ClientWndProc method into a valid window procedure<br> FNewClientProc := MakeObjectInstance(ClientWndProc);<br> // Get a pointer to the original window procedure<br> FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));<br> // Set ClientWndProc as the new window procedure<br> SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FNewClientProc));<br>end;<br><br>procedure TMainForm.DrawCentered;<br>{ This procedure centers the image on the form's client area }<br>var<br> CR: TRect;<br>begin<br> GetWindowRect(ClientHandle, CR);<br> with imgMain do<br> BitBlt(FDrawDC, ((CR.Right - CR.Left) - Picture.Width) div 2,<br> ((CR.Bottom - CR.Top) - Picture.Height) div 2,<br> Picture.Graphic.Width, Picture.Graphic.Height,<br> Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);<br>end;<br><br>procedure TMainForm.DrawStretched;<br>{ This procedure stretches the image on the form's client area }<br>var<br> CR: TRect;<br>begin<br> GetWindowRect(ClientHandle, CR);<br> StretchBlt(FDrawDC, 0, 0, CR.Right, CR.Bottom,<br> imgMain.Picture.Bitmap.Canvas.Handle, 0, 0,<br> imgMain.Picture.Width, imgMain.Picture.Height, SRCCOPY);<br>end;<br><br>procedure TMainForm.DrawTiled;<br>{ This procedure tiles the image on the form's client area }<br>var<br> Row, Col: Integer;<br> CR, IR: TRect;<br> NumRows, NumCols: Integer;<br>begin<br> GetWindowRect(ClientHandle, CR);<br> IR := imgMain.ClientRect;<br> NumRows := CR.Bottom div IR.Bottom;<br> NumCols := CR.Right div IR.Right;<br> with imgMain do<br> for Row := 0 to NumRows+1 do<br> for Col := 0 to NumCols+1 do<br> BitBlt(FDrawDC, Col * Picture.Width, Row * Picture.Height,<br> Picture.Width, Picture.Height, Picture.Bitmap.Canvas.Handle,<br> 0, 0, SRCCOPY);<br>end;<br><br>procedure TMainForm.ClientWndProc(var Message: TMessage);<br>begin<br> case Message.Msg of<br> // Capture the WM_ERASEBKGND messages and perform the client area drawing<br> WM_ERASEBKGND:<br> begin<br> CallWindowProc(FOldClientProc, ClientHandle, Message.Msg, Message.wParam,<br> Message.lParam);<br> FDrawDC := TWMEraseBkGnd(Message).DC;<br> if mmiStretch.Checked then<br> DrawStretched<br> else if mmiCenter.Checked then<br> DrawCentered<br> else DrawTiled;<br> Message.Result := 1;<br> end;<br> { Capture the scrolling messages and ensure the client area<br> is redrawn by calling InvalidateRect }<br> WM_VSCROLL, WM_HSCROLL:<br> begin<br> Message.Result := CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,<br> Message.wParam, Message.lParam);<br> InvalidateRect(ClientHandle, nil, True);<br> end;<br> else<br> // By Default, call the original window procedure<br> Message.Result := CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,<br> Message.wParam, Message.lParam);<br> end; { case }<br>end;<br><br>procedure TMainForm.CreateMDIChild(const Name: string);<br>var<br> MdiChild: TMDIChildForm;<br>begin<br> MdiChild := TMDIChildForm.Create(Application);<br> MdiChild.Caption := Name;<br>end;<br><br>procedure TMainForm.mmiNewClick(Sender: TObject);<br>begin<br> CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));<br>end;<br><br>procedure TMainForm.mmiCloseClick(Sender: TObject);<br>begin<br> if ActiveMDIChild <> nil then<br> ActiveMDIChild.Close;<br>end;<br><br>procedure TMainForm.mmiExitClick(Sender: TObject);<br>begin<br> Close; <br>end;<br><br>procedure TMainForm.mmiTileClick(Sender: TObject);<br>begin<br> mmiTile.Checked := false;<br> mmiCenter.Checked := False;<br> mmiStretch.Checked := False;<br> { Set the Checked property for the menu item which invoked }<br> { this event handler to Checked }<br> if Sender is TMenuItem then<br> TMenuItem(Sender).Checked := not TMenuItem(Sender).Checked;<br> { Redraw the client area of the form }<br> InvalidateRect(ClientHandle, nil, True);<br>end;<br><br>end.