MDI窗体问题,请帮忙!(50分)

Y

yuxuant

Unregistered / Unconfirmed
GUEST, unregistred user!
有一登录窗体,设为主窗体。还有一个MDI父窗体,是auto-create form,
另外一个MDI子窗体,是available form。当登录以后,主窗体hide,在MDI父窗体上点击
菜单调用MDI子窗体时提示错误:EInvalidOperation,cannot creat form.no MDI forms
are currently active.

怎么办?
 
其实是个很简单的问题,你把什么是主窗体搞明白,什么是动态生成窗体就行了。
 
请详细说说,好吗?
 
本来想把MDI父窗体作为主窗体,但是在登录框窗体取消时,这个MDI父窗体闪烁一下,
感觉不好。
 
在工程文件中写
Application.ShowMainForm:=False;
在MDI主窗体的建立事件中建立登录窗体,登录成功后再Show自己.
 
你把一个MDI子窗体设置为available form,那末你必须在在MDI父窗体上点击
菜单时,动态创建子MDI窗体:
begin
if not Assigned(ChildForm) then
ChildForm := TChildForm.Create(Application);
end;

你在工程文件中前面写:
Application.ShowMainForm:=False;
在登录窗体LoginForm登录成功后,调用
Application.ShowMainForm:=True;
就可以消除闪烁

 
sorry
但是如何判断登录窗体LoginForm登录成功,我设了公共变量,但是又出别的错了。

谢谢诲人不倦!
 
//我的源程序
//调用CheckPassWord('默认用户名'),返回为真就可以进入程序
unit LogIn;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, Forms,
Dialogs, ExtCtrls,Global, Child, StdCtrls,
Buttons, TFlatEditUnit, TFlatButtonUnit,MainDM;

type
TLogInForm = class(TChildForm)
bOK: TFlatButton;
bCancel: TFlatButton;
tUserName: TFlatEdit;
tPassWord: TFlatEdit;
labUserName: TLabel;
labPassWord: TLabel;
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure bOKClick(Sender: TObject);
procedure bCancelClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
CheckOK:boolean;
{ Public declarations }
end;

function CheckPassWord(UserName:string=''):boolean;

implementation

{$R *.dfm}

function CheckPassWord(UserName:string=''):boolean;
//检查密码函数,建立LogIn窗体
begin
with TLogInForm.Create(Application) do
begin
if length(UserName)>0 then
begin
Caption:=SCheckPassWord;
tUserName.Text:=UserName;
tUserName.Enabled:=false;
end;
ShowModel;
result:=CheckOK;
end;
end;

procedure TLogInForm.FormKeyPress(Sender: TObject; var Key: Char);
//Esc退出,Enter确认
begin
inherited;
if key=#13 then
begin
key:=#0;
if ActiveControl=bCancel then
bCancelClick(bCancel)
else
bOkClick(bOk);
end;
if key=#27 then
begin
key:=#0;
bCancelClick(bCancel);
end;
end;

procedure TLogInForm.bOKClick(Sender: TObject);
//确认密码
var
MousePoint:TPoint;
begin
inherited;
if length(tusername.text)>0 then
begin
if MainDMForm.ADSUser.Locate(sfield_username,tusername.Text,[]) then
begin
if MainDMForm.ADSUser[SField_PassWord]=tpassword.Text then
begin
sUserName:=MainDMForm.ADSUser[SField_UserName];
iUserGrade:=MainDMForm.ADSUser[SField_UserGrade];
CheckOK:=true;
close;
end else begin
msgbox(sepassword,caption,mb_iconstop);
tpassword.SetFocus;
end;
end else begin
msgbox(format(seusername,[tusername.text]),caption,mb_iconstop);
tusername.SetFocus;
end;
end else begin
sUserName:=SNoUserName;
iUserGrade:=4;
CheckOK:=true;
close;
end;
end;

procedure TLogInForm.bCancelClick(Sender: TObject);
//退出
begin
inherited;
CheckOK:=false;
close;
end;

procedure TLogInForm.FormActivate(Sender: TObject);
//如果保存了用户名,则使用
begin
inherited;
if bSaveUserName and (length(susername)>0) then
begin
tusername.Text:=susername;
tpassword.SetFocus;
end;
end;

end.
 
