home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 September
/
Chip_2001-09_cd1.bin
/
zkuste
/
delphi
/
kolekce
/
d6
/
RX275D6.ZIP
/
Units
/
LoginDlg.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1999-10-12
|
14KB
|
465 lines
{*******************************************************}
{ }
{ Delphi VCL Extensions (RX) }
{ }
{ Copyright (c) 1995, 1996 AO ROSNO }
{ Copyright (c) 1997, 1998 Master-Bank }
{ }
{*******************************************************}
unit LoginDlg;
{$I RX.INC}
interface
uses SysUtils, Messages, Classes, Controls, Forms, Dialogs, StdCtrls,
ExtCtrls, DB, DBTables, DBLists, RxLogin, BdeUtils;
type
TCheckUserNameEvent = function(UsersTable: TTable;
const UserName, Password: string): Boolean of object;
TDialogMode = (dmAppLogin, dmDBLogin, dmUnlock);
TDBLoginDialog = class
private
FDialog: TRxLoginForm;
FMode: TDialogMode;
FSelectDatabase: Boolean;
FIniAliasName: string;
FCheckUserEvent: TCheckUserNameEvent;
FCheckUnlock: TCheckUnlockEvent;
FIconDblClick: TNotifyEvent;
procedure Login(Database: TDatabase; LoginParams: TStrings);
function GetUserInfo: Boolean;
function CheckUser(Table: TTable): Boolean;
function CheckUnlock: Boolean;
procedure OkBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
function ExecuteAppLogin: Boolean;
function ExecuteDbLogin(LoginParams: TStrings): Boolean;
function ExecuteUnlock: Boolean;
public
Database: TDatabase;
AttemptNumber: Integer;
ShowDBName: Boolean;
UsersTableName: string;
UserNameField: string;
MaxPwdLen: Integer;
LoginName: string;
IniFileName: string;
UseRegistry: Boolean;
constructor Create(DialogMode: TDialogMode; DatabaseSelect: Boolean);
destructor Destroy; override;
function Execute(LoginParams: TStrings): Boolean;
function GetUserName: string;
function CheckDatabaseChange: Boolean;
procedure FillParams(LoginParams: TStrings);
property Mode: TDialogMode read FMode;
property SelectDatabase: Boolean read FSelectDatabase;
property OnCheckUnlock: TCheckUnlockEvent read FCheckUnlock write FCheckUnlock;
property OnCheckUserEvent: TCheckUserNameEvent read FCheckUserEvent write FCheckUserEvent;
property OnIconDblClick: TNotifyEvent read FIconDblClick write FIconDblClick;
end;
procedure OnLoginDialog(Database: TDatabase; LoginParams: TStrings;
AttemptNumber: Integer; ShowDBName: Boolean);
function LoginDialog(Database: TDatabase; AttemptNumber: Integer;
const UsersTableName, UserNameField: string; MaxPwdLen: Integer;
CheckUserEvent: TCheckUserNameEvent; IconDblClick: TNotifyEvent;
var LoginName: string; const IniFileName: string;
UseRegistry, SelectDatabase: Boolean): Boolean;
function UnlockDialog(const UserName: string; OnUnlock: TCheckUnlockEvent;
IconDblClick: TNotifyEvent): Boolean;
function UnlockDialogEx(const UserName: string; OnUnlock: TCheckUnlockEvent;
IconDblClick: TNotifyEvent; MaxPwdLen, AttemptNumber: Integer): Boolean;
implementation
uses {$IFDEF WIN32} Windows, Registry, BDE, {$ELSE} WinTypes, WinProcs,
DbiTypes, {$ENDIF} IniFiles, Graphics, AppUtils, RxDConst, Consts,
VclUtils, RxConst;
const
keyLastLoginUserName = 'LastUser';
keySelectDatabase = 'SelectDatabase'; { dialog never writes this value }
keyLastAliasName = 'LastAlias'; { used if SelectDatabase = True }
{ TDBLoginDialog }
constructor TDBLoginDialog.Create(DialogMode: TDialogMode; DatabaseSelect: Boolean);
begin
inherited Create;
FMode := DialogMode;
FSelectDatabase := DatabaseSelect;
FDialog := CreateLoginDialog((FMode = dmUnlock), FSelectDatabase,
FormShow, OkBtnClick);
AttemptNumber := 3;
ShowDBName := True;
end;
destructor TDBLoginDialog.Destroy;
begin
FDialog.Free;
inherited Destroy;
end;
procedure TDBLoginDialog.OkBtnClick(Sender: TObject);
var
Ok: Boolean;
SaveLogin: TDatabaseLoginEvent;
SetCursor: Boolean;
begin
if FMode = dmUnlock then begin
Ok := False;
try
Ok := CheckUnlock;
except
Application.HandleException(Self);
end;
if Ok then FDialog.ModalResult := mrOk
else FDialog.ModalResult := mrCancel;
end
else if Mode = dmAppLogin then begin
{$IFDEF WIN32}
SetCursor := GetCurrentThreadID = MainThreadID;
{$ELSE}
SetCursor := True;
{$ENDIF}
SaveLogin := Database.OnLogin;
try
try
if FSelectDatabase then
Database.AliasName := FDialog.CustomCombo.Text;
Database.OnLogin := Login;
if SetCursor then Screen.Cursor := crHourGlass;
try
Database.Open;
finally
if SetCursor then Screen.Cursor := crDefault;
end;
except
Application.HandleException(Self);
end;
finally
Database.OnLogin := SaveLogin;
end;
if Database.Connected then
try
if SetCursor then Screen.Cursor := crHourGlass;
Ok := False;
try
Ok := GetUserInfo;
except
Application.HandleException(Self);
end;
if Ok then FDialog.ModalResult := mrOk
else begin
FDialog.ModalResult := mrNone;
Database.Close;
end;
finally
if SetCursor then Screen.Cursor := crDefault;
end;
end
else { dmDBLogin } FDialog.ModalResult := mrOk
end;
procedure TDBLoginDialog.FormShow(Sender: TObject);
var
S: string;
begin
if (FMode in [dmAppLogin, dmDBLogin]) and FSelectDatabase then begin
with TBDEItems.Create(FDialog) do
try
{$IFDEF WIN32}
SessionName := Database.SessionName;
{$ENDIF}
ItemType := bdDatabases;
FDialog.CustomCombo.Items.Clear;
Open;
while not Eof do begin
FDialog.CustomCombo.Items.Add(FieldByName('NAME').AsString);
Next;
end;
if FIniAliasName = '' then S := Database.AliasName
else S := FIniAliasName;
with FDialog.CustomCombo do ItemIndex := Items.IndexOf(S);
finally
Free;
end;
end;
end;
function TDBLoginDialog.ExecuteAppLogin: Boolean;
var
Ini: TObject;
begin
try
{$IFDEF WIN32}
if UseRegistry then begin
Ini := TRegIniFile.Create(IniFileName);
{$IFDEF RX_D5}
TRegIniFile(Ini).Access := KEY_READ;
{$ENDIF}
end
else
Ini := TIniFile.Create(IniFileName);
{$ELSE}
Ini := TIniFile.Create(IniFileName);
{$ENDIF WIN32}
try
FDialog.UserNameEdit.Text := IniReadString(Ini, FDialog.ClassName,
keyLastLoginUserName, LoginName);
FSelectDatabase := IniReadBool(Ini, FDialog.ClassName,
keySelectDatabase, FSelectDatabase);
FIniAliasName := IniReadString(Ini, FDialog.ClassName,
keyLastAliasName, '');
finally
Ini.Free;
end;
except
IniFileName := '';
end;
FDialog.SelectDatabase := SelectDatabase;
Result := (FDialog.ShowModal = mrOk);
Database.OnLogin := nil;
if Result then begin
LoginName := GetUserName;
if IniFileName <> '' then begin
{$IFDEF WIN32}
if UseRegistry then Ini := TRegIniFile.Create(IniFileName)
else Ini := TIniFile.Create(IniFileName);
{$ELSE}
Ini := TIniFile.Create(IniFileName);
{$ENDIF WIN32}
try
IniWriteString(Ini, FDialog.ClassName, keyLastLoginUserName, GetUserName);
IniWriteString(Ini, FDialog.ClassName, keyLastAliasName, Database.AliasName);
finally
Ini.Free;
end;
end;
end;
end;
function TDBLoginDialog.ExecuteDbLogin(LoginParams: TStrings): Boolean;
{$IFDEF WIN32}
var
CurrSession: TSession;
{$ENDIF}
begin
Result := False;
if (Database = nil) or not Assigned(LoginParams) then Exit;
if ShowDBName then
FDialog.AppTitleLabel.Caption := FmtLoadStr(SDatabaseName,
[Database.DatabaseName]);
FDialog.UserNameEdit.Text := LoginParams.Values[szUSERNAME];
{$IFDEF WIN32}
CurrSession := Sessions.CurrentSession;
{$ENDIF}
try
Result := FDialog.ShowModal = mrOk;
if Result then FillParams(LoginParams)
else SysUtils.Abort;
finally
{$IFDEF WIN32}
Sessions.CurrentSession := CurrSession;
{$ENDIF}
end;
end;
function TDBLoginDialog.ExecuteUnlock: Boolean;
begin
with FDialog.UserNameEdit do begin
Text := LoginName;
ReadOnly := True;
Font.Color := clGrayText;
end;
Result := (FDialog.ShowModal = mrOk);
end;
function TDBLoginDialog.Execute(LoginParams: TStrings): Boolean;
var
SaveCursor: TCursor;
begin
SaveCursor := Screen.Cursor;
Screen.Cursor := crDefault;
try
if Assigned(FIconDblClick) then begin
with FDialog.AppIcon do begin
OnDblClick := OnIconDblClick;
Cursor := crHand;
end;
with FDialog.KeyImage do begin
OnDblClick := OnIconDblClick;
Cursor := crHand;
end;
end;
FDialog.PasswordEdit.MaxLength := MaxPwdLen;
FDialog.AttemptNumber := AttemptNumber;
case FMode of
dmAppLogin: Result := ExecuteAppLogin;
dmDBLogin: Result := ExecuteDbLogin(LoginParams);
dmUnlock: Result := ExecuteUnlock;
else Result := False;
end;
if Result then LoginName := GetUserName;
finally
Screen.Cursor := SaveCursor;
end;
end;
function TDBLoginDialog.GetUserName: string;
begin
if CheckDatabaseChange then
Result := Copy(FDialog.UserNameEdit.Text, 1,
Pos('@', FDialog.UserNameEdit.Text) - 1)
else
Result := FDialog.UserNameEdit.Text;
end;
function TDBLoginDialog.CheckDatabaseChange: Boolean;
begin
Result := (FMode in [dmAppLogin, dmDBLogin]) and
(Pos('@', Fdialog.UserNameEdit.Text) > 0) and
((Database <> nil) and (Database.DriverName <> '') and
(CompareText(Database.DriverName, szCFGDBSTANDARD) <> 0));
end;
procedure TDBLoginDialog.FillParams(LoginParams: TStrings);
begin
LoginParams.Values[szUSERNAME] := GetUserName;
LoginParams.Values['PASSWORD'] := FDialog.PasswordEdit.Text;
if CheckDatabaseChange then begin
LoginParams.Values[szSERVERNAME] := Copy(FDialog.UserNameEdit.Text,
Pos('@', FDialog.UserNameEdit.Text) + 1, MaxInt)
end;
end;
procedure TDBLoginDialog.Login(Database: TDatabase; LoginParams: TStrings);
begin
FillParams(LoginParams);
end;
function TDBLoginDialog.GetUserInfo: Boolean;
var
Table: TTable;
begin
if UsersTableName = '' then Result := CheckUser(nil)
else begin
Result := False;
Table := TTable.Create(Database);
try
try
Table.DatabaseName := Database.DatabaseName;
{$IFDEF WIN32}
Table.SessionName := Database.SessionName;
{$ENDIF}
Table.TableName := UsersTableName;
Table.IndexFieldNames := UserNameField;
Table.Open;
if Table.FindKey([GetUserName]) then begin
Result := CheckUser(Table);
if not Result then
raise EDatabaseError.Create(LoadStr(SInvalidUserName));
end
else
raise EDatabaseError.Create(LoadStr(SInvalidUserName));
except
Application.HandleException(Self);
end;
finally
Table.Free;
end;
end;
end;
function TDBLoginDialog.CheckUser(Table: TTable): Boolean;
begin
if Assigned(FCheckUserEvent) then
Result := FCheckUserEvent(Table, GetUserName, FDialog.PasswordEdit.Text)
else Result := True;
end;
function TDBLoginDialog.CheckUnlock: Boolean;
begin
if Assigned(FCheckUnlock) then
Result := FCheckUnlock(FDialog.PasswordEdit.Text)
else Result := True;
end;
{ Utility routines }
procedure OnLoginDialog(Database: TDatabase; LoginParams: TStrings;
AttemptNumber: Integer; ShowDBName: Boolean);
var
Dlg: TDBLoginDialog;
begin
Dlg := TDBLoginDialog.Create(dmDBLogin, False);
try
Dlg.Database := Database;
Dlg.ShowDBName := ShowDBName;
Dlg.AttemptNumber := AttemptNumber;
Dlg.Execute(LoginParams);
finally
Dlg.Free;
end;
end;
function UnlockDialogEx(const UserName: string; OnUnlock: TCheckUnlockEvent;
IconDblClick: TNotifyEvent; MaxPwdLen, AttemptNumber: Integer): Boolean;
var
Dlg: TDBLoginDialog;
begin
Dlg := TDBLoginDialog.Create(dmUnlock, False);
try
Dlg.LoginName := UserName;
Dlg.OnIconDblClick := IconDblClick;
Dlg.OnCheckUnlock := OnUnlock;
Dlg.MaxPwdLen := MaxPwdLen;
Dlg.AttemptNumber := AttemptNumber;
Result := Dlg.Execute(nil);
finally
Dlg.Free;
end;
end;
function UnlockDialog(const UserName: string; OnUnlock: TCheckUnlockEvent;
IconDblClick: TNotifyEvent): Boolean;
begin
Result := UnlockDialogEx(UserName, OnUnlock, IconDblClick, 0, 1);
end;
function LoginDialog(Database: TDatabase; AttemptNumber: Integer;
const UsersTableName, UserNameField: string; MaxPwdLen: Integer;
CheckUserEvent: TCheckUserNameEvent; IconDblClick: TNotifyEvent;
var LoginName: string; const IniFileName: string;
UseRegistry, SelectDatabase: Boolean): Boolean;
var
Dlg: TDBLoginDialog;
begin
Dlg := TDBLoginDialog.Create(dmAppLogin, SelectDatabase);
try
Dlg.LoginName := LoginName;
Dlg.OnIconDblClick := IconDblClick;
Dlg.OnCheckUserEvent := CheckUserEvent;
Dlg.MaxPwdLen := MaxPwdLen;
Dlg.Database := Database;
Dlg.AttemptNumber := AttemptNumber;
Dlg.UsersTableName := UsersTableName;
Dlg.UserNameField := UserNameField;
Dlg.IniFileName := IniFileName;
Dlg.UseRegistry := UseRegistry;
Result := Dlg.Execute(nil);
if Result then LoginName := Dlg.LoginName;
finally
Dlg.Free;
end;
end;
end.