請問:結束 MDI Child 時,按「x」和「self.close」,有什麼不同? |
答題得分者是:borland_delphi70
|
jaya
初階會員 發表:9 回覆:70 積分:30 註冊:2002-05-22 發送簡訊給我 |
遇到了一個怪怪的問題
在 MDI Form 裡,動態開啟了一個子表單(MDI Child)。
表單裡放了一個SpeedButton,功能就是結束表單:self.close;
開啟、操作都沒有問題。可是在結束子表單時就很奇怪了。 如果是按子表單右上的「X」的話,就可以正常結束。
但是按下SpeedButton就會出現錯誤。「Access Violation with message at address ....)。
更怪的是,同一張子表單,再重開一次,再按一次SpeedButton,也可以正常結束。 也就是,只有程式執行後,第一次開啟這個子表單,而且是用SpeedButton結束的,才會有問題,其餘狀況都是ok的。 該子表單是動態建立的,結束時也有 freeandnil()。
請問有人遇過這種狀況嗎?
|
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
|
jaya
初階會員 發表:9 回覆:70 積分:30 註冊:2002-05-22 發送簡訊給我 |
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
|
jaya
初階會員 發表:9 回覆:70 積分:30 註冊:2002-05-22 發送簡訊給我 |
謝謝 change.jian 的回覆。 從「Access Violation」的錯誤訊息來看,應該是您說的原因。
但是我查不出來 因為問題是發生在「開啟表單-立即結束」的狀況下,在移除無關的程式碼之後,
該子表單的程式碼如下。
被繼承的單元中,與開始、結束有關的程式碼也附在最後面。
( class="code">
unit ufmDiagRoom; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Udbform, DB, DBCtrls, Buttons, ExtCtrls, StdCtrls, Mask, ADODB; type
TfmDiagRoom = class(TDbForm)
dtDiagRoom: TADOTable;
dtDiagRoomsn: TAutoIncField;
dtDiagRoomDiag_RoomID: TStringField;
dtDiagRoomDiag_RoomName: TStringField;
dtDiagRoomenable: TBooleanField;
Label1: TLabel;
DBEdit1: TDBEdit;
Label2: TLabel;
DBEdit2: TDBEdit;
Label3: TLabel;
DBCheckBox1: TDBCheckBox;
dtUser: TADOQuery;
dsUser: TDataSource;
DBLookupComboBox1: TDBLookupComboBox;
dtDiagRoomDiag_DrID: TWideStringField;
dtDiagRoomDiag_DrName: TWideStringField;
dtUserUserid: TWideStringField;
dtUserusername: TWideStringField;
dtUseruserename: TWideStringField;
dtUserpassword: TWideStringField;
dtUseractive: TIntegerField;
dtUserqua: TIntegerField;
Label4: TLabel;
DBEdit3: TDBEdit;
dtDiagRoomDiag_FormName: TWideStringField;
Label5: TLabel;
dtProgram: TADOQuery;
dsProgram: TDataSource;
DBLookupComboBox2: TDBLookupComboBox;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure bpostClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure opendb;override;
end; var
fmDiagRoom: TfmDiagRoom; implementation
uses
global, UDM, UPub;
{$R *.dfm} procedure TfmDiagRoom.opendb;
begin
inherited;
dtDiagRoom.Open;
dtUser.Open;
end; procedure TfmDiagRoom.FormClose(Sender: TObject; var Action: TCloseAction);
begin
inherited;
freeandnil(fmDiagRoom);
end; procedure TfmDiagRoom.bpostClick(Sender: TObject);
begin
dtDiagRoom.FieldByName('Diag_DrName').AsString :=
dtUser.FieldByName('UserName').AsString;
inherited; end; end.
被繼承的單元裡的相關程式碼:
procedure TDbForm.FormCreate(Sender: TObject); begin opendb; end; procedure TDbForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin if ds1.dataset.State <> dsbrowse then begin if messagedlg('資料尚未儲存,確定要離開?',mtConfirmation, [mbYes, mbNo], 0) <> mrYes then begin canclose:=false; end; end; end; procedure TDbForm.bexitClick(Sender: TObject); begin self.Close; end; |
jeffreck
高階會員 發表:247 回覆:340 積分:197 註冊:2003-01-23 發送簡訊給我 |
|
jaya
初階會員 發表:9 回覆:70 積分:30 註冊:2002-05-22 發送簡訊給我 |
|
hahalin
版主 發表:295 回覆:1698 積分:823 註冊:2002-04-14 發送簡訊給我 |
|
jaya
初階會員 發表:9 回覆:70 積分:30 註冊:2002-05-22 發送簡訊給我 |
|
borland_delphi70
中階會員 發表:8 回覆:50 積分:51 註冊:2002-12-06 發送簡訊給我 |
function TCustomForm.CloseQuery: Boolean;
var
I: Integer;
begin
if FormStyle = fsMDIForm then
begin
Result := False;
for I := 0 to MDIChildCount - 1 do
if not MDIChildren[I].CloseQuery then Exit;
end;
Result := True;
if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end; 在 CloseQuery 中對 MDIChild 的處理作業是從 0 到 N 所以自行在 MDIChild 的 CloseQuery 中自行 Free 會導致 Loop I 不正確,進而引發錯誤,而且不固定是哪個 MDIChild 關閉時會錯誤,一般而言在關到第 3 或第 4 個 MDIChild 時會 Access Violation
|
borland_delphi70
中階會員 發表:8 回覆:50 積分:51 註冊:2002-12-06 發送簡訊給我 |
|
jaya
初階會員 發表:9 回覆:70 積分:30 註冊:2002-05-22 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |