創建通用窗體欲在不同應用(特別是非 Delphi)中使用,打包進 DLL 最適當。含窗體 DLL 約 100K 組件庫開銷,多窗體合編一 DLL 可最小化(共享組件庫)。
program → libraryuses 移除 Forms 單元begin...end 間代碼uses 下、begin 前添加 exports 導出函數/過程名passform.dll 含兩窗體:SetPassWordForm(設置)、GetPassWordForm(驗證)。Delphi/VB 程序均可調用。
TSetPassWordForm 定義:
type
TSetPassWordForm = class(TForm)
Label1: TLabel; Edit1: TEdit; OKBtn, CancelBtn: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
private
Verified: Boolean;
public
PassWord: PChar;
end;
創建初始化:
procedure TSetPassWordForm.FormCreate(Sender: TObject);
begin
Verified := False;
PassWord := StrAlloc(40);
OKBtn.Enabled := False;
Label1.Caption := 'Please Input PassWord:';
end;
OKBtn 初始禁用,密碼正確設置後啟用,確保只有正確設置才能正常關閉,否則只能取消。
輸出函數 SetPassWord:
function SetPassWord(PWord: PChar): Boolean;
var SetPassWordForm: TSetPassWordForm;
begin
Result := False;
SetPassWordForm := TSetPassWordForm.Create(Application);
try
with SetPassWordForm do
if ShowModal = mrOK then
begin
StrCopy(PWord, StrUpper(PassWord));
Result := True;
end;
finally
SetPassWordForm.Free;
end;
end;
成功則複製大寫密碼到 PWord 返回 True。注意 PWord 雖為輸出參數但屬值參數(指針類型指向字符串地址)。調用 StrCopy 要求 PWord 已分配內存,否則發生保護錯。try...finally 保護內存資源釋放。
用戶輸入按回車後要求再次輸入確認,相同才能正常關閉,否則清空重輸。實現於 Edit1KeyPress:
procedure TSetPassWordForm.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Edit1.Text = '' then Exit;
if Key = #13 then
begin
if Verified then
if StrPas(PassWord) = Edit1.Text then
begin
OKBtn.Enabled := True;
Edit1.Enabled := False;
OKBtn.SetFocus;
end
else
begin
Verified := False;
MessageDlg('PassWord is InValid.', mtWarning, [mbOK], 0);
Edit1.Text := '';
PassWord := '';
Label1.Caption := 'Please Input PassWord:';
end
else
begin
Verified := True;
StrPCopy(PassWord, Edit1.Text);
Edit1.Text := '';
Label1.Caption := 'Please Verify PassWord:';
end;
Key := #0;
end;
end;
單一導出函數 GetPassWord:
function GetPassword(Password: PChar): Boolean;
var GetPasswordForm: TGetPasswordForm;
begin
Result := False;
GetPasswordForm := TGetPasswordForm.Create(Application);
try
with GetPasswordForm do
if ShowModal = mrOK then
if UpperCase(Edit1.Text) <> StrPas(StrUpper(Password)) then
MessageDlg('Invalid Password', mtWarning, [mbOK], 0)
else Result := True;
finally
GetPasswordForm.Free;
end;
end;
Password 為輸入參數(非空),調用者維護。輸入回顯字符由 PasswordChar 屬性決定。
library PassForm;
uses
GetPass in 'GETPASS.PAS' {PasswordForm},
SetPass in 'SETPASS.PAS' {SetPassWordForm};
exports
GetPassword, SetPassWord;
begin end.
包含兩導出函數聲明(implementation 部):
function GetPassword(Password: PChar): Boolean; far; external 'c:\dlls\PassForm';
function SetPassword(Password: PChar): Boolean; far; external 'c:\dlls\PassForm';
設置密碼:
procedure TForm1.SetButtonClick(Sender: TObject);
begin
PassWord := StrAlloc(40);
if not SetPassWord(PassWord) then
MessageDlg('PassWord is not set', mtInformation, [mbOK], 0);
end;
驗證密碼:
procedure TForm1.TestButtonClick(Sender: TObject);
begin
if PassWord = nil then
begin
MessageDlg('Set password first', mtInformation, [mbOK], 0);
SetButton.SetFocus; Exit;
end;
if GetPassword(PassWord) then
Label1.Caption := 'You are Welcome!'
else
Label1.Caption := 'Sorry, You are Invalid User.';
end;
VB 不支持創建 DLL 但可調用標準 Windows API DLL 和他語言 DLL。驗證 DLL 通用性:
Option Explicit
Declare Function GetPassWord Lib "c:\dlls\passform.dll" (ByVal PassWord As String) As Integer
Declare Function SetPassWord Lib "c:\dlls\passform.dll" (ByVal PassWord As String) As Integer
Dim PassWord As String * 40
Sub Check_Click()
If PassWord = "" Then
MsgBox "Enter sample password first": SetPass.SetFocus
Else
If GetPassWord(PassWord) Then StatusLbl.Caption = "You are Welcome!"
Else StatusLbl.Caption = "Sorry,You are Invalid User."
End If
End Sub
Sub SetPass_Click()
If SetPassWord(PassWord) = 0 Then MsgBox "PassWord is not Set."
End Sub
DLL 編程中 Delphi 表現優異,窗體重用機制是 Delphi 對 Windows DLL 編程的重大改進。一般 DLL 編程也體現 Delphi 快捷方便特點。DLL 是 Windows 程序組織重要方式,保護不同工具/時期工作成果,可構建自己的程序模塊庫。