異常為物件,定義新異常類別同定義新物件型別。預設異常處理僅處理繼承自 Exception 或其子類別的物件,故自訂異常應繼承 Exception 或標準異常類別。若模組引發新異常卻無對應處理,預設機制會顯示含異常類別名稱與錯誤訊息的對話框。
type
EMyException = class(Exception);
使用保留字 raise 後接異常類別實例:
type
EPasswordInvalid = class(Exception);
...
if Password <> CorrectPassword then
raise EPasswordInvalid.Create('Incorrect Password entered');
異常產生時,System 單元 ErrorAddr 變數記錄發生位址,異常處理程序可參考。自行引發時亦可指定位址:
raise EInstance at Address_Expression;
Label1、Label2)對應編輯框功能PassWord(密碼輸入)、InputEdit(數值輸入)Label2、InputEdit 不可見(Visible=False)Label2、InputEdit 顯示,Label1、PassWord 隱藏PassWord.PasswordChar 設定密碼回顯字元type
EInValidation = class(Exception)
public
ErrorCode: Integer;
constructor Create(const Msg: string; ErrorNum: Integer);
end;
EInvalidPassWord = class(EInValidation)
public
constructor Create;
end;
EInvalidInput = class(EInValidation)
public
constructor Create(ErrorNum: Integer);
end;
EInValidation 增加 ErrorCode 欄位保存錯誤代碼,提供程式設計彈性:異常類別可依代碼提供不同訊息,呼叫端可在 try...except 外部截取代碼處理。
constructor EInValidation.Create(const Msg: string; ErrorNum: Integer);
begin
inherited Create(Msg);
ErrorCode := ErrorNum;
end;
constructor EInvalidPassWord.Create;
begin
inherited Create('Invalid Password Entered', 0);
end;
constructor EInvalidInput.Create(ErrorNum: Integer);
var
Msg: string;
begin
case ErrorNum of
1: Msg := 'Can not convert String to Number';
2: Msg := 'Number is out of Range';
else Msg := 'Input is Invalid';
end;
inherited Create(Msg, ErrorNum);
end;
EInvalidInput:ErrorCode=1 非純數字序列,=2 數值超出範圍。
procedure TForm1.PassWordKeyPress(Sender: TObject; var Key: Char);
const
CurrentPassWord = 'Delphi';
begin
if Key = #13 then
begin
try
if PassWord.Text <> CurrentPassWord then
raise EInvalidPassWord.Create;
Label2.Visible := True;
InputEdit.Visible := True;
InputEdit.SetFocus;
PassWord.Visible := False;
Label1.Visible := False;
except
on EInvalidPassWord do
begin
PassWord.Text := '';
raise; { 重新引發,交由系統預設處理顯示訊息 }
end;
end;
Key := #0;
end;
end;
procedure TForm1.InputEditKeyPress(Sender: TObject; var Key: Char);
var
Res: Real;
Code: Integer;
begin
if Key = #13 then
begin
try
Val(InputEdit.Text, Res, Code);
if Code <> 0 then
raise EInvalidInput.Create(1);
if (Res > 1) or (Res < 0) then
raise EInvalidInput.Create(2);
MessageDlg('Correct Input', mtInformation, [mbOK], 0);
Key := #0;
except
on E: EInvalidInput do
begin
InputEdit.Text := '';
MessageDlg(E.Message, mtWarning, [mbOK], 0); { 透過異常實例取得訊息自行顯示 }
end;
end;
end;
end;
兩種異常訊息顯示策略:密碼錯誤用 raise 重新引發交由系統預設處理;數值錯誤透過異常實例 E.Message 取得訊息自行以 MessageDlg 顯示。