Delphi 如何在MDI应用程序中执行图像平铺?
一年来我尝试了很多代码,但都没有100%的效果 我只需要能够把一个图像作为我的主要形式的背景,并能够平铺它 我使用的是DELPHI 2007。我假设您指的是主MDI框架窗口的客户端区域 屏幕的这一区域由MDI客户端窗口处理,因此一种方法是对MDI客户端窗口进行子类化,然后处理WM_PAINT消息。背景我假设您指的是主MDI框架窗口的客户端区域Delphi 如何在MDI应用程序中执行图像平铺?,delphi,winapi,Delphi,Winapi,一年来我尝试了很多代码,但都没有100%的效果 我只需要能够把一个图像作为我的主要形式的背景,并能够平铺它 我使用的是DELPHI 2007。我假设您指的是主MDI框架窗口的客户端区域 屏幕的这一区域由MDI客户端窗口处理,因此一种方法是对MDI客户端窗口进行子类化,然后处理WM_PAINT消息。背景我假设您指的是主MDI框架窗口的客户端区域 屏幕的这一区域由MDI客户端窗口处理,因此实现这一点的一种方法是对MDI客户端窗口进行子类化,然后处理WM_PAINT消息。我不确定它是否能工作,但我发现
屏幕的这一区域由MDI客户端窗口处理,因此实现这一点的一种方法是对MDI客户端窗口进行子类化,然后处理WM_PAINT消息。我不确定它是否能工作,但我发现 决定在于拦截 在
WM_ERASEBKGND
,WM_VSCROLL
和
WM\HSCROLL
消息并执行绘制
使用DrawImage
程序对区域进行
或程序<代码>创建WND
过程使用SetWindowLong
过程
用于安装新程序的
窗户。别忘了拆下电线
Application.CreateForm(TForm2,Form2)
从项目文件和unit2.pas文件中的行var Form2:TForm
2
我不确定它是否会起作用,但我发现了 决定在于拦截 在
WM_2;擦除bkgnd
,WM\u VSCROLL
和
WM\HSCROLL
消息并执行绘制
使用DrawImage
程序对区域进行
或程序<代码>创建WND
过程使用SetWindowLong
过程
用于安装新程序的
窗户。别忘了拆下电线
Application.CreateForm(TForm2,Form2)
从项目文件和unit2.pas文件中的行var Form2:TForm
2
您可以执行以下操作,在MDI forms OnPaint过程中添加以下内容
Canvas.Lock;
try
Canvas.Brush.Bitmap := MyImg.Picture.Bitmap;
Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight));
finally
Canvas.Unlock;
end;
但是,由于重新绘制过多,当您手动重新调整表单大小时,它仍然会闪烁。有windows消息说窗体已调整大小,您可以挂接到该窗体,并且在窗体完成调整大小之前不会更新
这些windows消息将起到以下作用:
Canvas.Lock;
try
Canvas.Brush.Bitmap := MyImg.Picture.Bitmap;
Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight));
finally
Canvas.Unlock;
end;
但是,由于重新绘制过多,当您手动重新调整表单大小时,它仍然会闪烁。有windows消息说窗体已调整大小,您可以挂接到该窗体,并且在窗体完成调整大小之前不会更新
这些windows消息将起到以下作用:
{================================================================================
Copyright (C) 1997-2002 Mills Enterprise
Unit : rmMDIBackground
Purpose : To allow an image to be placed with in the workspace area of an
MDI Form. Background colors are also available.
Date : 04-24-2000
Author : Ryan J. Mills
Version : 1.93
================================================================================}
unit rmMDIBackground;
interface
{$I CompilerDefines.INC}
uses
Windows, Messages, Classes, Forms, graphics;
type
TrmBMPDisplayStyle = (dsTiled, dsStretched, dsCentered, dsNone) ;
TrmMDIBackground = class(TComponent)
private
OldWndProc: TFarProc;
NewWndProc: Pointer;
OldMDIWndProc: TFarProc;
NewMDIWndProc: Pointer;
fBitmap: TBitmap;
fstyle: TrmBMPDisplayStyle;
fColor: TColor;
fBuffer: TBitmap;
fLastRect: TRect;
procedure SetBitmap(const Value: tBitmap) ;
procedure SetDStyle(const Value: TrmBMPDisplayStyle) ;
procedure SetMDIColor(const Value: TColor) ;
{ Private declarations }
protected
{ Protected declarations }
procedure HookWndProc(var AMsg: TMessage) ;
procedure HookWnd;
procedure UnHookWnd;
procedure HookMDIWndProc(var AMsg: TMessage) ;
procedure HookMDIWin;
procedure UnhookMDIWin;
procedure PaintImage;
public
{ Public declarations }
constructor Create(AOwner: TComponent) ; override;
destructor Destroy; override;
published
{ Published declarations }
property Bitmap: tBitmap read fBitmap write SetBitmap;
property DisplayStyle: TrmBMPDisplayStyle read fstyle write SetDStyle default dsNone;
property Color: TColor read fColor write SetMDIColor default clappWorkspace;
end;
implementation
uses rmGlobalComponentHook;
{ TrmMDIBackground }
constructor TrmMDIBackground.create(AOwner: TComponent) ;
begin
inherited;
NewWndProc := nil;
OldWndProc := nil;
OldMDIWndProc := nil;
NewMDIWndProc := nil;
fBitmap := tBitmap.create;
fbuffer := tbitmap.create;
fColor := clAppWorkSpace;
fstyle := dsNone;
fLastRect := rect(0, 0, 0, 0) ;
HookWnd;
end;
destructor TrmMDIBackground.destroy;
begin
UnHookWnd;
fBitmap.free;
fbuffer.free;
inherited;
end;
procedure TrmMDIBackground.HookMDIWin;
begin
if csdesigning in componentstate then exit;
if not assigned(NewMDIWndProc) then
begin
OldMDIWndProc := TFarProc(GetWindowLong(TForm(Owner) .ClientHandle, GWL_WNDPROC) ) ;
{$ifdef D6_or_higher}
NewMDIWndProc := Classes.MakeObjectInstance(HookMDIWndProc) ;
{$else}
NewMDIWndProc := MakeObjectInstance(HookMDIWndProc) ;
{$endif}
SetWindowLong(TForm(Owner) .ClientHandle, GWL_WNDPROC, LongInt(NewMDIWndProc) ) ;
end;
end;
procedure TrmMDIBackground.HookMDIWndProc(var AMsg: TMessage) ;
begin
with AMsg do
begin
if msg <> WM_ERASEBKGND then
Result := CallWindowProc(OldMDIWndProc, TForm(Owner) .ClientHandle, Msg, wParam, lParam)
else
result := 1;
if (msg = WM_NCPaint) or (msg = wm_Paint) then
PaintImage;
end;
end;
procedure TrmMDIBackground.HookWnd;
begin
if csdesigning in componentstate then exit;
if TForm(Owner) .formstyle <> fsMDIForm then exit;
if not assigned(NewWndProc) then
begin
OldWndProc := TFarProc(GetWindowLong(TForm(Owner) .handle, GWL_WNDPROC) ) ;
{$ifdef D6_or_higher}
NewWndProc := Classes.MakeObjectInstance(HookWndProc) ;
{$else}
NewWndProc := MakeObjectInstance(HookWndProc) ;
{$endif}
SetWindowLong(TForm(Owner) .handle, GWL_WNDPROC, LongInt(NewWndProc) ) ;
PushOldProc(TForm(Owner) , OldWndProc) ;
HookMDIWin;
end;
end;
procedure TrmMDIBackground.HookWndProc(var AMsg: TMessage) ;
begin
case AMsg.msg of
WM_DESTROY:
begin
AMsg.Result := CallWindowProc(OldWndProc, Tform(Owner) .handle, AMsg.Msg, AMsg.wParam, AMsg.lParam) ;
UnHookWnd;
exit;
end;
wm_EraseBKGND:
begin
aMsg.Result := 1;
exit;
end;
end;
AMsg.Result := CallWindowProc(OldWndProc, Tform(Owner) .handle, AMsg.Msg, AMsg.wParam, AMsg.lParam) ;
case aMsg.Msg of
WM_PAINT, // WM_ERASEBKGND,
WM_NCPaint: PaintImage;
end;
end;
procedure TrmMDIBackground.PaintImage;
var
DC: HDC;
Brush: HBrush;
cx, cy: integer;
wRect: TRect;
x, y: integer;
begin
if csdesigning in componentstate then exit;
if TForm(Owner) .FormStyle <> fsMDIForm then exit;
GetWindowRect(TForm(Owner) .ClientHandle, wRect) ;
DC := GetDC(TForm(Owner) .clienthandle) ;
try
case fstyle of
dsTiled, dsStretched, dsCentered:
begin
case fStyle of
dsTiled:
begin
cx := (wRect.right - wRect.left) ;
cy := (wRect.bottom - wRect.top) ;
y := 0;
while y < cy do
begin
x := 0;
while x < cx do
begin
bitBlt(DC, x, y, fBitmap.width, fBitmap.height,
fBitmap.canvas.Handle, 0, 0, srccopy) ;
inc(x, fBitmap.width) ;
end;
inc(y, fBitmap.Height) ;
end;
end;
dsStretched:
begin
cx := (wRect.right - wRect.left) ;
cy := (wRect.bottom - wRect.top) ;
StretchBlt(DC, 0, 0, cx, cy, fBitmap.Canvas.Handle, 0, 0, fBitmap.width, fBitmap.height, srccopy) ;
end;
dsCentered:
begin
fBuffer.width := wRect.right - wRect.left;
fBuffer.height := wRect.bottom - wRect.top;
Brush := CreateSolidBrush(ColorToRGB(fcolor) ) ;
try
FillRect(fBuffer.canvas.handle, rect(0, 0, fBuffer.width, fBuffer.height) , brush) ;
finally
DeleteObject(Brush) ;
end;
cx := (fBuffer.width div 2) - (fBitmap.width div 2) ;
cy := (fBuffer.height div 2) - (fbitmap.height div 2) ;
bitBlt(fBuffer.Canvas.handle, cx, cy, fBitmap.width, fBitmap.height,
fBitmap.Canvas.Handle, 0, 0, srccopy) ;
bitBlt(DC, 0, 0, fBuffer.width, fBuffer.height,
fBuffer.Canvas.Handle, 0, 0, srccopy) ;
end;
end;
end;
dsNone:
begin
Brush := CreateSolidBrush(ColorToRGB(fcolor) ) ;
try
FillRect(DC, TForm(Owner) .ClientRect, brush) ;
finally
DeleteObject(Brush) ;
end;
end;
end;
fLastRect := wRect;
finally
ReleaseDC(TForm(Owner) .clienthandle, DC) ;
end;
end;
procedure TrmMDIBackground.SetBitmap(const Value: tBitmap) ;
begin
fBitmap.assign(Value) ;
end;
procedure TrmMDIBackground.SetDStyle(const Value: TrmBMPDisplayStyle) ;
begin
if fstyle <> Value then
begin
fstyle := Value;
PaintImage;
end;
end;
procedure TrmMDIBackground.SetMDIColor(const Value: TColor) ;
begin
if fColor <> Value then
begin
fColor := Value;
PaintImage;
end;
end;
procedure TrmMDIBackground.UnhookMDIWin;
begin
if csdesigning in componentstate then exit;
if assigned(NewMDIWndProc) then
begin
SetWindowLong(TForm(Owner) .ClientHandle, GWL_WNDPROC, LongInt(OldMDIWndProc) ) ;
if assigned(NewMDIWndProc) then
{$ifdef D6_or_higher}
Classes.FreeObjectInstance(NewMDIWndProc) ;
{$else}
FreeObjectInstance(NewMDIWndProc) ;
{$endif}
NewMDIWndProc := nil;
OldMDIWndProc := nil;
end;
end;
procedure TrmMDIBackground.UnHookWnd;
begin
if csdesigning in componentstate then exit;
if assigned(NewWndProc) then
begin
SetWindowLong(TForm(Owner) .handle, GWL_WNDPROC, LongInt(PopOldProc(TForm(Owner) ) ) ) ;
if assigned(NewWndProc) then
{$ifdef D6_or_higher}
Classes.FreeObjectInstance(NewWndProc) ;
{$else}
FreeObjectInstance(NewWndProc) ;
{$endif}
NewWndProc := nil;
OldWndProc := nil;
end;
UnHookMDIWin;
end;
end.
{================================================================================
版权所有(C)1997-2002米尔斯企业
单位:RMMDI背景
用途:允许将图像放置在的工作区中
MDI表单。也可以使用背景色。
日期:04-24-2000
作者:Ryan J.Mills
版本:1.93
================================================================================}
单位背景;
接口
{$I CompilerDefines.INC}
使用
窗口、消息、类、窗体、图形;
类型
TrmBMPDisplayStyle=(数据文件化、数据树化、数据中心化、数据无);
TrmMDIBackground=类别(t组件)
私有的
OldWndProc:TFarProc;
NewWndProc:指针;
OldMDIWndProc:TFarProc;
NewMDIWndProc:指针;
fBitmap:TBitmap;
fstyle:TrmBMPDisplayStyle;
f颜色:t颜色;
fBuffer:TBitmap;
fLastRect:TRect;
程序设定图(常数值:tBitmap);
过程设置样式(常量值:TrmBMPDisplayStyle);
程序设置MDIColor(常量值:TColor);
{私有声明}
受保护的
{受保护的声明}
程序WNDPROC(var AMsg:TMessage);
程序挂钩;
程序解钩;
程序钩住MDIWndProc(var AMsg:TMessage);
程序性胜利;
程序解锁;
程序图像;
公众的
{公开声明}
构造函数创建(AOwner:TComponent);推翻
毁灭者毁灭;推翻
出版
{已发布声明}
属性位图:tBitmap读取fBitmap写入SetBitmap;
属性DisplayStyle:TrmBMPDisplayStyle read fstyle write SetDStyle default dsNone;
属性颜色:TColor read fColor write SetMDIColor default clappWorkspace;
结束;
实施
使用rmGlobalComponentHook;
{TrmMDIBackground}
构造函数TrmMDIBackground.create(所有者:TComponent);
开始
继承;
NewWndProc:=零;
OldWndProc:=零;
OldMDIWndProc:=零;
NewMDIWndProc:=零;
fBitmap:=tBitmap.create;
fbuffer:=tbitmap.create;
F颜色:=克拉普工作空间;
fstyle:=dsNone;
fLastRect:=rect(0,0,0,0);
钩住;
结束;
析构函数TrmMDIBackground.destroy;
开始
无忧无虑;
fBitmap.free;
fbuffer.free;
继承;
结束;
程序TrmMDIBackground.HookMDIWin;
开始
如果csdesigning处于组件状态,则退出;
如果未分配(NewMDIWndProc)