想在MID主窗口中放入按钮和背景图,怎么做?(200分)

  • 主题发起人 主题发起人 lishding
  • 开始时间 开始时间
MID还是MDI,formstyle中好像没有Mid
 
不好意思打错了,是 MDIForm
 
好像要响应Mainform的绘制背景消息才行。
 
能否给我例子?
 
转载程序员大本营
给MDI主窗口加背景

在MDI程序中,由于MDI的主窗口一般的功能是提供子窗口显示的位置和提供菜
单、工具条、状态条等,而窗口的客户区则一般不会有其它的用途,如果在这里
画上一些软件的标志、公司的标志或者其它的背景图案的话,不仅可以使MDI的主
窗口更加充实、美观,而且还可以更加突出公司的形象和增加公司标志在客户心
中的地位。

由于MDI主窗口的特性,使用普通OnPaint和使用TImage等方法都不会产生作
用。下面将用编写一个简单的MDI程序来介绍如何实现。

第一步:打开Delphi(Delphi 1,2,3都可以),创建一个新的工程。
第二步:将Form1的FormStyle设置为fsMDIForm,设置成MDI的主窗口。
第三步:在Form1上增加一个Image元件,并选择要设置的背景到Image的Pic
ture中。
第四步:在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, wPa
ram, lParam);
end;
end;

第六步:在Form1的创建事件中加入:
FClientInstance := MakeObjectInstance(ClientWndProc);
FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)
);
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));


上面的步骤已经完成了MDI主窗口背景图案的设置,下面可以增加一个MDIC
hild窗口,实现MDI程序。

第七步:新增加一个Form,并将FormStyle设置为fsMDIChild。

现在你可以编译运行这个程序,你会发现,Image元件并不会在Form上显示出
来,但是整个Form的客户区域被Image中的图像所铺满。


如何使 MDIChildForm正常关闭

为何我用 Delphi 写的 MDI Child Window 无法 Close ? 请各位先进指教一下,
是否
我那个 Property 设错了 ?

请在 MDI Child 的 OnClose() 事件中加入这列程式

Action := caFree;
例如:
procedure TFrom2.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Action := caFree;
end;
 
但是按钮怎么做呢?
 
没人帮忙吗?
 
按钮好像直接放上就搞定了
 
按钮直接放上去后,会挡住子窗口,

我用一子窗口作为一个Panel板放在主窗口中(最大化,无标题栏)
但每次打开一个子窗口时,这个窗口自动缩小了,
请问如何禁止这个窗口自动缩?
 
将窗体的WINDOWSSTATE属性设置为wsMaximized就可以了。
 
我设置了,但一打开一个子窗口后,它自动缩小窗口
 
我有一个很妙的办法,现在我编的一个管理软件中也遇到这样的问题,我要求MID主窗口菜单栏
不变,每点击其中的按钮,在子窗体中都要马上现实对应的内容,即原来的窗体马上消失,新
窗体立即出现并且都是最大化,没有什么放大缩小和关闭按钮。
方法如下:新建一子窗体,加入pagecontrol控件,将align属性定为alClient,将form1的
formstyle属性设为bsNone,将windowstate设为wsMaximized,在pagecontrol中加入几个标签
假设有3个,名字为,biao1,biao2,biao3,在每个biao中可加入你要的内容,将每个biao的
tabvisible设为false,然后在MID主窗口中的对应按钮中加入命令:
(biao1的控制):
form1.biao1.Visible :=true;
form1.biao2.Visible :=false;
form1.biao3.Visible :=false;
(biao2的控制):
form1.biao1.Visible :=false;
form1.biao2.Visible :=true;
form1.biao3.Visible :=false;
(biao3的控制):
form1.biao1.Visible :=false;
form1.biao2.Visible :=false;
form1.biao3.Visible :=true;
你明白了么?,效果非常好的,通过这种思想,也是可以做背景的,只不过让一个
标签show和hide
 
