第一步:打开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除出错!!!!
那位能试试看后告诉我为什么呢?谢谢了!
第二步:将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除出错!!!!
那位能试试看后告诉我为什么呢?谢谢了!
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;
1、循环多余!
2、用StretchBitBlt
3、还需要处理WM_VSCROLL和WM_HSCROLL消息,才能把“MDI背景”做好DWGZ 的if Assigned(...) 写法很好,但是也多余
{ 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;
我用你的这段代码试了一下,程序不出错了,可是运行后,图片没有显示出来,关闭MDI主窗口时还报了个地址错误!
我的图片是静态放置的,也要这样写吗????
我现在还是糊涂了!!!我按你的方法再试一下!
在Form中添加Image控件
设BMP图象
name为 IMG_BK
在Foem的Create事件中写入
Self.brush.bitmap:=img_bk.picture.bitmap;
我放的是JPG图象总是不行,可是换了BMP就可以了!
你们也没有说啊
你的方法也很好,简单又便捷!好了,我现在就揭贴了,谢谢你们大家的帮助!
另外的你的程序在主窗体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.