可不可以在MDI的主窗口右下角放个图片? (50分)

  • 主题发起人 主题发起人 娃娃
  • 开始时间 开始时间
问题依然没有解决啊,有没有朋友帮帮手啊
 
问题依然没有解决,请高手出招!
 
//先在MDI窗口上放置两个Image,分别叫Image1,Image2
type
TFrm_MDI_Main = class(TForm)
...
Image1: TImage;
Image2: TImage;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
//below 3 lines to display a picture on the MDI client
FClientInstance : TFarProc;
FPrevClientProc : TFarProc;
procedure ClientWndProc(var Message: TMessage);
public
end;

procedure TFrm_MDI_Main.ClientWndProc(var Message: TMessage);
var
Dc : hDC;
Row : Integer;
Col : Integer;
begin
with Message do
case Msg of
WM_ERASEBKGND:
begin
Dc := TWMEraseBkGnd(Message).Dc;
for Row := 0 to ClientHeight div Image1.Picture.Height do
for Col := 0 to ClientWidth div Image1.Picture.Width do
BitBlt(Dc,
Col * Image1.Picture.Width,
Row * Image1.Picture.Height,
Image1.Picture.Width,
Image1.Picture.Height,
Image1.Picture.Bitmap.Canvas.Handle,
0,
0,
SRCCOPY);

Result := 1;

BitBlt(Dc,
ClientWidth - Image1.Picture.Width,
ClientHeight - Image1.Picture.Height + 10,
Image2.Picture.Width,
Image2.Picture.Height,
Image2.Picture.Bitmap.Canvas.Handle,
0,
0,
SRCCOPY);
end;
else
Result := CallWindowProc(FPrevClientProc,
ClientHandle,
Msg,
wParam,
lParam);
end;
end;

procedure TFrm_MDI_Main.FormCreate(Sender: TObject);
begin
FClientInstance := MakeObjectInstance(ClientWndProc);
FPrevClientProc := Pointer(GetWindowLong(ClientHandle,GWL_WNDPROC));
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));
end;
 
还是不行啊,小弟用的是Delphi6,是不是你用的是7啊?

我这里开始编译都过不去
for Col := 0 to ClientWidth div Image1.Picture.Width do
总是在这里出错,提示说“Divsion by Zero”

i := ClientHeight div Image1.Picture.Height; 《----------
j :=ClientWidth div Image1.Picture.Width;
for Row := 0 to i do
for Col := 0 to j do
我改成这样,可以编译通过,但是MDI的客户区不会自动刷新了,而且不能最小化窗口,一最小化就有同上面的提示(在用箭头标明的那些停住)。
 
另外我不明白的是,为什么要在循环的后面再来一次BitBlt?是不是你的Image控件还有什么特别的设置?

我现在是已经可以让它显示在右下角,不过一改变窗口大小,MDI的客户区刷新就有问题。
好象只会刷新改变的那部分。原来的区域不刷新,但是这样一来,就会有些脏图象在客户区了,很难看。
 
因为我用了两次图片效果,一个是用平铺Image1做MDI背景;你所说的那个就是把Image2放在右下角;
1、Image1.Picture.Width 为0的问题你加个判断就行;
2、客户区刷新问题,你在FormResize事件中再调用一下该过程就行,或把现有的
case Msg of
WM_ERASEBKGND:
改成:
case Msg of
WM_ERASEBKGND or WM_RESIZE: (不能确定是不是这么写,你可以找一下Resize消息ID)
 
补充:我的这些代码是在D5上实现的,现在在D7上照样没问题
 
这里的关键是,我的Image1.picture.width并不是为0啊。
(我在前面加了一句showmessage(inttostr(image1.picture.width)))
可还是有这个提示。
 
我明白是怎么回事了,我这里最主要的问题就是总是客户区刷新不完全,而你做了两次的效果,所以平铺那次的刷新动作刚好修定了我刷新不完的那个问题。
 
问题解决了总的给分吧,这是游戏规则,呵呵
 
cheylin
不好意思,我还在研究,还是没有解决,我只是觉得你的方法应该是这样的解决我的问题的,可是我还是实现不了。

现在第一幅平铺的图可以画出来了,不过第二幅右下角的图画不出来
 
告诉你的Mail,我发个例子给你
 
computer@deruntex.com

真是谢谢了!
 
直接设置Image控件的Anchors属性就可以了吧,akLeft与akTop设为false,而akRight与akBottom均设为true。我在D6下试过,没有任何问题。
 
已经发给你了

忘了告诉你,因为这里的图片操作都是针对位图进行,因此要求Image必须为.BMP
 
to cheylin
我测试了一下,的确是Delphi版本的问题,你的程序我原封不动的在Delphi6下重新编译一下就变我发给你的那个样子了。你看看。
 
to HunterTeam
我也试过了,在IDE环境下设置你所说的那两项属性,然后把图片放在窗口的右下角是可以在IDE环境中起作用,不过经过编译的程序就不行了。
 
问题终于解决,代码如下,在这里对cheylin兄表示十二万分的感谢!!!

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, jpeg, ExtCtrls;

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
FileF1: TMenuItem;
EditE1: TMenuItem;
Open1: TMenuItem;
New1: TMenuItem;
Close1: TMenuItem;
N1: TMenuItem;
Exit1: TMenuItem;
Image1: TImage;
Image2: TImage;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
//below 3 lines to display a picture on the MDI client
FClientInstance : TFarProc;
FPrevClientProc : TFarProc;
procedure ClientWndProc(var Message: TMessage);

public
{ Public declarations }
end;

var
Form1: TForm1;
Dc : hDC;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.ClientWndProc(var Message: TMessage);
var
Dc : hDC;
Row : Integer;
Col : Integer;
begin
with Message do
if (Msg = WM_PAINT) or (Msg = WM_ERASEBKGND) then
begin
Dc := TWMEraseBkGnd(Message).Dc;
for Row := 0 to ClientHeight div Image1.Picture.Height do
for Col := 0 to ClientWidth div Image1.Picture.Width do
BitBlt(Dc,
Col * Image1.Picture.Width,
Row * Image1.Picture.Height,
Image1.Picture.Width,
Image1.Picture.Height,
Image1.Picture.Bitmap.Canvas.Handle,
0,
0,
SRCCOPY);
Result := 1;
BitBlt(Dc,
ClientWidth - Image2.Picture.Width, //¾ßÌåµÄLeft×Ô¼ºµ÷Õû°É
ClientHeight - Image2.Picture.Height, //¾ßÌåµÄTop×Ô¼ºµ÷Õû°É
Image2.Picture.Width,
Image2.Picture.Height,
Image2.Picture.Bitmap.Canvas.Handle,
0,
0,
SRCCOPY);

end
else
Result := CallWindowProc(FPrevClientProc,
ClientHandle,
Msg,
wParam,
lParam);

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FClientInstance := MakeObjectInstance(ClientWndProc);
FPrevClientProc := Pointer(GetWindowLong(ClientHandle,GWL_WNDPROC));
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));
end;

end.
 
完了,还是有后遗症,性能太差了!
 
性能应该也不会太差,因为计算机处理图形能力天生有缺陷,建议用在这种地方的图片不应该太大,一般nK
 
后退
顶部