前面已有人回答过了查查
 
试试看吧!

unit MainFrm;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, Menus,
StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, JPeg;

type
TMainForm = class(TForm)
mmMain: TMainMenu;
mmiFile: TMenuItem;
mmiNew: TMenuItem;
mmiClose: TMenuItem;
N1: TMenuItem;
mmiExit: TMenuItem;
mmiImage: TMenuItem;
mmiTile: TMenuItem;
mmiCenter: TMenuItem;
mmiStretch: TMenuItem;
imgMain: TImage;
procedure mmiNewClick(Sender: TObject);
procedure mmiCloseClick(Sender: TObject);
procedure mmiExitClick(Sender: TObject);
procedure mmiTileClick(Sender: TObject);
private
FOldClientProc,
FNewClientProc: TFarProc;
FDrawDC: hDC;
procedure CreateMDIChild(const Name: string);
procedure ClientWndProc(var Message: TMessage);
procedure DrawStretched;
procedure DrawCentered;
procedure DrawTiled;
protected
procedure CreateWnd; override;
end;

var
MainForm: TMainForm;

implementation

uses MdiChildFrm;

{$R *.DFM}

procedure TMainForm.CreateWnd;
begin
inherited CreateWnd;
// Turn the ClientWndProc method into a valid window procedure
FNewClientProc := MakeObjectInstance(ClientWndProc);
// Get a pointer to the original window procedure
FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
// Set ClientWndProc as the new window procedure
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FNewClientProc));
end;

procedure TMainForm.DrawCentered;
{ This procedure centers the image on the form's client area }
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 TMainForm.DrawStretched;
{ This procedure stretches the image on the form's client area }
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 TMainForm.DrawTiled;
{ This procedure tiles the image on the form's client area }
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 TMainForm.ClientWndProc(var Message: TMessage);
begin
case Message.Msg of
// Capture the WM_ERASEBKGND messages and perform the client area drawing
WM_ERASEBKGND:
begin
CallWindowProc(FOldClientProc, ClientHandle, Message.Msg, Message.wParam,
Message.lParam);
FDrawDC := TWMEraseBkGnd(Message).DC;
if mmiStretch.Checked then
DrawStretched
else if mmiCenter.Checked then
DrawCentered
else DrawTiled;
Message.Result := 1;
end;
{ Capture the scrolling messages and ensure the client area
is redrawn by calling InvalidateRect }
WM_VSCROLL, WM_HSCROLL:
begin
Message.Result := CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,
Message.wParam, Message.lParam);
InvalidateRect(ClientHandle, nil, True);
end;
else
// By Default, call the original window procedure
Message.Result := CallWindowProc(FOldClientProc, ClientHandle, Message.Msg,
Message.wParam, Message.lParam);
end; { case }
end;

procedure TMainForm.CreateMDIChild(const Name: string);
var
MdiChild: TMDIChildForm;
begin
MdiChild := TMDIChildForm.Create(Application);
MdiChild.Caption := Name;
end;

procedure TMainForm.mmiNewClick(Sender: TObject);
begin
CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));
end;

procedure TMainForm.mmiCloseClick(Sender: TObject);
begin
if ActiveMDIChild <> nil then
ActiveMDIChild.Close;
end;

procedure TMainForm.mmiExitClick(Sender: TObject);
begin
Close;
end;

procedure TMainForm.mmiTileClick(Sender: TObject);
begin
mmiTile.Checked := false;
mmiCenter.Checked := False;
mmiStretch.Checked := False;
{ Set the Checked property for the menu item which invoked }
{ this event handler to Checked }
if Sender is TMenuItem then
TMenuItem(Sender).Checked := not TMenuItem(Sender).Checked;
{ Redraw the client area of the form }
InvalidateRect(ClientHandle, nil, True);
end;

end.
 
问题已解决,在D6中按 chen___ye 的方法,
 
后退
顶部