请看:数据库程序开发中的一个奇怪的现象???(100分)

  • 主题发起人 主题发起人 ssg
  • 开始时间 开始时间
S

ssg

Unregistered / Unconfirmed
GUEST, unregistred user!
程序编制中发现一个奇怪的现象:(源代码如下)
其中,Form1为主窗口,Form2为动态生成的子窗口,DataModual为数据模块;
DataModual1上置一TDatabase平构件,程序运行时自动连接数据服务器(用的是DB2);
Form1上有主菜单File,按New时动态生成Form2;
Form2上有Table1,连接置数据库的一个表,另有Dbgrid和dbnavigator,窗口生成
时打开表,关闭时关闭表;
通过试验发现,当Form2的属性为fsdialog时,程序运行正常(重复打开关闭对话框),而Form2的属性为fsMdiChild时,即使保证只打开一个子窗口(打开后又关闭),在下次打开子窗口时出现"Open语句中指定的游标已经打开"错误.
这是为什么????Form2都是动态生成,为什么结果却不同呢???
请各位高手赐教.

主窗口:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
file1: TMenuItem;
new1: TMenuItem;
procedure new1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
uses unit2;
{$R *.DFM}

procedure TForm1.new1Click(Sender: TObject);
var
child: TForm2;
begin
Child:= TForm2.Create( application );
{ try
Child.Showmodal;
finally
Child.free;
end; }
end;

end.

子窗口:
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, DBCtrls, Grids, DBGrids, Db, DBTables;

type
TForm2 = class(TForm)
DataSource1: TDataSource;
Table1: TTable;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation
uses unit3;
{$R *.DFM}

procedure TForm2.FormShow(Sender: TObject);
begin
table1.open;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
table1.close;
// action:= cafree;
end;

end.


数据模块:
unit Unit3;

interface

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

type
TDataModule3 = class(TDataModule)
db1: TDatabase;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
DataModule3: TDataModule3;

implementation

{$R *.DFM}

procedure TDataModule3.DataModuleCreate(Sender: TObject);
begin
db1.open;
end;

procedure TDataModule3.DataModuleDestroy(Sender: TObject);
begin
db1.close;
end;

end.


 
procedure TForm1.new1Click(Sender: TObject);
begin
Form2.Showmodal;
end;//这个方法好。
或procedure TForm1.new1Click(Sender: TObject);
var
child: TForm2;
begin
Child:= TForm2.Create( application );
try
Child.Showmodal;
finally
Child.free;
Child:=nil;//加上试试。
end;
end;//书上看的,不一定好用。





 
首先,我注意到你程序中
{ try
Child.Showmodal;
finally
Child.free;
end; }
部分,说明你已经发现了MDIchild窗体不能被showmodal.那么wumeng的回答应该是不可行的.
而下面这一句
"而Form2的属性为fsMdiChild时,即使保证只打开一个子窗口(打开后又关闭),"
我不知你是怎样实现?因为,当MDIchild窗体被关闭时,仅仅会最小化,而不会释放
其实你简单地在form2的close事件中加上一句:
Action := caFree;//保证该MDIChild每次被关闭的时候释放
应该就没有问题了
 
coyoto:
打开一个子窗口后,在打开第二个子窗口前关闭之,即可保证只打开一个子窗口。
另外,我在onclose中加过action=cafree;
这个问题实在让我想不通!
 
如果你的程序仅仅简单到如你所描述,我做过了试验,确实没有问题,
我猜想剩下的可能性在于你数据库的环境影响.
请详细描述你所用的数据库及环境设置
 
建议不要将TABLE与FORM2放在一起,TABLE与DATASTORE均集中于数据模块中。
MDI方式容易导致数据集在FORM1的工作区内打开,你在FORM2中关闭的只是
该数据集的连接。
 
数据库用的是IBM的DB2.
 
为 mdiChild 时,在 close 中加上 Action := caFree
 
接受答案了.
 

Similar threads

后退
顶部