我觉得MdiMainFrom显然应该是主窗体,应该新建一个passwordform
在project.dpr里加入
Application.Initialize;
Application.CreateForm(TPasswordDlg, PasswordDlg);
try
//为Passworddlg添加一个方法Execute,该方法通过ShowModal显示
//并确认密码是否正确,正确返回True,否则返回False
if PasswordDlg.Executethen begin
Application.CreateForm(tform1,form1);
Application.Run;
end;
finally
PasswordDlg.Free;
end;
然后在password的unit里写:
procedure TPasswordDlg.OKBtnClick(Sender: TObject);
begin
modalresult:=mrcancel;
if passworddlg.Password.Text='1234567' then
begin
modalresult:=mrok;//passworddlg.RetTrue:=true;
end
else showmessage('密码错误!');
end;

function TPasswordDlg.Execute: boolean;
begin
result:=false;
if passworddlg.ShowModal=mrOK then
result:=true;
end;

 
最简单的就是在工程文件里写:

Application.Initialize;
if InputQuery()= password then
begin
Application.CreateForm(TPasswordDlg, PasswordDlg);
Application.run;
end
else
Application.terminate;
end;
end.

 
Delphi认为第一个建立的窗体为子窗体,所以只有将你的程序需要的主窗体第一个建立,
显然登录窗体不是主窗体,为了释放他,必须在主窗体之后建立,所以就要在主窗体的
建立事件中建立登录窗体
 
delphi的主窗体可以在options里设定,根本没有规定第一个建立的是主窗体.
所以,passwordform可以在主窗体建立前先create,如果密码输入不正确,根本没有
必要create主窗体.这样出现密码框的速度很快,尤其是在主窗体很大时.不信你可
以先create passwordform,然后在MainForm的create之前,free掉PasswordForm,看
看出不出错.
 
各位说的,相信都是成功之后的经验之谈。但不知怎么搞的,在下这个仍然出错。其中有个
数据模块,登录窗体中要从数据库中取出用户名,所以可能要先建立数据模块窗体。另外还有
闪现窗体。
下面是源码:
//工程文件
program rlglnew;

uses
Forms,
Messages,
Windows,
Main in 'Main.pas' {frm_Main},
skin in 'skin.pas' {frm_skin},
login in 'login.pas' {frm_login},
DataModal in 'DataModal.pas' {DM: TDataModule};


{$R *.RES}

begin
Frm_skin:=Tfrm_skin.Create(Application);
Frm_skin.Show;
Frm_skin.Update;


Application.Initialize;
Application.ShowMainForm:=False;
Application.CreateForm(Tfrm_Main, frm_Main);
Application.CreateForm(TDM, DM);

Frm_skin.free;
frm_login:=Tfrm_login.Create(Application);
frm_login.Showmodal;//运行到这个地方提示错误:connot make a visible window modal
if frm_login.ModalResult <>2 then
begin
Application.Run;
end;
end.
//登录窗体
unit login;

interface

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

type
Tfrm_login = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;
edt_Pass: TEdit;
comb_User: TComboBox;
btn_login: TBitBtn;
btn_exit: TBitBtn;
procedure btn_exitClick(Sender: TObject);
procedure btn_logonClick(Sender: TObject);
procedure AppException(Sender: TObject; E: Exception);
procedure edt_PassClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private

{ Private declarations }
public
{ Public declarations }
username:string;
unitname:string;
password:string;
oper_object:string;
end;

var
frm_login: Tfrm_login;

implementation

uses DataModal;

{$R *.DFM}

procedure Tfrm_login.btn_exitClick(Sender: TObject);
begin
close;
end;

procedure Tfrm_login.btn_logonClick(Sender: TObject);
var
Oldcursor:TCursor;
begin
if comb_User.text='SUPER' then
begin
if trim(edt_Pass.text)='888888' then
begin
username:='SUPER';
ModalResult:=mrOk;
end
else
begin
Application.MessageBox('密码错误!','提示',MB_OK+MB_ICONWARNING);
edt_Pass.SetFocus;
end;
end
else
begin
DM.Qry_User.Close;
with DM.Qry_User do
begin
SQL.Clear;
SQL.Add('select * from User_Info where UserName=:UserName');
Parameters.ParamValues['UserName']:=comb_User.Text;
end;
Application.OnException :=AppException;
DM.Qry_User.Open;
if DM.Qry_User.Eof then
begin
Showmessage('这个用户已经改变,请与系统管理员联系!');
end
else
begin
if trim(DM.Qry_User.FieldByName('password').AsString)=trim(edt_Pass.Text) then
begin
username:=DM.Qry_User.FieldByName('username').AsString;
unitname:=DM.Qry_User.FieldByName('unitname').AsString;
password:=DM.Qry_User.FieldByName('password').AsString;
oper_object:=DM.Qry_User.FieldByName('object').AsString;
ModalResult:=mrOk;
end
else
begin
Application.MessageBox('密码错误!','提示',MB_OK+MB_ICONWARNING);
edt_Pass.SelectAll;
edt_Pass.SetFocus;
end;
end;
end;

