绝对简单 PackFrm.DBEdit25.SetFocus 报错?(120分)

  • 主题发起人 主题发起人 小梅
  • 开始时间 开始时间

小梅

Unregistered / Unconfirmed
GUEST, unregistred user!
今天本人太不爽了,被DELPHI 搞惨了。
问题是这样的:
我建了一个父窗体(MainFrm),还有许多的子窗体,其中有一个名为PackMainFrm的子窗体,
在工程中设置为Available form。在父窗体菜单的Click事件中SHOW 上子窗体PackMainFrm,

procedure TMainFrm.N14Click(Sender: TObject);
var
PackFrm: TPackFrm;
begin
Screen.Cursor:=crHourglass;
PackFrm:=TPackFrm.Create(self);
PackFrm.Show;
Screen.Cursor:=crDefault;
end;
(当再击一次,又创建成了一个PackMainFrm窗体)



另建一数据模块(PackPackDModule) 数据控件为ADO。

功能如下:

当插入一新记录后,将当前光标置给 DBEdit25
procedure TPackDModule.BoxADOTAfterInsert(DataSet: TDataSet);
begin
PackFrm.DBEdit25.SetFocus;
end;
结果如下所示:

Error  
   Project HD.exe raised exception class EAccessViolation with
   message'Access violation at address 0049E85B in module 'HD.EXE'.
   Read of address FFFFFFFF'.Process stopped.Use step or Run to
   continue.
             ┌─────┐
             │  O K │
             └─────┘

如果将子窗体PackMainFrm设置为Auto-Create form。

则以上操作不会报错。

第一问:以上出错的原因及解决的方法?(100分)
第二问:怎样控制窗体不被重复创建? (20分)
 
试试windows api函数setfocus
 
1:
if Assigned(PackFrm) then
PackFrm.Show;
else
begin
PackFrm:=TPackFrm.Create(Application);
PackFrm.Show;
end;
 
2:
请检查你的PackFrm是否已经创建?
 
1. To Hjking:
如果创建PackFrm后关闭PackFrm,Assigned检查不准确:
if Assigned(PackFrm) then //Assigned(PackFrm)=True
PackFrm.Show; //就会出错。

我的做法:
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
Form2Created:Boolean;
begin
Form2Created:=False;
for i:=0 to Screen.FormCount-1 do
begin
if Screen.Forms is TForm2 then
begin
Form2Created:=True;
break;
end;
end;
if not Form2Created then
Form2:=TForm2.Create(Application);
Form2.Show;
end;
2.
procedure TPackDModule.BoxADOTAfterInsert(DataSet: TDataSet);
begin
if Assigned(PackFrm) then
if PackFrm.Showing then
PackFrm.DBEdit25.SetFocus;
end;
 
PackFrm是Available Form,那么其创建和释放都必须由人手完成,
综观整个程序,只有创建,没有释放(或者在其它地方释放)吧。
请认真检查吧。
 
刚想到Hjking的做法如何作些补充就没问题了:
procedure TPackFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
PackFrm:=nil;
end;
 
1、你这是动态创建窗体,当然你这样做是肯定不行,因为在内存里没有指定地址。
解决的方法是这样比较好点,如果DBedit1对应字段是“field1”,如果你是用
TAdoTable、Ttable、Tquery和Tadoquery的,则:

Adotable1field1.FocusControl;

2、 防止窗体重复创建:
if not assigned(Child_Form) then
Child_Form := TChild_Form.Create(Self);
Child_Form.Show;
 
大家好,我用了以上提供的方法,在我的程序中无法实现,具报的错如故,而我另建
一父窗体和一子窗体,以上方法都行得通。
唉!说句实,DELPHI 编程是很快,可它经常会出问题,让人有碰运气的感觉,就如
CJ 大虾耍流氓,不行,重建一窗体,粘贴有误窗体的控件和代码,一切OK,真是莫明
其妙,实在气人,昨晚能预览的报表,今日没有改动,再运行,不行,真要气死我了。关于这些分,等我把问题解决了,会给大家一个说法,也欢迎大家与我讨论这个问题,帮助我。
 
在此特别感谢 Calvin,同时也感谢
fstao:
Hjking:
JohnsonGuo:
kucio:
popeye:
wumeng: 的参与.

Calvin to 小梅的信:

小梅:
您好!很高兴收到你的来信。由于这段时间比较忙,昨天的信今天才看到。以前也有打算写信给你交流一下,但这段时间比较忙,所以未能及时通信。
虽然我学习Delphi也有段时间,不过只是略知皮毛,说不上什么体会,如果学习Delphi的过程中有什么问题,或者一起研究吧。
至于你所写的代码中,我发现了一个问题,就是在事件中重复声明了一个对象Form2,因为Form2已经在Unit2中声明了,当你判断Assigned(Form2)(可能调了Unit2中的)因为已经创建了实例,所以不会再次创建,而你Form2.Show(应该是局部对象)时,由于还没创建所以出错。但有点我也不是很清楚,为什么有时Form2是局部对象,有时是引用Unit2的。
procedure TForm1.asdfasdf2Click(Sender: TObject);//用菜单的单击事件
Var
Form2:TForm2; // 去掉这个声明就没问题了,因为在Unit2中已经有声明的
// 你仔细看看Unit2就会发现了
begin
if not Assigned(Form2) then
Form2:=TForm2.Create(self);
Form2.Show; // 这个是局部对象,因为我改为Unit2.Form2.Show时就没问题
end;
不知道你有没有使用断点跟踪程序的运行,这样可以方便找错。另外,我以前也是用VB的,用了几年后才改用Delphi的,我觉得其实Delphi并非如你所说的这么不稳定(好像你在大富翁的贴子里说过的),或者你试试设置些断点,跟踪一下,或者可以找出问题所在。但在使用Delphi过程中我也曾经发现过一些Bug,或者可以通过Update Pack升级解决的。
时候不早了,改天再谈。
愿一起进步。
 
第一问的回答:PackFrm.DBEdit25控件没有被创建,读了空指针。
 
To shangjintong:
您好!
你走过来,我们来谈一谈。
确实PackFrm.DBEdit25控件没有被创建,读了空指针,请你细细道来?不知能否?
 
问题已经解决了,谢谢大家的帮助。分就见者有份了!
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
543
import
I
I
回复
0
查看
623
import
I
后退
顶部