home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 26
/
CD_ASCQ_26_1295.iso
/
vrac
/
dbctrls.zip
/
DBCTRLS.PAS
next >
Wrap
Pascal/Delphi Source File
|
1995-07-16
|
72KB
|
2,835 lines
{*******************************************************}
{ }
{ Delphi Visual Component Library }
{ }
{ Copyright (c) 1995 Borland International }
{ }
{*******************************************************}
unit DBCtrls;
interface
uses SysUtils, WinTypes, WinProcs, Messages, Classes, Controls, Forms,
Graphics, Menus, StdCtrls, ExtCtrls, DB, DBTables, Mask, Buttons;
type
{ TDBEdit }
TDBEdit = class(TCustomMaskEdit)
private
FDataLink: TFieldDataLink;
FCanvas: TControlCanvas;
FAlignment: TAlignment;
FFocused: Boolean;
FTextMargin: Integer;
procedure CalcTextMargin;
procedure DataChange(Sender: TObject);
procedure EditingChange(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetFocused(Value: Boolean);
procedure SetReadOnly(Value: Boolean);
procedure UpdateData(Sender: TObject);
procedure WMCut(var Message: TMessage); message WM_CUT;
procedure WMPaste(var Message: TMessage); message WM_PASTE;
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
protected
procedure Change; override;
function EditCanModify: Boolean; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure Reset; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Field: TField read GetField;
published
property AutoSelect;
property AutoSize;
property BorderStyle;
property CharCase;
property Color;
property Ctl3D;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property MaxLength;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PasswordChar;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
{ TDBText }
TDBText = class(TCustomLabel)
private
FDataLink: TFieldDataLink;
procedure DataChange(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
protected
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Field: TField read GetField;
published
property Align;
property Alignment;
property AutoSize default False;
property Color;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Transparent;
property ShowHint;
property Visible;
property WordWrap;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
{ TDBCheckBox }
TDBCheckBox = class(TCustomCheckBox)
private
FDataLink: TFieldDataLink;
FValueCheck: PString;
FValueUncheck: PString;
procedure DataChange(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
function GetValueCheck: string;
function GetValueUncheck: string;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetReadOnly(Value: Boolean);
procedure SetValueCheck(const Value: string);
procedure SetValueUncheck(const Value: string);
procedure UpdateData(Sender: TObject);
function ValueMatch(const ValueList, Value: string): Boolean;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
protected
procedure Toggle; override;
procedure KeyPress(var Key: Char); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Checked;
property Field: TField read GetField;
property State;
published
property Alignment;
property AllowGrayed;
property Caption;
property Color;
property Ctl3D;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ShowHint;
property TabOrder;
property TabStop;
property ValueChecked: string read GetValueCheck write SetValueCheck;
property ValueUnchecked: string read GetValueUncheck write SetValueUncheck;
property Visible;
property OnClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
{ TDBComboBox }
TDBComboBox = class(TCustomComboBox)
private
FDataLink: TFieldDataLink;
procedure DataChange(Sender: TObject);
procedure EditingChange(Sender: TObject);
function GetComboText: string;
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
procedure SetComboText(const Value: string);
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetEditReadOnly;
procedure SetItems(Value: TStrings);
procedure SetReadOnly(Value: Boolean);
procedure UpdateData(Sender: TObject);
procedure CMExit(var Message: TCMExit); message CM_EXIT;
protected
procedure Change; override;
procedure Click; override;
procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd;
ComboProc: Pointer); override;
procedure CreateWnd; override;
procedure DropDown; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure WndProc(var Message: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Field: TField read GetField;
property Text;
published
property Style; {Must be published before Items}
property Color;
property Ctl3D;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragMode;
property DragCursor;
property DropDownCount;
property Enabled;
property Font;
property ItemHeight;
property Items write SetItems;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ShowHint;
property Sorted;
property TabOrder;
property TabStop;
property Visible;
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDrawItem;
property OnDropDown;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMeasureItem;
end;
{ TDBListBox }
TDBListBox = class(TCustomListBox)
private
FDataLink: TFieldDataLink;
procedure DataChange(Sender: TObject);
procedure UpdateData(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetReadOnly(Value: Boolean);
procedure SetItems(Value: TStrings);
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
protected
procedure Click; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Field: TField read GetField;
published
property Align;
property BorderStyle;
property Color;
property Ctl3D default True;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property IntegralHeight;
property ItemHeight;
property Items write SetItems;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDrawItem;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMeasureItem;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
{ TDBRadioGroup }
TDBRadioGroup = class(TCustomRadioGroup)
private
FDataLink: TFieldDataLink;
FValue: PString;
FValues: TStrings;
FOnChange: TNotifyEvent;
procedure DataChange(Sender: TObject);
procedure UpdateData(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
function GetValue: string;
function GetButtonValue(Index: Integer): string;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetReadOnly(Value: Boolean);
procedure SetValue(const Value: string);
procedure SetItems(Value: TStrings);
procedure SetValues(Value: TStrings);
procedure CMExit(var Message: TCMExit); message CM_EXIT;
protected
procedure Change; dynamic;
procedure Click; override;
procedure KeyPress(var Key: Char); override;
function CanModify: Boolean; override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
property DataLink: TFieldDataLink read FDataLink;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Field: TField read GetField;
property ItemIndex;
property Value: string read GetValue write SetValue;
published
property Align;
property Caption;
property Color;
property Columns;
property Ctl3D;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property Items write SetItems;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ShowHint;
property TabOrder;
property TabStop;
property Values: TStrings read FValues write SetValues;
property Visible;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
end;
{ TDBMemo }
TDBMemo = class(TCustomMemo)
private
FDataLink: TFieldDataLink;
FAutoDisplay: Boolean;
FFocused: Boolean;
FMemoLoaded: Boolean;
FReserved: Byte;
procedure DataChange(Sender: TObject);
procedure EditingChange(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetReadOnly(Value: Boolean);
procedure SetAutoDisplay(Value: Boolean);
procedure SetFocused(Value: Boolean);
procedure UpdateData(Sender: TObject);
procedure WMCut(var Message: TMessage); message WM_CUT;
procedure WMPaste(var Message: TMessage); message WM_PASTE;
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
protected
procedure Change; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure LoadMemo;
property Field: TField read GetField;
published
property Align;
property Alignment;
property AutoDisplay: Boolean read FAutoDisplay write SetAutoDisplay default True;
property BorderStyle;
property Color;
property Ctl3D;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property MaxLength;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ScrollBars;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property WantTabs;
property WordWrap;
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
{ TDBImage }
TDBImage = class(TCustomControl)
private
FDataLink: TFieldDataLink;
FPicture: TPicture;
FBorderStyle: TBorderStyle;
FAutoDisplay: Boolean;
FStretch: Boolean;
FCenter: Boolean;
FPictureLoaded: Boolean;
FReserved: Byte;
procedure DataChange(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetReadOnly: Boolean;
procedure PictureChanged(Sender: TObject);
procedure SetAutoDisplay(Value: Boolean);
procedure SetBorderStyle(Value: TBorderStyle);
procedure SetCenter(Value: Boolean);
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetPicture(Value: TPicture);
procedure SetReadOnly(Value: Boolean);
procedure SetStretch(Value: Boolean);
procedure UpdateData(Sender: TObject);
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
procedure WMCut(var Message: TMessage); message WM_CUT;
procedure WMCopy(var Message: TMessage); message WM_COPY;
procedure WMPaste(var Message: TMessage); message WM_PASTE;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
protected
procedure CreateParams(var Params: TCreateParams); override;
function GetPalette: HPALETTE; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure CopyToClipboard;
procedure CutToClipboard;
procedure LoadPicture;
procedure PasteFromClipboard;
property Field: TField read GetField;
property Picture: TPicture read FPicture write SetPicture;
published
property Align;
property AutoDisplay: Boolean read FAutoDisplay write SetAutoDisplay default True;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property Center: Boolean read FCenter write SetCenter default True;
property Color;
property Ctl3D;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property ParentColor default False;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property ShowHint;
property Stretch: Boolean read FStretch write SetStretch default False;
property TabOrder;
property TabStop default True;
property Visible;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
const
InitRepeatPause = 400; { pause before repeat timer (ms) }
RepeatPause = 100; { pause before hint window displays (ms)}
SpaceSize = 5; { size of space between special buttons }
type
TNavButton = class;
TNavDataLink = class;
TNavGlyph = (ngEnabled, ngDisabled);
TNavigateBtn = (nbFirst, nbPrior, nbNext, nbLast,
nbInsert, nbDelete, nbEdit, nbPost, nbCancel, nbRefresh);
TButtonSet = set of TNavigateBtn;
TNavButtonStyle = set of (nsAllowTimer, nsFocusRect);
ENavClick = procedure (Sender: TObject; Button: TNavigateBtn) of object;
{ TDBNavigator }
TDBNavigator = class (TCustomPanel)
private
FDataLink: TNavDataLink;
FVisibleButtons: TButtonSet;
FHints: TStrings;
ButtonWidth: Integer;
MinBtnSize: TPoint;
FOnNavClick: ENavClick;
FocusedButton: TNavigateBtn;
FConfirmDelete: Boolean;
function GetDataSource: TDataSource;
procedure SetDataSource(Value: TDataSource);
procedure InitButtons;
procedure InitHints;
procedure Click(Sender: TObject);
procedure BtnMouseDown (Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SetVisible(Value: TButtonSet);
procedure AdjustSize (var W: Integer; var H: Integer);
procedure SetHints(Value: TStrings);
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
protected
Buttons: array[TNavigateBtn] of TNavButton;
procedure DataChanged;
procedure EditingChanged;
procedure ActiveChanged;
procedure Loaded; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
procedure BtnClick(Index: TNavigateBtn);
published
property DataSource: TDataSource read GetDataSource write SetDataSource;
property VisibleButtons: TButtonSet read FVisibleButtons write SetVisible
default [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete,
nbEdit, nbPost, nbCancel, nbRefresh];
property Align;
property DragCursor;
property DragMode;
property Enabled;
property Ctl3D;
property Hints: TStrings read FHints write SetHints;
property ParentCtl3D;
property ParentShowHint;
property PopupMenu;
property ConfirmDelete: Boolean read FConfirmDelete write FConfirmDelete default True;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick: ENavClick read FOnNavClick write FOnNavClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnResize;
end;
{ TNavButton }
TNavButton = class(TSpeedButton)
private
FIndex: TNavigateBtn;
FNavStyle: TNavButtonStyle;
FRepeatTimer: TTimer;
procedure TimerExpired(Sender: TObject);
protected
procedure Paint; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
public
destructor Destroy; override;
property NavStyle: TNavButtonStyle read FNavStyle write FNavStyle;
property Index : TNavigateBtn read FIndex write FIndex;
end;
{ TNavDataLink }
TNavDataLink = class(TDataLink)
private
FNavigator: TDBNavigator;
protected
procedure EditingChanged; override;
procedure DataSetChanged; override;
procedure ActiveChanged; override;
public
constructor Create(ANav: TDBNavigator);
destructor Destroy; override;
end;
implementation
uses DBIErrs, DBITypes, Clipbrd, DBConsts, Dialogs;
{$R DBCTRLS}
{ TDBEdit }
constructor TDBEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
inherited ReadOnly := True;
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnEditingChange := EditingChange;
FDataLink.OnUpdateData := UpdateData;
CalcTextMargin;
end;
destructor TDBEdit.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
FCanvas.Free;
inherited Destroy;
end;
procedure TDBEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
FDataLink.Edit;
end;
procedure TDBEdit.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
not FDataLink.Field.IsValidChar(Key) then
begin
MessageBeep(0);
Key := #0;
end;
case Key of
^H, ^V, ^X, #32..#255:
FDataLink.Edit;
#27:
begin
FDataLink.Reset;
SelectAll;
Key := #0;
end;
end;
end;
function TDBEdit.EditCanModify: Boolean;
begin
Result := FDataLink.Edit;
end;
procedure TDBEdit.Reset;
begin
FDataLink.Reset;
SelectAll;
end;
procedure TDBEdit.SetFocused(Value: Boolean);
begin
if FFocused <> Value then
begin
FFocused := Value;
if (FAlignment <> taLeftJustify) and not IsMasked then Invalidate;
FDataLink.Reset;
end;
end;
procedure TDBEdit.Change;
begin
FDataLink.Modified;
inherited Change;
end;
function TDBEdit.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBEdit.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBEdit.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBEdit.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBEdit.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBEdit.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBEdit.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TDBEdit.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
begin
if FAlignment <> FDataLink.Field.Alignment then
begin
EditText := ''; {forces update}
FAlignment := FDataLink.Field.Alignment;
end;
EditMask := FDataLink.Field.EditMask;
if FDataLink.Field.DataType = ftString then
MaxLength := FDataLink.Field.Size else
MaxLength := 0;
if FFocused and FDataLink.CanModify then
Text := FDataLink.Field.Text
else
EditText := FDataLink.Field.DisplayText;
end else
begin
FAlignment := taLeftJustify;
EditMask := '';
MaxLength := 0;
if csDesigning in ComponentState then
EditText := Name else
EditText := '';
end;
end;
procedure TDBEdit.EditingChange(Sender: TObject);
begin
inherited ReadOnly := not FDataLink.Editing;
end;
procedure TDBEdit.UpdateData(Sender: TObject);
begin
ValidateEdit;
FDataLink.Field.Text := Text;
end;
procedure TDBEdit.WMPaste(var Message: TMessage);
begin
FDataLink.Edit;
inherited;
end;
procedure TDBEdit.WMCut(var Message: TMessage);
begin
FDataLink.Edit;
inherited;
end;
procedure TDBEdit.CMEnter(var Message: TCMEnter);
begin
SetFocused(True);
inherited;
end;
procedure TDBEdit.CMExit(var Message: TCMExit);
begin
try
FDataLink.UpdateRecord;
except
SelectAll;
SetFocus;
raise;
end;
SetFocused(False);
SetCursor(0);
DoExit;
end;
procedure TDBEdit.WMPaint(var Message: TWMPaint);
var
Width, Indent, Left, I: Integer;
R: TRect;
DC: HDC;
PS: TPaintStruct;
S: string;
begin
if (FAlignment = taLeftJustify) or FFocused then
begin
inherited;
Exit;
end;
{ Since edit controls do not handle justification unless multi-line (and
then only poorly) we will draw right and center justify manually unless
the edit has the focus. }
if FCanvas = nil then
begin
FCanvas := TControlCanvas.Create;
FCanvas.Control := Self;
end;
DC := Message.DC;
if DC = 0 then DC := BeginPaint(Handle, PS);
FCanvas.Handle := DC;
try
FCanvas.Font := Font;
with FCanvas do
begin
R := ClientRect;
if (BorderStyle = bsSingle) then
begin
Brush.Color := clWindowFrame;
FrameRect(R);
InflateRect(R, -1, -1);
end;
Brush.Color := Color;
S := EditText;
if PasswordChar <> #0 then
begin
for I := 1 to Length(S) do
S[I] := PasswordChar;
end;
Width := TextWidth(S);
if BorderStyle = bsNone then Indent := 0 else Indent := FTextMargin;
if FAlignment = taRightJustify then
Left := R.Right - Width - Indent else
Left := (R.Left + R.Right - Width) div 2;
TextRect(R, Left, Indent, S);
end;
finally
FCanvas.Handle := 0;
if Message.DC = 0 then EndPaint(Handle, PS);
end;
end;
procedure TDBEdit.CMFontChanged(var Message: TMessage);
begin
inherited;
CalcTextMargin;
end;
procedure TDBEdit.CalcTextMargin;
var
DC: HDC;
SaveFont: HFont;
I: Integer;
SysMetrics, Metrics: TTextMetric;
begin
DC := GetDC(0);
GetTextMetrics(DC, SysMetrics);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
I := SysMetrics.tmHeight;
if I > Metrics.tmHeight then I := Metrics.tmHeight;
FTextMargin := I div 4;
end;
{ TDBText }
constructor TDBText.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
AutoSize := False;
ShowAccelChar := False;
FDataLink := TFieldDataLink.Create;
FDataLink.OnDataChange := DataChange;
end;
destructor TDBText.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
procedure TDBText.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
function TDBText.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBText.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBText.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBText.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBText.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TDBText.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
Caption := FDataLink.Field.DisplayText
else
if csDesigning in ComponentState then Caption := Name else Caption := '';
end;
{ TDBCheckBox }
constructor TDBCheckBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
State := cbUnchecked;
FValueCheck := NewStr(LoadStr(STextTrue));
FValueUncheck := NewStr(LoadStr(STextFalse));
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
end;
destructor TDBCheckBox.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
DisposeStr(FValueUncheck);
DisposeStr(FValueCheck);
inherited Destroy;
end;
procedure TDBCheckBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBCheckBox.DataChange(Sender: TObject);
var
NewState: TCheckBoxState;
Text: string;
begin
NewState := cbGrayed;
if (FDataLink.Field <> nil) and not FDataLink.Field.IsNull then
if FDataLink.Field.DataType = ftBoolean then
if FDataLink.Field.AsBoolean then
NewState := cbChecked
else
NewState := cbUnchecked
else
begin
Text := FDataLink.Field.Text;
if ValueMatch(FValueCheck^, Text) then NewState := cbChecked else
if ValueMatch(FValueUncheck^, Text) then NewState := cbUnchecked;
end;
State := NewState;
end;
procedure TDBCheckBox.UpdateData(Sender: TObject);
var
Pos: Integer;
S: PString;
begin
if State = cbGrayed then
FDataLink.Field.Clear
else
if FDataLink.Field.DataType = ftBoolean then
FDataLink.Field.AsBoolean := Checked
else
begin
if Checked then S := FValueCheck else S := FValueUncheck;
Pos := 1;
FDataLink.Field.Text := ExtractFieldName(S^, Pos);
end;
end;
function TDBCheckBox.ValueMatch(const ValueList, Value: string): Boolean;
var
Pos: Integer;
begin
Result := False;
Pos := 1;
while Pos <= Length(ValueList) do
if AnsiCompareText(ExtractFieldName(ValueList, Pos), Value) = 0 then
begin
Result := True;
Break;
end;
end;
procedure TDBCheckBox.Toggle;
begin
if FDataLink.Edit then
begin
inherited Toggle;
FDataLink.Modified;
end;
end;
function TDBCheckBox.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBCheckBox.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBCheckBox.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBCheckBox.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBCheckBox.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBCheckBox.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBCheckBox.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TDBCheckBox.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
case Key of
#8, ' ':
FDataLink.Edit;
#27:
FDataLink.Reset;
end;
end;
function TDBCheckBox.GetValueCheck: string;
begin
Result := FValueCheck^;
end;
function TDBCheckBox.GetValueUncheck: string;
begin
Result := FValueUncheck^;
end;
procedure TDBCheckBox.SetValueCheck(const Value: string);
begin
AssignStr(FValueCheck, Value);
DataChange(Self);
end;
procedure TDBCheckBox.SetValueUncheck(const Value: string);
begin
AssignStr(FValueUncheck, Value);
DataChange(Self);
end;
procedure TDBCheckBox.CMExit(var Message: TCMExit);
begin
try
FDataLink.UpdateRecord;
except
SetFocus;
raise;
end;
inherited;
end;
{ TDBComboBox }
constructor TDBComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
FDataLink.OnEditingChange := EditingChange;
end;
destructor TDBComboBox.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
procedure TDBComboBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBComboBox.CreateWnd;
begin
inherited CreateWnd;
SetEditReadOnly;
end;
procedure TDBComboBox.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
SetComboText(FDataLink.Field.Text)
else
if csDesigning in ComponentState then
SetComboText(Name)
else
SetComboText('');
end;
procedure TDBComboBox.UpdateData(Sender: TObject);
begin
FDataLink.Field.Text := GetComboText;
end;
procedure TDBComboBox.SetComboText(const Value: string);
var
I: Integer;
begin
if Value <> GetComboText then
begin
if Style <> csDropDown then
begin
if Value = '' then I := -1 else I := Items.IndexOf(Value);
ItemIndex := I;
if I >= 0 then Exit;
end;
if Style in [csDropDown, csSimple] then Text := Value;
end;
end;
function TDBComboBox.GetComboText: string;
var
I: Integer;
begin
if Style in [csDropDown, csSimple] then Result := Text else
begin
I := ItemIndex;
if ItemIndex < 0 then Result := '' else Result := Items[I];
end;
end;
procedure TDBComboBox.Change;
begin
FDataLink.Edit;
inherited Change;
FDataLink.Modified;
end;
procedure TDBComboBox.Click;
begin
FDataLink.Edit;
inherited Click;
FDataLink.Modified;
end;
procedure TDBComboBox.DropDown;
begin
FDataLink.Edit;
inherited DropDown;
end;
function TDBComboBox.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBComboBox.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBComboBox.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBComboBox.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBComboBox.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBComboBox.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBComboBox.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TDBComboBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if Key in [VK_BACK, VK_DELETE, VK_UP, VK_DOWN, 32..255] then
begin
if not FDataLink.Edit and (Key in [VK_UP, VK_DOWN]) then
Key := 0;
end;
end;
procedure TDBComboBox.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
not FDataLink.Field.IsValidChar(Key) then
begin
MessageBeep(0);
Key := #0;
end;
case Key of
^H, ^V, ^X, #32..#255:
FDataLink.Edit;
#27:
begin
FDataLink.Reset;
SelectAll;
Key := #0;
end;
end;
end;
procedure TDBComboBox.EditingChange(Sender: TObject);
begin
SetEditReadOnly;
end;
procedure TDBComboBox.SetEditReadOnly;
begin
if (Style in [csDropDown, csSimple]) and HandleAllocated then
SendMessage(FEditHandle, EM_SETREADONLY, Ord(not FDataLink.Editing), 0);
end;
procedure TDBComboBox.WndProc(var Message: TMessage);
begin
if not (csDesigning in ComponentState) then
case Message.Msg of
WM_COMMAND:
if TWMCommand(Message).NotifyCode = CBN_SELCHANGE then
if not FDataLink.Edit then
begin
if Style <> csSimple then
PostMessage(Handle, CB_SHOWDROPDOWN, 0, 0);
Exit;
end;
CB_SHOWDROPDOWN:
if Message.WParam <> 0 then FDataLink.Edit else
if not FDataLink.Editing then DataChange(Self); {Restore text}
end;
inherited WndProc (Message);
end;
procedure TDBComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd;
ComboProc: Pointer);
begin
if not (csDesigning in ComponentState) then
case Message.Msg of
WM_LBUTTONDOWN:
if (Style = csSimple) and (ComboWnd <> FEditHandle) then
if not FDataLink.Edit then Exit;
end;
inherited ComboWndProc (Message, ComboWnd, ComboProc);
end;
procedure TDBComboBox.CMExit(var Message: TCMExit);
begin
try
FDataLink.UpdateRecord;
except
SelectAll;
SetFocus;
raise;
end;
inherited;
end;
procedure TDBComboBox.SetItems(Value: TStrings);
begin
Items.Assign(Value);
DataChange(Self);
end;
{ TDBListBox }
constructor TDBListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
end;
destructor TDBListBox.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
procedure TDBListBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBListBox.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
ItemIndex := Items.IndexOf(FDataLink.Field.Text) else
ItemIndex := -1;
end;
procedure TDBListBox.UpdateData(Sender: TObject);
begin
if ItemIndex >= 0 then
FDataLink.Field.Text := Items[ItemIndex] else
FDataLink.Field.Text := '';
end;
procedure TDBListBox.Click;
begin
if FDataLink.Edit then
begin
inherited Click;
FDataLink.Modified;
end;
end;
function TDBListBox.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBListBox.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBListBox.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBListBox.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBListBox.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBListBox.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBListBox.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TDBListBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if Key in [VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP,
VK_RIGHT, VK_DOWN] then
if not FDataLink.Edit then Key := 0;
end;
procedure TDBListBox.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
case Key of
#32..#255:
if not FDataLink.Edit then Key := #0;
#27:
FDataLink.Reset;
end;
end;
procedure TDBListBox.WMLButtonDown(var Message: TWMLButtonDown);
begin
if FDataLink.Edit then inherited
else
begin
SetFocus;
with Message do
MouseDown(mbLeft, KeysToShiftState(Keys), XPos, YPos);
end;
end;
procedure TDBListBox.CMExit(var Message: TCMExit);
begin
try
FDataLink.UpdateRecord;
except
SetFocus;
raise;
end;
inherited;
end;
procedure TDBListBox.SetItems(Value: TStrings);
begin
Items.Assign(Value);
DataChange(Self);
end;
{ TDBRadioGroup }
constructor TDBRadioGroup.Create(AOwner: TComponent);
var
CStyle : TControlStyle;
begin
inherited Create(AOwner);
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
FValue := NullStr;
FValues := TStringList.Create;
end;
destructor TDBRadioGroup.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
DisposeStr (FValue);
FValues.Free;
inherited Destroy;
end;
procedure TDBRadioGroup.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBRadioGroup.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
Value := FDataLink.Field.Text
else
Value := EmptyStr;
end;
procedure TDBRadioGroup.UpdateData(Sender: TObject);
begin
if FDataLink.Field <> nil then
FDataLink.Field.Text := Value;
end;
function TDBRadioGroup.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBRadioGroup.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBRadioGroup.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBRadioGroup.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBRadioGroup.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBRadioGroup.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBRadioGroup.GetField: TField;
begin
Result := FDataLink.Field;
end;
function TDBRadioGroup.GetValue : string;
begin
Result := FValue^;
end;
function TDBRadioGroup.GetButtonValue(Index: Integer): string;
begin
if (Index < FValues.Count) and (FValues[Index] <> '') then
Result := FValues[Index]
else if (Index < Items.Count) then
Result := Items[Index]
else
Result := '';
end;
procedure TDBRadioGroup.SetValue (const Value: string);
var
I : Integer;
begin
AssignStr(FValue, Value);
if (ItemIndex < 0) or (GetButtonValue(ItemIndex) <> Value) then
begin
if (ItemIndex >= 0) then ItemIndex := -1;
for I := 0 to ControlCount - 1 do
begin
if GetButtonValue(I) = Value then
begin
ItemIndex := I;
break;
end;
end;
Change;
end;
end;
procedure TDBRadioGroup.CMExit(var Message: TCMExit);
begin
try
FDataLink.UpdateRecord;
except
if ItemIndex >= 0 then TRadioButton(Controls[ItemIndex]).SetFocus
else TRadioButton(Controls[0]).SetFocus;
raise;
end;
inherited;
end;
procedure TDBRadioGroup.Click;
begin
inherited Click;
if ItemIndex >= 0 then
Value := GetButtonValue(ItemIndex);
if FDataLink.Editing then FDataLink.Modified;
end;
procedure TDBRadioGroup.SetItems(Value: TStrings);
begin
Items.Assign(Value);
DataChange(Self);
end;
procedure TDBRadioGroup.SetValues(Value: TStrings);
begin
FValues.Assign(Value);
DataChange(Self);
end;
procedure TDBRadioGroup.Change;
begin
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TDBRadioGroup.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
case Key of
#8, ' ':
FDataLink.Edit;
#27:
FDataLink.Reset;
end;
end;
function TDBRadioGroup.CanModify: Boolean;
begin
Result := FDataLink.Edit;
end;
{ TDBMemo }
constructor TDBMemo.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
inherited ReadOnly := True;
FAutoDisplay := True;
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnEditingChange := EditingChange;
FDataLink.OnUpdateData := UpdateData;
end;
destructor TDBMemo.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
procedure TDBMemo.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBMemo.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if FMemoLoaded then
begin
if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
FDataLink.Edit;
end else
Key := 0;
end;
procedure TDBMemo.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
if FMemoLoaded then
begin
if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
not FDataLink.Field.IsValidChar(Key) then
begin
MessageBeep(0);
Key := #0;
end;
case Key of
^H, ^I, ^J, ^M, ^V, ^X, #32..#255:
FDataLink.Edit;
#27:
FDataLink.Reset;
end;
end else
begin
if Key = #13 then LoadMemo;
Key := #0;
end;
end;
procedure TDBMemo.Change;
begin
FDataLink.Modified;
FMemoLoaded := True;
inherited Change;
end;
function TDBMemo.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBMemo.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBMemo.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBMemo.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBMemo.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBMemo.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBMemo.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TDBMemo.LoadMemo;
begin
if not FMemoLoaded and (FDataLink.Field is TBlobField) then
begin
Lines.Assign(FDataLink.Field);
FMemoLoaded := True;
EditingChange(Self);
end;
end;
procedure TDBMemo.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
if FDataLink.Field is TBlobField then
begin
if FAutoDisplay or (FDataLink.Editing and FMemoLoaded) then
begin
FMemoLoaded := False;
LoadMemo;
end else
begin
Text := '(' + FDataLink.Field.DisplayLabel + ')';
FMemoLoaded := False;
end;
end else
begin
if FFocused and FDataLink.CanModify then
Text := FDataLink.Field.Text
else
Text := FDataLink.Field.DisplayText;
FMemoLoaded := True;
end
else
begin
if csDesigning in ComponentState then Text := Name else Text := '';
FMemoLoaded := False;
end;
end;
procedure TDBMemo.EditingChange(Sender: TObject);
begin
inherited ReadOnly := not (FDataLink.Editing and FMemoLoaded);
end;
procedure TDBMemo.UpdateData(Sender: TObject);
begin
if FDataLink.Field is TBlobField then
FDataLink.Field.Assign(Lines)
else
FDataLink.Field.Text := Text;
end;
procedure TDBMemo.SetFocused(Value: Boolean);
begin
if FFocused <> Value then
begin
FFocused := Value;
if not (FDataLink.Field is TBlobField) then FDataLink.Reset;
end;
end;
procedure TDBMemo.CMEnter(var Message: TCMEnter);
begin
SetFocused(True);
inherited;
end;
procedure TDBMemo.CMExit(var Message: TCMExit);
begin
if not (FDataLink.Field is TBlobField) then
try
FDataLink.UpdateRecord;
except
SetFocus;
raise;
end;
SetFocused(False);
inherited;
end;
procedure TDBMemo.SetAutoDisplay(Value: Boolean);
begin
if FAutoDisplay <> Value then
begin
FAutoDisplay := Value;
if Value then LoadMemo;
end;
end;
procedure TDBMemo.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
if not FMemoLoaded then LoadMemo else inherited;
end;
procedure TDBMemo.WMCut(var Message: TMessage);
begin
FDataLink.Edit;
inherited;
end;
procedure TDBMemo.WMPaste(var Message: TMessage);
begin
FDataLink.Edit;
inherited;
end;
{ TDBImage }
constructor TDBImage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csFramed, csOpaque];
Width := 105;
Height := 105;
TabStop := True;
ParentColor := False;
FPicture := TPicture.Create;
FPicture.OnChange := PictureChanged;
FBorderStyle := bsSingle;
FAutoDisplay := True;
FCenter := True;
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
end;
destructor TDBImage.Destroy;
begin
FPicture.Free;
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
function TDBImage.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBImage.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;
function TDBImage.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TDBImage.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;
function TDBImage.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
procedure TDBImage.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TDBImage.GetField: TField;
begin
Result := FDataLink.Field;
end;
function TDBImage.GetPalette: HPALETTE;
begin
Result := 0;
if FPicture.Graphic is TBitmap then
Result := TBitmap(FPicture.Graphic).Palette;
end;
procedure TDBImage.SetAutoDisplay(Value: Boolean);
begin
if FAutoDisplay <> Value then
begin
FAutoDisplay := Value;
if Value then LoadPicture;
end;
end;
procedure TDBImage.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then
begin
FBorderStyle := Value;
RecreateWnd;
end;
end;
procedure TDBImage.SetCenter(Value: Boolean);
begin
if FCenter <> Value then
begin
FCenter := Value;
Invalidate;
end;
end;
procedure TDBImage.SetPicture(Value: TPicture);
begin
FPicture.Assign(Value);
end;
procedure TDBImage.SetStretch(Value: Boolean);
begin
if FStretch <> Value then
begin
FStretch := Value;
Invalidate;
end;
end;
procedure TDBImage.Paint;
var
W, H: Integer;
R: TRect;
S: string[63];
begin
with Canvas do
begin
Brush.Style := bsSolid;
Brush.Color := Color;
if FPictureLoaded then
begin
if Stretch then
if Picture.Graphic.Empty then
FillRect(ClientRect) else
StretchDraw(ClientRect, Picture.Graphic)
else
begin
SetRect(R, 0, 0, Picture.Width, Picture.Height);
if Center then OffsetRect(R, (ClientWidth - Picture.Width) div 2,
(ClientHeight - Picture.Height) div 2);
StretchDraw(R, Picture.Graphic);
ExcludeClipRect(Handle, R.Left, R.Top, R.Right, R.Bottom);
FillRect(ClientRect);
SelectClipRgn(Handle, 0);
end;
end else
begin
Font := Self.Font;
if FDataLink.Field <> nil then
S := FDataLink.Field.DisplayLabel else
S := Name;
S := '(' + S + ')';
W := TextWidth(S);
H := TextHeight(S);
R := ClientRect;
TextRect(R, (R.Right - W) div 2, (R.Bottom - H) div 2, S);
end;
if (GetParentForm(Self).ActiveControl = Self) and
not (csDesigning in ComponentState) then
begin
Brush.Color := clWindowFrame;
FrameRect(ClientRect);
end;
end;
end;
procedure TDBImage.PictureChanged(Sender: TObject);
begin
FDataLink.Modified;
FPictureLoaded := True;
Invalidate;
end;
procedure TDBImage.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBImage.LoadPicture;
begin
if not FPictureLoaded and (FDataLink.Field is TBlobField) then
Picture.Assign(FDataLink.Field);
end;
procedure TDBImage.DataChange(Sender: TObject);
begin
Picture.Graphic := nil;
FPictureLoaded := False;
if FAutoDisplay then LoadPicture;
end;
procedure TDBImage.UpdateData(Sender: TObject);
begin
if FDataLink.Field is TBlobField then
with TBlobField(FDataLink.Field) do
if Picture.Graphic is TBitmap then
Assign(Picture.Graphic)
else
Clear;
end;
procedure TDBImage.CopyToClipboard;
begin
if Picture.Graphic <> nil then Clipboard.Assign(Picture);
end;
procedure TDBImage.CutToClipboard;
begin
if Picture.Graphic <> nil then
if FDataLink.Edit then
begin
CopyToClipboard;
Picture.Graphic := nil;
end;
end;
procedure TDBImage.PasteFromClipboard;
begin
if Clipboard.HasFormat(CF_PICTURE) and FDataLink.Edit then
Picture.Assign(Clipboard);
end;
procedure TDBImage.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
if FBorderStyle = bsSingle then
Params.Style := Params.Style or WS_BORDER;
end;
procedure TDBImage.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
case Key of
VK_INSERT:
if ssShift in Shift then PasteFromClipBoard else
if ssCtrl in Shift then CopyToClipBoard;
VK_DELETE:
if ssShift in Shift then CutToClipBoard;
end;
end;
procedure TDBImage.KeyPress(var Key: Char);
var
MyForm : TForm;
begin
if Key = #13 then
begin
MYForm := GetParentForm( Self );
SendMessage(MYForm.Handle, WM_NEXTDLGCTL, 0, 0);
Key := #0;
end;
if Key <> #0 then inherited KeyPress(Key);
case Key of
^X: CutToClipBoard;
^C: CopyToClipBoard;
^V: PasteFromClipBoard;
#13: LoadPicture;
#27: FDataLink.Reset;
end;
end;
procedure TDBImage.CMEnter(var Message: TCMEnter);
begin
Invalidate; { Draw the focus marker }
inherited;
end;
procedure TDBImage.CMExit(var Message: TCMExit);
begin
Invalidate; { Erase the focus marker }
inherited;
end;
procedure TDBImage.CMTextChanged(var Message: TMessage);
begin
inherited;
if not FPictureLoaded then Invalidate;
end;
procedure TDBImage.WMLButtonDown(var Message: TWMLButtonDown);
begin
if TabStop and CanFocus then SetFocus;
inherited;
end;
procedure TDBImage.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
LoadPicture;
inherited;
end;
procedure TDBImage.WMCut(var Message: TMessage);
begin
CutToClipboard;
end;
procedure TDBImage.WMCopy(var Message: TMessage);
begin
CopyToClipboard;
end;
procedure TDBImage.WMPaste(var Message: TMessage);
begin
PasteFromClipboard;
end;
{ TDBNavigator }
const
BtnStateName: array[TNavGlyph] of PChar = ('EN', 'DI');
BtnTypeName: array[TNavigateBtn] of PChar = ('FIRST', 'PRIOR', 'NEXT',
'LAST', 'INSERT', 'DELETE', 'EDIT', 'POST', 'CANCEL', 'REFRESH');
BtnHintId: array[TNavigateBtn] of Word = (SFirstRecord, SPriorRecord,
SNextRecord, SLastRecord, SInsertRecord, SDeleteRecord, SEditRecord,
SPostEdit, SCancelEdit, SRefreshRecord);
constructor TDBNavigator.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] +
[csFramed, csOpaque];
FDataLink := TNavDataLink.Create(Self);
FVisibleButtons := [nbFirst, nbPrior, nbNext, nbLast, nbInsert,
nbDelete, nbEdit, nbPost, nbCancel, nbRefresh];
FHints := TStringList.Create;
InitButtons;
BevelOuter := bvNone;
BevelInner := bvNone;
Width := 241;
Height := 25;
ButtonWidth := 0;
FocusedButton := nbFirst;
FConfirmDelete := True;
end;
destructor TDBNavigator.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
procedure TDBNavigator.InitButtons;
var
I: TNavigateBtn;
Btn: TNavButton;
X: Integer;
ResName: array[0..40] of Char;
begin
MinBtnSize := Point(20, 18);
X := 0;
for I := Low(Buttons) to High(Buttons) do
begin
Btn := TNavButton.Create (Self);
Btn.Index := I;
Btn.Visible := I in FVisibleButtons;
Btn.Enabled := True;
Btn.SetBounds (X, 0, MinBtnSize.X, MinBtnSize.Y);
Btn.Glyph.Handle := LoadBitmap(HInstance,
StrFmt(ResName, 'dbn_%s', [BtnTypeName[I]]));
Btn.NumGlyphs := 2;
Btn.OnClick := Click;
Btn.OnMouseDown := BtnMouseDown;
Btn.Parent := Self;
Buttons[I] := Btn;
X := X + MinBtnSize.X;
end;
InitHints;
Buttons[nbPrior].NavStyle := Buttons[nbPrior].NavStyle + [nsAllowTimer];
Buttons[nbNext].NavStyle := Buttons[nbNext].NavStyle + [nsAllowTimer];
end;
procedure TDBNavigator.InitHints;
var
I: Integer;
J: TNavigateBtn;
begin
for J := Low(Buttons) to High(Buttons) do
Buttons[J].Hint := LoadStr (BtnHintId[J]);
J := Low(Buttons);
for I := 0 to (FHints.Count - 1) do
begin
if FHints.Strings[I] <> '' then Buttons[J].Hint := FHints.Strings[I];
if J = High(Buttons) then Exit;
Inc(J);
end;
end;
procedure TDBNavigator.SetHints(Value: TStrings);
begin
FHints.Assign(Value);
InitHints;
end;
procedure TDBNavigator.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then DataSource := nil;
end;
procedure TDBNavigator.SetVisible(Value: TButtonSet);
var
I: TNavigateBtn;
W, H: Integer;
begin
W := Width;
H := Height;
FVisibleButtons := Value;
for I := Low(Buttons) to High(Buttons) do
Buttons[I].Visible := I in FVisibleButtons;
AdjustSize (W, H);
if (W <> Width) or (H <> Height) then
inherited SetBounds (Left, Top, W, H);
Invalidate;
end;
procedure TDBNavigator.AdjustSize (var W: Integer; var H: Integer);
var
Count: Integer;
MinW: Integer;
I: TNavigateBtn;
LastBtn: TNavigateBtn;
Space, Temp, Remain: Integer;
X: Integer;
begin
if (csLoading in ComponentState) then Exit;
if Buttons[nbFirst] = nil then Exit;
Count := 0;
LastBtn := High(Buttons);
for I := Low(Buttons) to High(Buttons) do
begin
if Buttons[I].Visible then
begin
Inc(Count);
LastBtn := I;
end;
end;
if Count = 0 then Inc(Count);
MinW := Count * (MinBtnSize.X - 1) + 1;
if W < MinW then
W := MinW;
if H < MinBtnSize.Y then
H := MinBtnSize.Y;
ButtonWidth := ((W - 1) div Count) + 1;
Temp := Count * (ButtonWidth - 1) + 1;
if Align = alNone then
W := Temp;
X := 0;
Remain := W - Temp;
Temp := Count div 2;
for I := Low(Buttons) to High(Buttons) do
begin
if Buttons[I].Visible then
begin
Space := 0;
if Remain <> 0 then
begin
Dec (Temp, Remain);
if Temp < 0 then
begin
Inc (Temp, Count);
Space := 1;
end;
end;
Buttons[I].SetBounds (X, 0, ButtonWidth + Space, Height);
Inc (X, ButtonWidth - 1 + Space);
LastBtn := I;
end
else
Buttons[I].SetBounds (Width + 1, 0, ButtonWidth, Height);
end;
end;
procedure TDBNavigator.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
W, H: Integer;
begin
W := AWidth;
H := AHeight;
AdjustSize (W, H);
inherited SetBounds (ALeft, ATop, W, H);
end;
procedure TDBNavigator.WMSize(var Message: TWMSize);
var
W, H: Integer;
begin
inherited;
{ check for minimum size }
W := Width;
H := Height;
AdjustSize (W, H);
if (W <> Width) or (H <> Height) then
inherited SetBounds(Left, Top, W, H);
Message.Result := 0;
end;
procedure TDBNavigator.Click(Sender: TObject);
begin
BtnClick (TNavButton (Sender).Index);
end;
procedure TDBNavigator.BtnMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
OldFocus: TNavigateBtn;
Form: TForm;
begin
OldFocus := FocusedButton;
FocusedButton := TNavButton (Sender).Index;
if TabStop and (GetFocus <> Handle) and CanFocus then
begin
SetFocus;
if (GetFocus <> Handle) then
Exit;
end
else if TabStop and (GetFocus = Handle) and (OldFocus <> FocusedButton) then
begin
Buttons[OldFocus].Invalidate;
Buttons[FocusedButton].Invalidate;
end;
end;
procedure TDBNavigator.BtnClick(Index: TNavigateBtn);
begin
if (DataSource <> nil) and (DataSource.State <> dsInactive) then
begin
with DataSource.DataSet do
begin
case Index of
nbPrior: Prior;
nbNext: Next;
nbFirst: First;
nbLast: Last;
nbInsert: Insert;
nbEdit: Edit;
nbCancel: Cancel;
nbPost: Post;
nbRefresh: Refresh;
nbDelete:
begin
if not FConfirmDelete or
(MessageDlg (LoadStr(SDeleteRecordQuestion),
mtConfirmation, mbOKCancel, 0) <> idCancel) then
Delete;
end;
end;
end;
end;
if not (csDesigning in ComponentState) and Assigned(FOnNavClick) then
FOnNavClick(Self, Index);
end;
procedure TDBNavigator.WMSetFocus(var Message: TWMSetFocus);
begin
Buttons[FocusedButton].Invalidate;
end;
procedure TDBNavigator.WMKillFocus(var Message: TWMKillFocus);
begin
Buttons[FocusedButton].Invalidate;
end;
procedure TDBNavigator.KeyDown(var Key: Word; Shift: TShiftState);
var
NewFocus: TNavigateBtn;
OldFocus: TNavigateBtn;
begin
OldFocus := FocusedButton;
case Key of
VK_RIGHT:
begin
NewFocus := FocusedButton;
repeat
if NewFocus < High(Buttons) then
NewFocus := Succ(NewFocus);
until (NewFocus = High(Buttons)) or (Buttons[NewFocus].Visible);
if NewFocus <> FocusedButton then
begin
FocusedButton := NewFocus;
Buttons[OldFocus].Invalidate;
Buttons[FocusedButton].Invalidate;
end;
end;
VK_LEFT:
begin
NewFocus := FocusedButton;
repeat
if NewFocus > Low(Buttons) then
NewFocus := Pred(NewFocus);
until (NewFocus = Low(Buttons)) or (Buttons[NewFocus].Visible);
if NewFocus <> FocusedButton then
begin
FocusedButton := NewFocus;
Buttons[OldFocus].Invalidate;
Buttons[FocusedButton].Invalidate;
end;
end;
VK_SPACE:
begin
if Buttons[FocusedButton].Enabled then
Buttons[FocusedButton].Click;
end;
end;
end;
procedure TDBNavigator.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS;
end;
procedure TDBNavigator.DataChanged;
var
UpEnable, DnEnable: Boolean;
begin
UpEnable := Enabled and FDataLink.Active and not FDataLink.DataSet.BOF;
DnEnable := Enabled and FDataLink.Active and not FDataLink.DataSet.EOF;
Buttons[nbFirst].Enabled := UpEnable;
Buttons[nbPrior].Enabled := UpEnable;
Buttons[nbNext].Enabled := DnEnable;
Buttons[nbLast].Enabled := DnEnable;
Buttons[nbDelete].Enabled := Enabled and FDataLink.Active and
FDataLink.DataSet.CanModify and
not (FDataLink.DataSet.BOF and FDataLink.DataSet.EOF);
end;
procedure TDBNavigator.EditingChanged;
var
CanModify: Boolean;
begin
CanModify := Enabled and FDataLink.Active and FDataLink.DataSet.CanModify;
Buttons[nbInsert].Enabled := CanModify;
Buttons[nbEdit].Enabled := CanModify and not FDataLink.Editing;
Buttons[nbPost].Enabled := CanModify and FDataLink.Editing;
Buttons[nbCancel].Enabled := CanModify and FDataLink.Editing;
Buttons[nbRefresh].Enabled := not (FDataLink.DataSet is TQuery);
end;
procedure TDBNavigator.ActiveChanged;
var
I: TNavigateBtn;
begin
if not (Enabled and FDataLink.Active) then
for I := Low(Buttons) to High(Buttons) do
Buttons[I].Enabled := False
else
begin
DataChanged;
EditingChanged;
end;
end;
procedure TDBNavigator.CMEnabledChanged(var Message: TMessage);
begin
inherited;
if not (csLoading in ComponentState) then
ActiveChanged;
end;
procedure TDBNavigator.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
if not (csLoading in ComponentState) then
ActiveChanged;
end;
function TDBNavigator.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TDBNavigator.Loaded;
var
W, H: Integer;
begin
inherited Loaded;
W := Width;
H := Height;
AdjustSize (W, H);
if (W <> Width) or (H <> Height) then
inherited SetBounds (Left, Top, W, H);
InitHints;
ActiveChanged;
end;
{TNavButton}
destructor TNavButton.Destroy;
begin
if FRepeatTimer <> nil then
FRepeatTimer.Free;
inherited Destroy;
end;
procedure TNavButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseDown (Button, Shift, X, Y);
if nsAllowTimer in FNavStyle then
begin
if FRepeatTimer = nil then
FRepeatTimer := TTimer.Create(Self);
FRepeatTimer.OnTimer := TimerExpired;
FRepeatTimer.Interval := InitRepeatPause;
FRepeatTimer.Enabled := True;
end;
end;
procedure TNavButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseUp (Button, Shift, X, Y);
if FRepeatTimer <> nil then
FRepeatTimer.Enabled := False;
end;
procedure TNavButton.TimerExpired(Sender: TObject);
begin
FRepeatTimer.Interval := RepeatPause;
if (FState = bsDown) and MouseCapture then
begin
try
Click;
except
FRepeatTimer.Enabled := False;
raise;
end;
end;
end;
procedure TNavButton.Paint;
var
R: TRect;
begin
inherited Paint;
if (GetFocus = Parent.Handle) and
(FIndex = TDBNavigator (Parent).FocusedButton) then
begin
R := Bounds(0, 0, Width, Height);
InflateRect(R, -3, -3);
if FState = bsDown then
OffsetRect(R, 1, 1);
DrawFocusRect(Canvas.Handle, R);
end;
end;
{ TNavDataLink }
constructor TNavDataLink.Create(ANav: TDBNavigator);
begin
inherited Create;
FNavigator := ANav;
end;
destructor TNavDataLink.Destroy;
begin
FNavigator := nil;
inherited Destroy;
end;
procedure TNavDataLink.EditingChanged;
begin
if FNavigator <> nil then FNavigator.EditingChanged;
end;
procedure TNavDataLink.DataSetChanged;
begin
if FNavigator <> nil then FNavigator.DataChanged;
end;
procedure TNavDataLink.ActiveChanged;
begin
if FNavigator <> nil then FNavigator.ActiveChanged;
end;
end.