end;

procedure Tfrm_login.AppException(Sender: TObject; E: Exception);
begin
Application.ShowException(E);
Application.MessageBox('错误:数据库读取失败.'+#13+'建议您检查网络的连接情况或者与数据库系统管理员联系!',
'连接错误',MB_OK+MB_ICONWARNING);
Application.Terminate;
end;

procedure Tfrm_login.edt_PassClick(Sender: TObject);
begin
edt_Pass.SelStart :=0;
edt_Pass.SelLength :=length(edt_Pass.Text);
end;

procedure Tfrm_login.FormCreate(Sender: TObject);
begin
//try
Application.OnException :=AppException;
comb_User.Items.Clear;
DM.Tbl_User.Open;
with DM.Tbl_User do
begin
if Eof then
begin
comb_User.Items.Add('SUPER');
end
else
begin
while not DM.Tbl_User.Eof do
begin
comb_User.Items.Add(DM.Tbl_User.FieldByName('UserName').AsString);
DM.Tbl_User.Next;
end;
end;
comb_User.ItemIndex :=0;
end;
// except
// Application.MessageBox('一般网络故障,请与系统管理员联系!','提示',MB_OK);
// end;
end;

end.

//数据模块
unit DataModal;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, ADODB;

type
TDM = class(TDataModule)
ADOConnection1: TADOConnection;
Tbl_User: TADOTable;
Qry_User: TADOQuery;
Qry_BaseTable: TADOQuery;
Qry_BaseTable1: TADOQuery;
Qry_Unit: TADOQuery;
Qry_Department: TADOQuery;
Qry_Unit1: TADOQuery;
Qry_Department1: TADOQuery;
Qry_JiBen1: TADOQuery;
Qry_DanWeiBD1: TADOQuery;
Qry_BuMenBD1: TADOQuery;
Qry_User_Oper: TADOQuery;
Qry_User1: TADOQuery;
Qry_User_Oper1: TADOQuery;
Qry_NewChaXun: TADOQuery;
Qry_NewChaXunDSDesigner: TStringField;
Qry_NewChaXunDSDesigner2: TStringField;
Qry_NewChaXunDSDesigner3: TStringField;
Qry_NewChaXunDSDesigner4: TStringField;
Qry_NewChaXunDSDesigner5: TDateTimeField;
Qry_NewChaXunDSDesigner6: TStringField;
Qry_NewChaXunDSDesigner7: TStringField;
Qry_NewChaXunDSDesigner8: TWideStringField;
Qry_NewChaXunDSDesigner9: TStringField;
Qry_NewChaXunDSDesigner10: TDateTimeField;
Qry_NewChaXunDSDesigner11: TStringField;
Qry_NewChaXunDSDesigner12: TStringField;
Qry_NewChaXunDSDesigner13: TWideStringField;
Qry_NewChaXunDSDesigner14: TWideStringField;
Qry_NewChaXunDSDesigner15: TStringField;
Qry_NewChaXunDSDesigner16: TWideStringField;
Qry_NewChaXunDSDesigner17: TDateTimeField;
Qry_NewChaXunDSDesigner18: TStringField;
Qry_NewChaXunDSDesigner19: TDateTimeField;
Qry_NewChaXunDSDesigner20: TStringField;
Qry_NewChaXunDSDesigner21: TStringField;
Qry_NewChaXunDSDesigner22: TStringField;
Qry_NewChaXunDSDesigner23: TStringField;
Qry_NewChaXunDSDesigner24: TStringField;
Qry_NewChaXunDSDesigner25: TStringField;
Qry_NewChaXunDSDesigner26: TDateTimeField;
Qry_NewChaXunDSDesigner27: TStringField;
Qry_NewChaXunDSDesigner28: TStringField;
Qry_NewChaXunDSDesigner29: TStringField;
Qry_NewChaXunDSDesigner30: TDateTimeField;
Qry_NewChaXunDSDesigner31: TBlobField;
Qry_NewChaXunDSDesigner32: TStringField;
Qry_NewChaXunField: TIntegerField;
Qry_JiBen: TADOQuery;
Qry_JiBen_Print: TADOQuery;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure AppException(Sender: TObject; E: Exception);
private
{ Private declarations }
public
{ Public declarations }
end;

var
DM: TDM;

implementation




{$R *.DFM}

procedure TDM.AppException(Sender: TObject; E: Exception);
begin
//Application.ShowException(E);
Application.MessageBox('错误:数据库读取失败.'+#13+'建议您检查网络的连接情况或者与数据库系统管理员联系!',
'连接错误',MB_OK+MB_ICONWARNING);
Application.Terminate;
end;

procedure TDM.DataModuleCreate(Sender: TObject);
{var
CurTime:LongWord;
DelayTime:LongWord;}
begin
{ DelayTime:=5000;
CurTime:=GetTickCount;
while(GetTickCount<(CurTime+DelayTime)) do
begin
end; }
Application.OnException := AppException;
// ADOConnection1.Connected:=True;
//Tbl_User.Active :=True;
//Application.OnException :=nil;
end;

procedure TDM.DataModuleDestroy(Sender: TObject);
begin
ADOConnection1.Connected:=False;
ADOConnection1.KeepConnection :=False;
end;
end.
//主窗体
unit Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, jpeg, ExtCtrls, ImgList, ComCtrls, ToolWin, StdCtrls, Buttons,
ExtDlgs, IniFiles, Db, ADODB, MDIWallp;

const
CM_RESTORE=WM_USER+$1000;
APPNAME='人力资源管理系统';

type
Tfrm_Main = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N9: TMenuItem;
LR_JIBENXX: TMenuItem;
LR_LVLIXX: TMenuItem;
LR_XUELIXX: TMenuItem;
LR_SHEHUIXX: TMenuItem;
N10: TMenuItem;
LR_ZHICHENGXX: TMenuItem;
LR_JIANGLIXX: TMenuItem;
LR_CHENGCHUXX: TMenuItem;
LR_JIANZHIXX: TMenuItem;
LR_CHUGUOXX: TMenuItem;
LR_SHANGBXX: TMenuItem;
LR_LONGDXX: TMenuItem;
BD_ZhiWu: TMenuItem;
BD_BuMen: TMenuItem;
BD_GangWei: TMenuItem;
N11: TMenuItem;
BD_ShiYong: TMenuItem;
BD_ZaiZhi: TMenuItem;
BD_LiChang: TMenuItem;
N12: TMenuItem;
BD_XIEYI: TMenuItem;
BD_ZHAOPIN: TMenuItem;
BD_FUYUANBING: TMenuItem;
XT_DANWEI: TMenuItem;
XT_BUMEN: TMenuItem;
XT_GANGWEI: TMenuItem;
XT_GWLEIBIE: TMenuItem;
XT_GWMINGCHENG: TMenuItem;
XT_GWIZHUANGTAI: TMenuItem;
XT_YONGHU: TMenuItem;
BZ_ZHUTI: TMenuItem;
N14: TMenuItem;
BZ_GUANYU: TMenuItem;
StatusBar1: TStatusBar;
Timer1: TTimer;
N16: TMenuItem;
JICHUBIAOGZ: TMenuItem;
N17: TMenuItem;
OpenPictureDialog1: TOpenPictureDialog;
N8: TMenuItem;
BeiJing: TMenuItem;
N15: TMenuItem;
KLXG: TMenuItem;
CHA_JD: TMenuItem;
CHA_FH: TMenuItem;
TJ_LSLL: TMenuItem;
TJ_TONGJI: TMenuItem;
Timer2: TTimer;
Timer3: TTimer;
BD_DanWei: TMenuItem;
N3: TMenuItem;
LingChang_ChaX: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
MDIWallpaper1: TMDIWallpaper;
PopupMenu1: TPopupMenu;
N13: TMenuItem;
N18: TMenuItem;
N19: TMenuItem;
procedure XT_EXITClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure XT_ZHUOMIANClick(Sender: TObject);
procedure N15Click(Sender: TObject);
procedure BeiJingClick(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Timer3Timer(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure N13Click(Sender: TObject);
procedure N18Click(Sender: TObject);
procedure N19Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
WindowList: Pointer;
procedure CreateParams(var Params:TCreateParams);override;
procedure RestoreRequest(var message:TMessage);message CM_RESTORE;
end;

var
frm_Main: Tfrm_Main;
OldCursor:TCursor;
implementation

uses login;


{$R *.DFM}



procedure Tfrm_Main.XT_EXITClick(Sender: TObject);
begin
close;
end;

procedure Tfrm_Main.FormShow(Sender: TObject);
var
MyIni:TIniFile;
name:string;

begin

StatusBar1.Panels[0].Text :='欢迎使用人力资源管理系统!';
//StatusBar1.Panels[1].Text :='单位名称:'+frm_login.unitname;
//StatusBar1.Panels[2].Text:='用户名称:'+frm_login.username;
StatusBar1.Panels[4].Text:=DateToStr(now);
Application.HintHidePause :=5000;
Application.HintPause :=0;
MyIni:=TIniFile.Create('c:/test.ini');
name:=MyIni.ReadString('path','name','');
if name<>'' then
begin
if FileExists(name) then
MDIWallpaper1.Picture.LoadFromFile(name);
end;
end;

procedure Tfrm_Main.Timer1Timer(Sender: TObject);
begin
StatusBar1.Panels[3].Text:=TimeToStr(Time);
end;

procedure Tfrm_Main.FormCreate(Sender: TObject);
begin
EnableMenuItem(GetSystemMenu(frm_Main.Handle,False),SC_CLOSE,MF_GRAYED);
end;

procedure Tfrm_Main.XT_ZHUOMIANClick(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
MDIWallpaper1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;

procedure Tfrm_Main.N15Click(Sender: TObject);
begin
close;
end;

procedure Tfrm_Main.BeiJingClick(Sender: TObject);
var
MyIni:TIniFile;
begin
if OpenPictureDialog1.Execute then
begin
MDIWallpaper1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
MyIni:=TIniFile.Create('c:/test.ini');
MyIni.WriteString('path','name',OpenPictureDialog1.Filename);
end;
end;


procedure Tfrm_Main.Timer2Timer(Sender: TObject);
begin
StatusBar1.Panels[0].Text :=' '+StatusBar1.Panels[0].Text;
if length(StatusBar1.Panels[0].Text)=Length('欢迎使用人力资源管理系统!')+68 then
begin
statusBar1.Panels[0].Text:='欢迎使用人力资源管理系统!';
//Timer2.Enabled :=False;
//TImer3.Enabled :=True;
end;
end;

procedure Tfrm_Main.Timer3Timer(Sender: TObject);
var
str:string;
begin
str:=StatusBar1.Panels[0].Text;
DELETE(str,1,1);
StatusBar1.Panels[0].Text :=str;
if length(StatusBar1.Panels[0].Text)=Length('欢迎使用人力资源管理系统!') then
begin
Timer2.Enabled :=True;
TImer3.Enabled :=False;
end;
end;

procedure Tfrm_Main.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WinClassName:=APPNAME;
end;

procedure Tfrm_Main.RestoreRequest(var message: TMessage);
begin
MessageBox(Handle,'程序-'+APPNAME+'已经运行了.','信息',MB_OK+MB_ICONINFORMATION+MB_SYSTEMMODAL);
if IsIconic(Application.Handle)=TRUE then
Application.Restore
else
Application.BringToFront;
end;

procedure Tfrm_Main.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if button=mbright then
PopupMenu1.Popup(x,y+40);
end;

procedure Tfrm_Main.N13Click(Sender: TObject);
begin
MDIWallpaper1.Mode:=wpCenter;
end;

procedure Tfrm_Main.N18Click(Sender: TObject);
begin
MDIWallpaper1.Mode:=wpTile;
end;

procedure Tfrm_Main.N19Click(Sender: TObject);
begin
MDIWallpaper1.Mode:=wpStretch;
end;

end.

其中主窗体、数据模块是auto-create forms,闪现窗体、登录窗体是available forms。是
在progject的options中设置的。
 
to ysai:
在主窗体的建立事件中建立登录窗体.登录成功之后如何使程序继续运行,如何返回到工程
文件中?因为先前Application.ShowMainForm:=False;了!另外我在主窗体的建立事件中建立登录窗体
时:procedure Tfrm_Main.FormCreate(Sender: TObject);
begin
frm_login:=Tfrm_login.Create(Application);
frm_login.ShowModal;//仍然提示这个错误:cannot make a visible window modal.
end;
主窗体是MDI父窗体,auto-create.登录窗体是一般窗体,available。
 
我都把我的源程序贴出来了,照做一定没问题,不知道你的程序为什么出问题!
我是在主窗体中调用CheckPassWord函数,在函数中建立登录窗体的,如果登录成功
才Show主窗体,否则退出程序
 
谢谢各位!
暂时不用mdi窗体了。
 
loginform和你的splashform一样,都应该在主窗体建立前建立.
 
顶部