home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 September
/
Chip_2001-09_cd1.bin
/
zkuste
/
delphi
/
kolekce
/
d6
/
RX275D6.ZIP
/
Units
/
RxLookup.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-06-24
|
93KB
|
3,191 lines
{*******************************************************}
{ }
{ Delphi VCL Extensions (RX) }
{ }
{ Copyright (c) 1995,1997 Borland International }
{ Portions copyright (c) 1995, 1996 AO ROSNO }
{ Portions copyright (c) 1997, 1998 Master-Bank }
{ }
{*******************************************************}
unit RxLookup;
interface
{$I RX.INC}
uses SysUtils, Windows, DBCtrls, VDBConsts, Variants, Messages, Classes, Controls, Forms, Graphics, Menus, DB, Mask,
{$IFNDEF RX_D3} DBTables, {$ENDIF} Buttons, StdCtrls, DBUtils, ToolEdit;
const
DefFieldsDelim = ',';
type
{ TRxLookupControl }
TLookupListStyle = (lsFixed, lsDelimited);
TRxLookupControl = class;
TGetImageEvent = procedure (Sender: TObject; IsEmpty: Boolean;
var Graphic: TGraphic; var TextMargin: Integer) of object;
TDataSourceLink = class(TDataLink)
private
FDataControl: TRxLookupControl;
protected
procedure ActiveChanged; override;
procedure LayoutChanged; override;
procedure FocusControl(Field: TFieldRef); override;
procedure RecordChanged(Field: TField); override;
end;
TLookupSourceLink = class(TDataLink)
private
FDataControl: TRxLookupControl;
protected
procedure ActiveChanged; override;
procedure LayoutChanged; override;
procedure DataSetChanged; override;
end;
TRxLookupControl = class(TCustomControl)
private
FLookupSource: TDataSource;
FDataLink: TDataSourceLink;
FLookupLink: TLookupSourceLink;
FDataFieldName: string;
FLookupFieldName: string;
FLookupDisplay: string;
FDisplayIndex: Integer;
FDataField: TField;
FMasterField: TField;
FKeyField: TField;
FDisplayField: TField;
FListFields: TList;
FValue: string;
FDisplayValue: string;
FDisplayEmpty: string;
FSearchText: string;
FEmptyValue: string;
FEmptyItemColor: TColor;
FListActive: Boolean;
FPopup: Boolean;
FFocused: Boolean;
FLocate: TLocateObject;
FIndexSwitch: Boolean;
FIgnoreCase: Boolean;
FItemHeight: Integer;
FFieldsDelim: Char;
FListStyle: TLookupListStyle;
FOnChange: TNotifyEvent;
FOnGetImage: TGetImageEvent;
{$IFDEF WIN32}
FLookupMode: Boolean;
procedure CheckNotFixed;
procedure SetLookupMode(Value: Boolean);
function GetKeyValue: Variant;
procedure SetKeyValue(const Value: Variant);
{$ENDIF}
function CanModify: Boolean;
procedure CheckNotCircular;
procedure DataLinkActiveChanged;
procedure CheckDataLinkActiveChanged;
procedure DataLinkRecordChanged(Field: TField);
function GetBorderSize: Integer;
function GetField: TField;
function GetDataSource: TDataSource;
function GetLookupField: string;
function GetLookupSource: TDataSource;
function GetReadOnly: Boolean;
function GetTextHeight: Integer;
function DefaultTextHeight: Integer;
function GetItemHeight: Integer;
function LocateKey: Boolean;
function LocateDisplay: Boolean;
function ValueIsEmpty(const S: string): Boolean;
function StoreEmpty: Boolean;
procedure ProcessSearchKey(Key: Char);
procedure UpdateKeyValue;
procedure SelectKeyValue(const Value: string);
procedure SetDataFieldName(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure SetDisplayEmpty(const Value: string);
procedure SetEmptyValue(const Value: string);
procedure SetEmptyItemColor(Value: TColor);
procedure SetLookupField(const Value: string);
procedure SetValueKey(const Value: string);
procedure SetValue(const Value: string);
procedure SetDisplayValue(const Value: string);
procedure SetListStyle(Value: TLookupListStyle); virtual;
procedure SetFieldsDelim(Value: Char); virtual;
procedure SetLookupDisplay(const Value: string);
procedure SetLookupSource(Value: TDataSource);
procedure SetReadOnly(Value: Boolean);
procedure SetItemHeight(Value: Integer);
function ItemHeightStored: Boolean;
procedure DrawPicture(Canvas: TCanvas; Rect: TRect; Image: TGraphic);
procedure UpdateDisplayValue;
function EmptyRowVisible: Boolean;
procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE;
procedure WMKillFocus(var Message: TMessage); message WM_KILLFOCUS;
procedure WMSetFocus(var Message: TMessage); message WM_SETFOCUS;
protected
procedure Change; dynamic;
procedure KeyValueChanged; virtual;
procedure DisplayValueChanged; virtual;
procedure ListLinkActiveChanged; virtual;
procedure ListLinkDataChanged; virtual;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
function GetPicture(Current, Empty: Boolean; var TextMargin: Integer): TGraphic; virtual;
procedure UpdateDisplayEmpty(const Value: string); virtual;
function SearchText(var AValue: string): Boolean;
function GetWindowWidth: Integer;
property DataField: string read FDataFieldName write SetDataFieldName;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DisplayEmpty: string read FDisplayEmpty write SetDisplayEmpty;
property EmptyValue: string read FEmptyValue write SetEmptyValue stored StoreEmpty;
property EmptyItemColor: TColor read FEmptyItemColor write SetEmptyItemColor default clWindow;
property IgnoreCase: Boolean read FIgnoreCase write FIgnoreCase default True;
property IndexSwitch: Boolean read FIndexSwitch write FIndexSwitch default True;
property ItemHeight: Integer read GetItemHeight write SetItemHeight
stored ItemHeightStored;
property ListStyle: TLookupListStyle read FListStyle write SetListStyle default lsFixed;
property FieldsDelimiter: Char read FFieldsDelim write SetFieldsDelim default DefFieldsDelim;
property LookupDisplay: string read FLookupDisplay write SetLookupDisplay;
property LookupDisplayIndex: Integer read FDisplayIndex write FDisplayIndex default 0;
property LookupField: string read GetLookupField write SetLookupField;
property LookupSource: TDataSource read GetLookupSource write SetLookupSource;
property ParentColor default False;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
property TabStop default True;
property Value: string read FValue write SetValue stored False;
property DisplayValue: string read FDisplayValue write SetDisplayValue stored False;
{$IFDEF WIN32}
property KeyValue: Variant read GetKeyValue write SetKeyValue stored False;
{$ENDIF}
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnGetImage: TGetImageEvent read FOnGetImage write FOnGetImage;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ClearValue;
function Locate(const SearchField: TField; const AValue: string;
Exact: Boolean): Boolean;
procedure ResetField; virtual;
{$IFDEF RX_D4}
function ExecuteAction(Action: TBasicAction): Boolean; override;
function UpdateAction(Action: TBasicAction): Boolean; override;
function UseRightToLeftAlignment: Boolean; override;
{$ENDIF}
property Field: TField read GetField;
end;
{ TRxDBLookupList }
TRxDBLookupList = class(TRxLookupControl)
private
FRecordIndex: Integer;
FRecordCount: Integer;
FRowCount: Integer;
FBorderStyle: TBorderStyle;
FKeySelected: Boolean;
FTracking: Boolean;
FTimerActive: Boolean;
FLockPosition: Boolean;
FSelectEmpty: Boolean;
FMousePos: Integer;
function GetKeyIndex: Integer;
procedure ListDataChanged;
procedure SelectCurrent;
procedure SelectItemAt(X, Y: Integer);
procedure SetBorderStyle(Value: TBorderStyle);
procedure SetRowCount(Value: Integer);
procedure StopTimer;
procedure StopTracking;
procedure TimerScroll;
procedure UpdateScrollBar;
procedure UpdateBufferCount(Rows: Integer);
procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
procedure WMTimer(var Message: TMessage); message WM_TIMER;
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure KeyValueChanged; override;
procedure DisplayValueChanged; override;
procedure ListLinkActiveChanged; override;
procedure ListLinkDataChanged; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure Loaded; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure Paint; override;
procedure UpdateDisplayEmpty(const Value: string); override;
{$IFDEF RX_D4}
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
{$ENDIF}
public
constructor Create(AOwner: TComponent); override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
procedure DrawItemText(Canvas: TCanvas; Rect: TRect;
Selected, IsEmpty: Boolean); virtual;
property RowCount: Integer read FRowCount write SetRowCount stored False;
property DisplayValue;
property Value;
{$IFDEF WIN32}
property KeyValue;
{$ENDIF}
published
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property Align;
property Color;
property Ctl3D;
property DataField;
property DataSource;
property DisplayEmpty;
property DragCursor;
property DragMode;
property EmptyItemColor;
property EmptyValue;
property Enabled;
property FieldsDelimiter;
property Font;
property IgnoreCase;
{$IFDEF RX_D4}
property Anchors;
property BiDiMode;
property Constraints;
property DragKind;
property ParentBiDiMode;
{$ENDIF}
{$IFDEF WIN32}
{$IFNDEF VER90}
property ImeMode;
property ImeName;
{$ENDIF}
{$ENDIF}
property IndexSwitch;
property ItemHeight;
property ListStyle;
property LookupField;
property LookupDisplay;
property LookupDisplayIndex;
property LookupSource;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGetImage;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
{$IFDEF WIN32}
property OnStartDrag;
{$ENDIF}
{$IFDEF RX_D5}
property OnContextPopup;
{$ENDIF}
{$IFDEF RX_D4}
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnEndDock;
property OnStartDock;
{$ENDIF}
end;
{ TRxDBLookupCombo }
TRxPopupDataList = class(TRxDBLookupList)
private
FCombo: TRxLookupControl;
procedure WMMouseActivate(var Message: TMessage); message WM_MOUSEACTIVATE;
protected
procedure Click; override;
procedure CreateParams(var Params: TCreateParams); override;
{$IFNDEF WIN32}
procedure CreateWnd; override;
{$ENDIF}
procedure KeyPress(var Key: Char); override;
public
constructor Create(AOwner: TComponent); override;
end;
{$IFNDEF WIN32}
TDropDownAlign = (daLeft, daRight, daCenter);
{$ENDIF}
TRxDBLookupCombo = class(TRxLookupControl)
private
FDataList: TRxPopupDataList;
FButtonWidth: Integer;
FDropDownCount: Integer;
FDropDownWidth: Integer;
FDropDownAlign: TDropDownAlign;
FEscapeClear: Boolean;
FListVisible: Boolean;
FPressed: Boolean;
FTracking: Boolean;
FAlignment: TAlignment;
FSelImage: TPicture;
FSelMargin: Integer;
FDisplayValues: TStrings;
FDisplayAll: Boolean;
{$IFNDEF WIN32}
FBtnGlyph: TBitmap;
FBtnDisabled: TBitmap;
{$ENDIF}
FOnDropDown: TNotifyEvent;
FOnCloseUp: TNotifyEvent;
procedure ListMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure StopTracking;
procedure TrackButton(X, Y: Integer);
function GetMinHeight: Integer;
function GetText: string;
procedure InvalidateText;
procedure UpdateCurrentImage;
procedure PaintDisplayValues(Canvas: TCanvas; R: TRect; ALeft: Integer);
procedure SetFieldsDelim(Value: Char); override;
procedure SetListStyle(Value: TLookupListStyle); override;
function GetDisplayAll: Boolean;
procedure SetDisplayAll(Value: Boolean);
function GetDisplayValues(Index: Integer): string;
procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
{$IFDEF WIN32}
procedure CNKeyDown(var Message: TWMKeyDown); message CN_KEYDOWN;
procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
{$ENDIF}
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
{$IFDEF RX_D4}
procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED;
{$ENDIF}
protected
procedure Click; override;
procedure CreateParams(var Params: TCreateParams); override;
function GetPicture(Current, Empty: Boolean; var TextMargin: Integer): TGraphic; override;
procedure UpdateFieldText;
procedure KeyValueChanged; override;
procedure DisplayValueChanged; override;
procedure ListLinkActiveChanged; override;
procedure ListLinkDataChanged; override;
procedure Paint; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure UpdateDisplayEmpty(const Value: string); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure CloseUp(Accept: Boolean); dynamic;
procedure DropDown; virtual;
procedure ResetField; override;
property IsDropDown: Boolean read FListVisible;
property ListVisible: Boolean read FListVisible;
property Text: string read GetText;
property DisplayValue;
property DisplayValues[Index: Integer]: string read GetDisplayValues;
property Value;
{$IFDEF WIN32}
property KeyValue;
{$ENDIF}
published
property DropDownAlign: TDropDownAlign read FDropDownAlign write FDropDownAlign default daLeft;
property DropDownCount: Integer read FDropDownCount write FDropDownCount default 7;
property DropDownWidth: Integer read FDropDownWidth write FDropDownWidth default 0;
property EscapeClear: Boolean read FEscapeClear write FEscapeClear default True;
property DisplayAllFields: Boolean read GetDisplayAll write SetDisplayAll default False;
property Color;
property Ctl3D;
property DataField;
property DataSource;
property DisplayEmpty;
property DragCursor;
property DragMode;
property EmptyValue;
property EmptyItemColor;
property Enabled;
property FieldsDelimiter;
property Font;
property IgnoreCase;
{$IFDEF RX_D4}
property Anchors;
property BiDiMode;
property Constraints;
property DragKind;
property ParentBiDiMode;
{$ENDIF}
{$IFDEF WIN32}
{$IFNDEF VER90}
property ImeMode;
property ImeName;
{$ENDIF}
{$ENDIF}
property IndexSwitch;
property ItemHeight;
property ListStyle;
property LookupField;
property LookupDisplay;
property LookupDisplayIndex;
property LookupSource;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnChange;
property OnClick;
property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGetImage;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
{$IFDEF WIN32}
property OnStartDrag;
{$ENDIF}
{$IFDEF RX_D5}
property OnContextPopup;
{$ENDIF}
{$IFDEF RX_D4}
property OnEndDock;
property OnStartDock;
{$ENDIF}
end;
{ TPopupDataWindow }
TPopupDataWindow = class(TRxPopupDataList)
private
FEditor: TWinControl;
FCloseUp: TCloseUpEvent;
protected
procedure InvalidateEditor;
procedure Click; override;
procedure DisplayValueChanged; override;
function GetPicture(Current, Empty: Boolean; var TextMargin: Integer): TGraphic; override;
procedure KeyPress(var Key: Char); override;
procedure PopupMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure CloseUp(Accept: Boolean); virtual;
public
constructor Create(AOwner: TComponent); override;
procedure Hide;
procedure Show(Origin: TPoint);
property OnCloseUp: TCloseUpEvent read FCloseUp write FCloseUp;
end;
{ TRxLookupEdit }
TRxLookupEdit = class(TCustomComboEdit)
private
FChanging: Boolean;
FIgnoreChange: Boolean;
FDropDownCount: Integer;
FDropDownWidth: Integer;
FPopupOnlyLocate: Boolean;
FOnCloseUp: TNotifyEvent;
FOnDropDown: TNotifyEvent;
function GetListStyle: TLookupListStyle;
procedure SetListStyle(Value: TLookupListStyle);
function GetFieldsDelim: Char;
procedure SetFieldsDelim(Value: Char);
function GetLookupDisplay: string;
procedure SetLookupDisplay(const Value: string);
function GetDisplayIndex: Integer;
procedure SetDisplayIndex(Value: Integer);
function GetLookupField: string;
procedure SetLookupField(const Value: string);
function GetLookupSource: TDataSource;
procedure SetLookupSource(Value: TDataSource);
procedure SetDropDownCount(Value: Integer);
function GetLookupValue: string;
procedure SetLookupValue(const Value: string);
function GetOnGetImage: TGetImageEvent;
procedure SetOnGetImage(Value: TGetImageEvent);
protected
procedure Change; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
procedure ShowPopup(Origin: TPoint); override;
procedure HidePopup; override;
procedure PopupChange; override;
procedure PopupDropDown(DisableEdit: Boolean); override;
{$IFDEF WIN32}
function AcceptPopup(var Value: Variant): Boolean; override;
procedure SetPopupValue(const Value: Variant); override;
function GetPopupValue: Variant; override;
{$ELSE}
function AcceptPopup(var Value: string): Boolean; override;
procedure SetPopupValue(const Value: string); override;
function GetPopupValue: string; override;
{$ENDIF}
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property LookupValue: string read GetLookupValue write SetLookupValue;
published
property DropDownCount: Integer read FDropDownCount write SetDropDownCount default 8;
property DropDownWidth: Integer read FDropDownWidth write FDropDownWidth default 0;
property ListStyle: TLookupListStyle read GetListStyle write SetListStyle default lsFixed;
property FieldsDelimiter: Char read GetFieldsDelim write SetFieldsDelim default DefFieldsDelim;
property LookupDisplay: string read GetLookupDisplay write SetLookupDisplay;
property LookupDisplayIndex: Integer read GetDisplayIndex write SetDisplayIndex default 0;
property LookupField: string read GetLookupField write SetLookupField;
property LookupSource: TDataSource read GetLookupSource write SetLookupSource;
property PopupOnlyLocate: Boolean read FPopupOnlyLocate write FPopupOnlyLocate default True;
property Alignment;
property AutoSelect;
property BorderStyle;
property ButtonHint;
property CharCase;
property ClickKey;
property Color;
property Ctl3D;
property DirectInput;
property DragCursor;
property DragMode;
property EditMask;
property Enabled;
property Font;
property HideSelection;
{$IFDEF RX_D4}
property Anchors;
property BiDiMode;
property Constraints;
property DragKind;
property ParentBiDiMode;
{$ENDIF}
{$IFDEF WIN32}
{$IFNDEF VER90}
property ImeMode;
property ImeName;
{$ENDIF}
{$ENDIF}
property MaxLength;
property OEMConvert;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupAlign;
property PopupMenu;
property ReadOnly;
property ShowHint;
property TabOrder;
property TabStop;
property Text;
property Visible;
property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
property OnGetImage: TGetImageEvent read GetOnGetImage write SetOnGetImage;
property OnButtonClick;
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;
{$IFDEF WIN32}
property OnStartDrag;
{$ENDIF}
{$IFDEF RX_D5}
property OnContextPopup;
{$ENDIF}
{$IFDEF RX_D4}
property OnEndDock;
property OnStartDock;
{$ENDIF}
end;
implementation
uses DBConsts, Dialogs, {$IFNDEF WIN32} Str16, {$ENDIF} VCLUtils, rxStrUtils,
{$IFNDEF RX_D3} BdeUtils, {$ENDIF} MaxMin, ClipIcon;
{ TDataSourceLink }
procedure TDataSourceLink.ActiveChanged;
begin
if FDataControl <> nil then FDataControl.DataLinkActiveChanged;
end;
procedure TDataSourceLink.LayoutChanged;
begin
if FDataControl <> nil then FDataControl.CheckDataLinkActiveChanged;
end;
procedure TDataSourceLink.RecordChanged(Field: TField);
begin
if FDataControl <> nil then FDataControl.DataLinkRecordChanged(Field);
end;
procedure TDataSourceLink.FocusControl(Field: TFieldRef);
begin
if (Field^ <> nil) and (FDataControl <> nil) and
(Field^ = FDataControl.FDataField) and FDataControl.CanFocus then
begin
Field^ := nil;
FDataControl.SetFocus;
end;
end;
{ TLookupSourceLink }
procedure TLookupSourceLink.ActiveChanged;
begin
if FDataControl <> nil then FDataControl.ListLinkActiveChanged;
end;
procedure TLookupSourceLink.LayoutChanged;
begin
if FDataControl <> nil then FDataControl.ListLinkActiveChanged;
end;
procedure TLookupSourceLink.DataSetChanged;
begin
if FDataControl <> nil then FDataControl.ListLinkDataChanged;
end;
{ TRxLookupControl }
const
SearchTickCount: Longint = 0;
{$IFNDEF WIN32}
procedure GetFieldList(DataSet: TDataSet; List: TList;
const FieldNames: string);
var
Pos: Integer;
begin
Pos := 1;
while Pos <= Length(FieldNames) do
List.Add(DataSet.FieldByName(ExtractFieldName(FieldNames, Pos)));
end;
{$ENDIF}
constructor TRxLookupControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if NewStyleControls then ControlStyle := [csOpaque]
else ControlStyle := [csOpaque, csFramed];
ParentColor := False;
TabStop := True;
FFieldsDelim := DefFieldsDelim;
FLookupSource := TDataSource.Create(Self);
FDataLink := TDataSourceLink.Create;
FDataLink.FDataControl := Self;
FLookupLink := TLookupSourceLink.Create;
FLookupLink.FDataControl := Self;
FListFields := TList.Create;
FEmptyValue := EmptyStr;
FEmptyItemColor := clWindow;
FValue := FEmptyValue;
{$IFDEF RX_D3}
FLocate := CreateLocate(nil);
{$ELSE}
FLocate := TDBLocate.Create;
{$ENDIF}
FIndexSwitch := True;
FIgnoreCase := True;
end;
destructor TRxLookupControl.Destroy;
begin
FListFields.Free;
FListFields := nil;
FLookupLink.FDataControl := nil;
FLookupLink.Free;
FLookupLink := nil;
FDataLink.FDataControl := nil;
FDataLink.Free;
FDataLink := nil;
FLocate.Free;
FLocate := nil;
inherited Destroy;
end;
function TRxLookupControl.CanModify: Boolean;
begin
Result := FListActive and not ReadOnly and ((FDataLink.DataSource = nil) or
(FMasterField <> nil) and FMasterField.CanModify);
end;
procedure TRxLookupControl.Change;
begin
if Assigned(FOnChange) then FOnChange(Self);
end;
function TRxLookupControl.ValueIsEmpty(const S: string): Boolean;
begin
Result := (S = FEmptyValue);
end;
function TRxLookupControl.StoreEmpty: Boolean;
begin
Result := (FEmptyValue <> EmptyStr);
end;
{$IFDEF WIN32}
procedure TRxLookupControl.CheckNotFixed;
begin
if FLookupMode then _DBError(SPropDefByLookup);
if FDataLink.DataSourceFixed then _DBError(SDataSourceFixed);
end;
procedure TRxLookupControl.SetLookupMode(Value: Boolean);
begin
if FLookupMode <> Value then
if Value then begin
FMasterField := FDataField.DataSet.FieldByName(FDataField.KeyFields);
FLookupSource.DataSet := FDataField.LookupDataSet;
FLookupFieldName := FDataField.LookupKeyFields;
FLookupMode := True;
FLookupLink.DataSource := FLookupSource;
end else
begin
FLookupLink.DataSource := nil;
FLookupMode := False;
FLookupFieldName := '';
FLookupSource.DataSet := nil;
FMasterField := FDataField;
end;
end;
function TRxLookupControl.GetKeyValue: Variant;
begin
if ValueIsEmpty(Value) then Result := NULL
else Result := Value;
end;
procedure TRxLookupControl.SetKeyValue(const Value: Variant);
begin
Self.Value := Value;
end;
{$ENDIF}
procedure TRxLookupControl.CheckNotCircular;
begin
{
if FDataLink.Active and FDataLink.DataSet.IsLinkedTo(LookupSource) then
_DBError(SCircularDataLink);
}
if FDataLink.Active and ((DataSource = LookupSource) or
(FDataLink.DataSet = FLookupLink.DataSet)) then
_DBError(SCircularDataLink);
end;
procedure TRxLookupControl.CheckDataLinkActiveChanged;
var
TestField: TField;
begin
if FDataLink.Active and (FDataFieldName <> '') then begin
TestField := FDataLink.DataSet.FieldByName(FDataFieldName);
if Pointer(FDataField) <> Pointer(TestField) then begin
FDataField := nil;
FMasterField := nil;
CheckNotCircular;
FDataField := TestField;
FMasterField := FDataField;
DataLinkRecordChanged(nil);
end;
end;
end;
procedure TRxLookupControl.DataLinkActiveChanged;
begin
FDataField := nil;
FMasterField := nil;
if FDataLink.Active and (FDataFieldName <> '') then begin
CheckNotCircular;
FDataField := FDataLink.DataSet.FieldByName(FDataFieldName);
FMasterField := FDataField;
end;
{$IFDEF WIN32}
SetLookupMode((FDataField <> nil) and FDataField.Lookup);
{$ENDIF}
DataLinkRecordChanged(nil);
end;
procedure TRxLookupControl.DataLinkRecordChanged(Field: TField);
begin
if (Field = nil) or (Field = FMasterField) then begin
if FMasterField <> nil then begin
SetValueKey(FMasterField.AsString);
end else SetValueKey(FEmptyValue);
end;
end;
{$IFDEF RX_D4}
function TRxLookupControl.ExecuteAction(Action: TBasicAction): Boolean;
begin
Result := inherited ExecuteAction(Action) or ((FDataLink <> nil) and
FDataLink.ExecuteAction(Action));
end;
function TRxLookupControl.UpdateAction(Action: TBasicAction): Boolean;
begin
Result := inherited UpdateAction(Action) or ((FDataLink <> nil) and
FDataLink.UpdateAction(Action));
end;
function TRxLookupControl.UseRightToLeftAlignment: Boolean;
begin
Result := DBUseRightToLeftAlignment(Self, Field);
end;
{$ENDIF}
function TRxLookupControl.GetBorderSize: Integer;
var
Params: TCreateParams;
R: TRect;
begin
CreateParams(Params);
SetRect(R, 0, 0, 0, 0);
{$IFDEF WIN32}
AdjustWindowRectEx(R, Params.Style, False, Params.ExStyle);
{$ELSE}
AdjustWindowRect(R, Params.Style, False);
if (csFramed in ControlStyle) and Ctl3D and
(Params.Style and WS_BORDER <> 0) then Inc(R.Bottom, 2);
{$ENDIF}
Result := R.Bottom - R.Top;
end;
function TRxLookupControl.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
function TRxLookupControl.GetLookupField: string;
begin
{$IFDEF WIN32}
if FLookupMode then Result := '' else
{$ENDIF}
Result := FLookupFieldName;
end;
function TRxLookupControl.GetLookupSource: TDataSource;
begin
{$IFDEF WIN32}
if FLookupMode then Result := nil else
{$ENDIF}
Result := FLookupLink.DataSource;
end;
function TRxLookupControl.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
function TRxLookupControl.GetField: TField;
begin
if Assigned(FDataLink) then Result := FDataField
else Result := nil;
end;
function TRxLookupControl.DefaultTextHeight: Integer;
var
DC: HDC;
SaveFont: HFont;
Metrics: TTextMetric;
begin
DC := GetDC(0);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
Result := Metrics.tmHeight;
end;
function TRxLookupControl.GetTextHeight: Integer;
begin
Result := Max(DefaultTextHeight, FItemHeight);
end;
procedure TRxLookupControl.KeyValueChanged;
begin
end;
procedure TRxLookupControl.DisplayValueChanged;
begin
end;
procedure TRxLookupControl.ListLinkActiveChanged;
var
DataSet: TDataSet;
{$IFDEF WIN32}
ResultField: TField;
{$ENDIF}
begin
FListActive := False;
FKeyField := nil;
FDisplayField := nil;
FListFields.Clear;
if FLookupLink.Active and (FLookupFieldName <> '') then begin
CheckNotCircular;
DataSet := FLookupLink.DataSet;
FKeyField := DataSet.FieldByName(FLookupFieldName);
{$IFDEF WIN32}
DataSet.GetFieldList(FListFields, FLookupDisplay);
{$ELSE}
GetFieldList(DataSet, FListFields, FLookupDisplay);
{$ENDIF}
{$IFDEF WIN32}
if FLookupMode then begin
ResultField := DataSet.FieldByName(FDataField.LookupResultField);
if FListFields.IndexOf(ResultField) < 0 then
FListFields.Insert(0, ResultField);
FDisplayField := ResultField;
end
else begin
if FListFields.Count = 0 then FListFields.Add(FKeyField);
if (FDisplayIndex >= 0) and (FDisplayIndex < FListFields.Count) then
FDisplayField := FListFields[FDisplayIndex]
else FDisplayField := FListFields[0];
end;
{$ELSE}
if FListFields.Count = 0 then FListFields.Add(FKeyField);
if (FDisplayIndex >= 0) and (FDisplayIndex < FListFields.Count) then
FDisplayField := FListFields[FDisplayIndex]
else FDisplayField := FListFields[0];
{$ENDIF}
FListActive := True;
end;
FLocate.DataSet := FLookupLink.DataSet;
end;
procedure TRxLookupControl.ListLinkDataChanged;
begin
end;
function TRxLookupControl.LocateDisplay: Boolean;
begin
Result := False;
try
Result := Locate(FDisplayField, FDisplayValue, True);
except
end;
end;
function TRxLookupControl.LocateKey: Boolean;
begin
Result := False;
try
Result := not ValueIsEmpty(FValue) and Locate(FKeyField, FValue, True);
except
end;
end;
procedure TRxLookupControl.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then begin
if (FDataLink <> nil) and (AComponent = DataSource) then
DataSource := nil;
if (FLookupLink <> nil) and (AComponent = LookupSource) then
LookupSource := nil;
end;
end;
function TRxLookupControl.SearchText(var AValue: string): Boolean;
begin
Result := False;
if (FDisplayField <> nil) then
if (AValue <> '') and Locate(FDisplayField, AValue, False) then begin
SelectKeyValue(FKeyField.AsString);
AValue := Copy(FDisplayField.AsString, 1, Length(AValue));
Result := True;
end
else if AValue = '' then begin
FLookupLink.DataSet.First;
SelectKeyValue(FKeyField.AsString);
AValue := '';
end;
end;
procedure TRxLookupControl.ProcessSearchKey(Key: Char);
var
TickCount: Longint;
S: string;
begin
S := '';
if (FDisplayField <> nil) {and (FDisplayField.DataType = ftString)} then
case Key of
#9, #27: FSearchText := '';
Char(VK_BACK), #32..#255:
if CanModify then begin
if not FPopup then begin
TickCount := GetTickCount;
if TickCount - SearchTickCount > 2000 then FSearchText := '';
SearchTickCount := TickCount;
end;
if (Key = Char(VK_BACK)) then
S := Copy(FSearchText, 1, Length(FSearchText) - 1)
else if Length(FSearchText) < 32 then
S := FSearchText + Key;
if SearchText(S) or (S = '') then FSearchText := S;
end;
end;
end;
procedure TRxLookupControl.ResetField;
begin
if (FDataLink.DataSource = nil) or
((FDataLink.DataSource <> nil) and CanModify) then
begin
if (FDataLink.DataSource <> nil) and (FMasterField <> nil) and
FDataLink.Edit then
begin
if FEmptyValue = EmptyStr then FMasterField.Clear
else FMasterField.AsString := FEmptyValue;
end;
FValue := FEmptyValue;
FDisplayValue := EmptyStr;
inherited Text := DisplayEmpty;
Invalidate;
Click;
end;
end;
procedure TRxLookupControl.ClearValue;
begin
SetValueKey(FEmptyValue);
end;
procedure TRxLookupControl.SelectKeyValue(const Value: string);
begin
if FMasterField <> nil then begin
if CanModify and FDataLink.Edit then begin
if FDataField = FMasterField then FDataField.DataSet.Edit;
FMasterField.AsString := Value;
end
else Exit;
end
else SetValueKey(Value);
UpdateDisplayValue;
Repaint;
Click;
end;
procedure TRxLookupControl.SetDataFieldName(const Value: string);
begin
if FDataFieldName <> Value then begin
FDataFieldName := Value;
DataLinkActiveChanged;
end;
end;
procedure TRxLookupControl.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
{$IFDEF WIN32}
if Value <> nil then Value.FreeNotification(Self);
{$ENDIF}
end;
procedure TRxLookupControl.SetListStyle(Value: TLookupListStyle);
begin
if FListStyle <> Value then begin
FListStyle := Value;
Invalidate;
end;
end;
procedure TRxLookupControl.SetFieldsDelim(Value: Char);
begin
if FFieldsDelim <> Value then begin
FFieldsDelim := Value;
if ListStyle = lsDelimited then Invalidate;
end;
end;
procedure TRxLookupControl.SetLookupField(const Value: string);
begin
{$IFDEF WIN32}
CheckNotFixed;
{$ENDIF}
if FLookupFieldName <> Value then begin
FLookupFieldName := Value;
ListLinkActiveChanged;
if FListActive then DataLinkRecordChanged(nil);
end;
end;
procedure TRxLookupControl.SetDisplayEmpty(const Value: string);
begin
if FDisplayEmpty <> Value then begin
UpdateDisplayEmpty(Value);
FDisplayEmpty := Value;
if not (csReading in ComponentState) then Invalidate;
end;
end;
procedure TRxLookupControl.SetEmptyValue(const Value: string);
begin
if FEmptyValue <> Value then begin
if ValueIsEmpty(FValue) then FValue := Value;
FEmptyValue := Value;
end;
end;
procedure TRxLookupControl.SetEmptyItemColor(Value: TColor);
begin
if FEmptyItemColor <> Value then begin
FEmptyItemColor := Value;
if not (csReading in ComponentState) and (DisplayEmpty <> '') then
Invalidate;
end;
end;
procedure TRxLookupControl.UpdateDisplayEmpty(const Value: string);
begin
end;
procedure TRxLookupControl.SetDisplayValue(const Value: string);
var
S: string;
begin
if (FDisplayValue <> Value) and CanModify and (FDataLink.DataSource <> nil) and
Locate(FDisplayField, Value, True) then
begin
S := FValue;
if FDataLink.Edit then begin
if FMasterField <> nil then FMasterField.AsString := S
else FDataField.AsString := S;
end;
end
else if (FDisplayValue <> Value) then begin
FDisplayValue := Value;
DisplayValueChanged;
Change;
end;
end;
procedure TRxLookupControl.UpdateKeyValue;
begin
if FMasterField <> nil then FValue := FMasterField.AsString
else FValue := FEmptyValue;
KeyValueChanged;
end;
procedure TRxLookupControl.SetValueKey(const Value: string);
begin
if FValue <> Value then begin
FValue := Value;
KeyValueChanged;
end;
end;
procedure TRxLookupControl.SetValue(const Value: string);
begin
if (Value <> FValue) then
if CanModify and (FDataLink.DataSource <> nil) and FDataLink.Edit then
begin
if FMasterField <> nil then FMasterField.AsString := Value
else FDataField.AsString := Value;
end
else begin
SetValueKey(Value);
Change;
end;
end;
procedure TRxLookupControl.SetLookupDisplay(const Value: string);
begin
if FLookupDisplay <> Value then begin
FLookupDisplay := Value;
ListLinkActiveChanged;
if FListActive then DataLinkRecordChanged(nil);
end;
end;
procedure TRxLookupControl.SetLookupSource(Value: TDataSource);
begin
{$IFDEF WIN32}
CheckNotFixed;
{$ENDIF}
FLookupLink.DataSource := Value;
{$IFDEF WIN32}
if Value <> nil then Value.FreeNotification(Self);
{$ENDIF}
if Value <> nil then FLocate.DataSet := Value.DataSet
else FLocate.DataSet := nil;
if FListActive then DataLinkRecordChanged(nil);
end;
procedure TRxLookupControl.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
function TRxLookupControl.GetItemHeight: Integer;
begin
Result := {Max(GetTextHeight, FItemHeight);}GetTextHeight;
end;
procedure TRxLookupControl.SetItemHeight(Value: Integer);
begin
if not (csReading in ComponentState) then
FItemHeight := Max(DefaultTextHeight, Value)
else FItemHeight := Value;
Perform(CM_FONTCHANGED, 0, 0);
end;
function TRxLookupControl.ItemHeightStored: Boolean;
begin
Result := FItemHeight > DefaultTextHeight;
end;
procedure TRxLookupControl.DrawPicture(Canvas: TCanvas; Rect: TRect;
Image: TGraphic);
var
X, Y, SaveIndex: Integer;
{$IFDEF WIN32}
Ico: HIcon;
W, H: Integer;
{$ENDIF}
begin
if Image <> nil then begin
X := (Rect.Right + Rect.Left - Image.Width) div 2;
Y := (Rect.Top + Rect.Bottom - Image.Height) div 2;
SaveIndex := SaveDC(Canvas.Handle);
try
IntersectClipRect(Canvas.Handle, Rect.Left, Rect.Top, Rect.Right,
Rect.Bottom);
if Image is TBitmap then
DrawBitmapTransparent(Canvas, X, Y, TBitmap(Image),
TBitmap(Image).TransparentColor)
{$IFDEF WIN32}
else if Image is TIcon then begin
Ico := CreateRealSizeIcon(TIcon(Image));
try
GetIconSize(Ico, W, H);
DrawIconEx(Canvas.Handle, (Rect.Right + Rect.Left - W) div 2,
(Rect.Top + Rect.Bottom - H) div 2, Ico, W, H, 0, 0, DI_NORMAL);
finally
DestroyIcon(Ico);
end;
end
{$ENDIF}
else Canvas.Draw(X, Y, Image);
finally
RestoreDC(Canvas.Handle, SaveIndex);
end;
end;
end;
function TRxLookupControl.GetPicture(Current, Empty: Boolean;
var TextMargin: Integer): TGraphic;
begin
TextMargin := 0;
Result := nil;
if Assigned(FOnGetImage) then FOnGetImage(Self, Empty, Result, TextMargin);
end;
procedure TRxLookupControl.WMGetDlgCode(var Message: TMessage);
begin
Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
end;
procedure TRxLookupControl.WMKillFocus(var Message: TMessage);
begin
FFocused := False;
Invalidate;
end;
procedure TRxLookupControl.WMSetFocus(var Message: TMessage);
begin
FFocused := True;
Invalidate;
end;
function TRxLookupControl.Locate(const SearchField: TField;
const AValue: string; Exact: Boolean): Boolean;
begin
FLocate.IndexSwitch := FIndexSwitch;
Result := False;
try
if not ValueIsEmpty(AValue) and (SearchField <> nil) then begin
Result := FLocate.Locate(SearchField.FieldName, AValue, Exact,
not IgnoreCase);
if Result then begin
if SearchField = FDisplayField then FValue := FKeyField.AsString;
UpdateDisplayValue;
end;
end;
except
end;
end;
function TRxLookupControl.EmptyRowVisible: Boolean;
begin
Result := DisplayEmpty <> EmptyStr;
end;
procedure TRxLookupControl.UpdateDisplayValue;
begin
if not ValueIsEmpty(FValue) then begin
if FDisplayField <> nil then
FDisplayValue := FDisplayField.AsString
else FDisplayValue := '';
end
else FDisplayValue := '';
end;
function TRxLookupControl.GetWindowWidth: Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to FListFields.Count - 1 do
Inc(Result, TField(FListFields[I]).DisplayWidth);
Canvas.Font := Font;
Result := Min(Result * Canvas.TextWidth('M') + FListFields.Count * 4 +
GetSystemMetrics(SM_CXVSCROLL), Screen.Width);
end;
{ TRxDBLookupList }
constructor TRxDBLookupList.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 121;
Ctl3D := True;
FBorderStyle := bsSingle;
{$IFDEF WIN32}
ControlStyle := [csOpaque, csDoubleClicks];
{$ELSE}
ControlStyle := [csFramed, csOpaque, csDoubleClicks];
{$ENDIF}
RowCount := 7;
end;
procedure TRxDBLookupList.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := Style or WS_VSCROLL;
if FBorderStyle = bsSingle then
{$IFDEF WIN32}
if NewStyleControls and Ctl3D then ExStyle := ExStyle or WS_EX_CLIENTEDGE
else Style := Style or WS_BORDER;
{$ELSE}
Style := Style or WS_BORDER;
{$ENDIF}
end;
end;
procedure TRxDBLookupList.CreateWnd;
begin
inherited CreateWnd;
UpdateScrollBar;
end;
procedure TRxDBLookupList.Loaded;
begin
inherited Loaded;
Height := Height;
end;
function TRxDBLookupList.GetKeyIndex: Integer;
var
FieldValue: string;
begin
if not ValueIsEmpty(FValue) then
for Result := 0 to FRecordCount - 1 do begin
FLookupLink.ActiveRecord := Result;
FieldValue := FKeyField.AsString;
FLookupLink.ActiveRecord := FRecordIndex;
if FieldValue = FValue then Exit;
end;
Result := -1;
end;
procedure TRxDBLookupList.KeyDown(var Key: Word; Shift: TShiftState);
var
Delta, KeyIndex, EmptyRow: Integer;
begin
inherited KeyDown(Key, Shift);
FSelectEmpty := False;
EmptyRow := Ord(EmptyRowVisible);
if CanModify then begin
Delta := 0;
case Key of
VK_UP, VK_LEFT: Delta := -1;
VK_DOWN, VK_RIGHT: Delta := 1;
VK_PRIOR: Delta := 1 - (FRowCount - EmptyRow);
VK_NEXT: Delta := (FRowCount - EmptyRow) - 1;
VK_HOME: Delta := -Maxint;
VK_END: Delta := Maxint;
end;
if Delta <> 0 then begin
if ValueIsEmpty(Value) and (EmptyRow > 0) and (Delta < 0) then
FSelectEmpty := True;
FSearchText := '';
if Delta = -Maxint then FLookupLink.DataSet.First
else if Delta = Maxint then FLookupLink.DataSet.Last
else begin
KeyIndex := GetKeyIndex;
if KeyIndex >= 0 then begin
FLookupLink.DataSet.MoveBy(KeyIndex - FRecordIndex);
end
else begin
KeyValueChanged;
Delta := 0;
end;
FLookupLink.DataSet.MoveBy(Delta);
if FLookupLink.DataSet.BOF and (Delta < 0) and (EmptyRow > 0) then
FSelectEmpty := True;
end;
SelectCurrent;
end;
end;
end;
procedure TRxDBLookupList.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
ProcessSearchKey(Key);
end;
procedure TRxDBLookupList.KeyValueChanged;
begin
if FListActive and not FLockPosition then
if not LocateKey then FLookupLink.DataSet.First;
end;
procedure TRxDBLookupList.DisplayValueChanged;
begin
if FListActive and not FLockPosition then
if not LocateDisplay then FLookupLink.DataSet.First;
end;
procedure TRxDBLookupList.ListLinkActiveChanged;
begin
try
inherited ListLinkActiveChanged;
finally
if FListActive and not FLockPosition then begin
if Assigned(FMasterField) then UpdateKeyValue
else KeyValueChanged;
end
else ListDataChanged;
end;
end;
procedure TRxDBLookupList.ListDataChanged;
begin
if FListActive then begin
FRecordIndex := FLookupLink.ActiveRecord;
FRecordCount := FLookupLink.RecordCount;
FKeySelected := not ValueIsEmpty(FValue) or not FLookupLink.DataSet.BOF;
end
else begin
FRecordIndex := 0;
FRecordCount := 0;
FKeySelected := False;
end;
if HandleAllocated then begin
UpdateScrollBar;
Invalidate;
end;
end;
procedure TRxDBLookupList.ListLinkDataChanged;
begin
ListDataChanged;
end;
procedure TRxDBLookupList.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if Button = mbLeft then begin
FSearchText := '';
if not FPopup then begin
if CanFocus then SetFocus;
if not FFocused then Exit;
end;
if CanModify then
if ssDouble in Shift then begin
if FRecordIndex = Y div GetTextHeight then DblClick;
end
else begin
MouseCapture := True;
FTracking := True;
SelectItemAt(X, Y);
end;
end;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TRxDBLookupList.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
if FTracking then begin
SelectItemAt(X, Y);
FMousePos := Y;
TimerScroll;
end;
inherited MouseMove(Shift, X, Y);
end;
procedure TRxDBLookupList.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if FTracking then begin
StopTracking;
SelectItemAt(X, Y);
end;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TRxDBLookupList.DrawItemText(Canvas: TCanvas; Rect: TRect;
Selected, IsEmpty: Boolean);
var
J, W, X, ATop, TextWidth, LastFieldIndex: Integer;
S: string;
Field: TField;
R: TRect;
AAlignment: TAlignment;
begin
TextWidth := Canvas.TextWidth('M');
LastFieldIndex := FListFields.Count - 1;
R := Rect;
R.Right := R.Left;
S := '';
ATop := (R.Bottom + R.Top - Canvas.TextHeight('Xy')) div 2;
for J := 0 to LastFieldIndex do begin
Field := FListFields[J];
if FListStyle = lsFixed then begin
if J < LastFieldIndex then W := Field.DisplayWidth * TextWidth + 4
else W := ClientWidth - R.Right;
if IsEmpty then begin
if J = 0 then begin
S := DisplayEmpty;
end
else S := '';
end
else S := Field.DisplayText;
X := 2;
AAlignment := Field.Alignment;
{$IFDEF RX_D4}
if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
{$ENDIF}
case AAlignment of
taRightJustify: X := W - Canvas.TextWidth(S) - 3;
taCenter: X := (W - Canvas.TextWidth(S)) div 2;
end;
R.Left := R.Right;
R.Right := R.Right + W;
{$IFDEF RX_D4}
if SysLocale.MiddleEast and UseRightToLeftReading then
Canvas.TextFlags := Canvas.TextFlags or ETO_RTLREADING
else
Canvas.TextFlags := Canvas.TextFlags and not ETO_RTLREADING;
{$ENDIF}
Canvas.TextRect(R, R.Left + X, ATop, S);
if J < LastFieldIndex then begin
Canvas.MoveTo(R.Right, R.Top);
Canvas.LineTo(R.Right, R.Bottom);
Inc(R.Right);
if R.Right >= ClientWidth then Break;
end;
end
else {if FListStyle = lsDelimited then} if not IsEmpty then begin
S := S + Field.DisplayText;
if J < LastFieldIndex then S := S + FFieldsDelim + ' ';
end;
end;
if (FListStyle = lsDelimited) then begin
if IsEmpty then
S := DisplayEmpty;
R.Left := Rect.Left;
R.Right := Rect.Right;
{$IFDEF RX_D4}
if SysLocale.MiddleEast and UseRightToLeftReading then
Canvas.TextFlags := Canvas.TextFlags or ETO_RTLREADING
else
Canvas.TextFlags := Canvas.TextFlags and not ETO_RTLREADING;
{$ENDIF}
Canvas.TextRect(R, R.Left + 2, ATop, S);
end;
end;
procedure TRxDBLookupList.Paint;
var
I, J, TextHeight, TextMargin: Integer;
Image: TGraphic;
Bmp: TBitmap;
R, ImageRect: TRect;
Selected: Boolean;
begin
Bmp := TBitmap.Create;
try
Canvas.Font := Font;
TextHeight := GetTextHeight;
if ColorToRGB(Color) <> ColorToRGB(clBtnFace) then
Canvas.Pen.Color := clBtnFace
else Canvas.Pen.Color := clBtnShadow;
for I := 0 to FRowCount - 1 do begin
J := I - Ord(EmptyRowVisible);
Canvas.Font.Color := Font.Color;
Canvas.Brush.Color := Color;
Selected := not FKeySelected and (I = 0) and not EmptyRowVisible;
R.Top := I * TextHeight;
R.Bottom := R.Top + TextHeight;
if I < FRecordCount + Ord(EmptyRowVisible) then begin
if (I = 0) and (J = -1) then begin
if ValueIsEmpty(FValue) then begin
Canvas.Font.Color := clHighlightText;
Canvas.Brush.Color := clHighlight;
Selected := True;
end
else Canvas.Brush.Color := EmptyItemColor;
R.Left := 0; R.Right := ClientWidth;
Image := GetPicture(False, True, TextMargin);
if TextMargin > 0 then begin
with Bmp do begin
Canvas.Font := Self.Canvas.Font;
Canvas.Brush := Self.Canvas.Brush;
Canvas.Pen := Self.Canvas.Pen;
Width := WidthOf(R);
Height := HeightOf(R);
end;
ImageRect := Bounds(0, 0, TextMargin, HeightOf(R));
Bmp.Canvas.FillRect(ImageRect);
if Image <> nil then DrawPicture(Bmp.Canvas, ImageRect, Image);
DrawItemText(Bmp.Canvas, Bounds(TextMargin, 0, WidthOf(R) - TextMargin,
HeightOf(R)), Selected, True);
Canvas.Draw(R.Left, R.Top, Bmp);
end
else DrawItemText(Canvas, R, Selected, True);
end
else begin
FLookupLink.ActiveRecord := J;
if not ValueIsEmpty(FValue) and (FKeyField.AsString = FValue) then
begin
Canvas.Font.Color := clHighlightText;
Canvas.Brush.Color := clHighlight;
Selected := True;
end;
R.Left := 0; R.Right := ClientWidth;
Image := GetPicture(False, False, TextMargin);
if TextMargin > 0 then begin
with Bmp do begin
Canvas.Font := Self.Canvas.Font;
Canvas.Brush := Self.Canvas.Brush;
Canvas.Pen := Self.Canvas.Pen;
Width := WidthOf(R);
Height := HeightOf(R);
end;
ImageRect := Bounds(0, 0, TextMargin, HeightOf(R));
Bmp.Canvas.FillRect(ImageRect);
if Image <> nil then DrawPicture(Bmp.Canvas, ImageRect, Image);
DrawItemText(Bmp.Canvas, Bounds(TextMargin, 0, WidthOf(R) - TextMargin,
HeightOf(R)), Selected, False);
Canvas.Draw(R.Left, R.Top, Bmp);
end
else DrawItemText(Canvas, R, Selected, False);
end;
end;
R.Left := 0;
R.Right := ClientWidth;
if J >= FRecordCount then Canvas.FillRect(R);
if Selected and (FFocused or FPopup) then Canvas.DrawFocusRect(R);
end;
finally
Bmp.Free;
end;
if FRecordCount <> 0 then FLookupLink.ActiveRecord := FRecordIndex;
end;
procedure TRxDBLookupList.SelectCurrent;
begin
FLockPosition := True;
try
if FSelectEmpty then begin
ResetField;
end
else SelectKeyValue(FKeyField.AsString);
finally
FSelectEmpty := False;
FLockPosition := False;
end;
end;
procedure TRxDBLookupList.SelectItemAt(X, Y: Integer);
var
Delta: Integer;
begin
if Y < 0 then Y := 0;
if Y >= ClientHeight then Y := ClientHeight - 1;
Delta := Y div GetTextHeight;
if (Delta = 0) and EmptyRowVisible then begin
FSelectEmpty := True;
end
else begin
Delta := Delta - FRecordIndex;
if EmptyRowVisible then Dec(Delta);
FLookupLink.DataSet.MoveBy(Delta);
end;
SelectCurrent;
end;
procedure TRxDBLookupList.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then begin
FBorderStyle := Value;
RecreateWnd;
if not (csReading in ComponentState) then begin
Height := Height;
RowCount := RowCount;
end;
end;
end;
procedure TRxDBLookupList.UpdateDisplayEmpty(const Value: string);
begin
UpdateBufferCount(RowCount - Ord(Value <> EmptyStr));
end;
procedure TRxDBLookupList.UpdateBufferCount(Rows: Integer);
begin
if FLookupLink.BufferCount <> Rows then begin
FLookupLink.BufferCount := Rows;
ListLinkDataChanged;
end;
end;
procedure TRxDBLookupList.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
BorderSize, TextHeight, Rows: Integer;
begin
BorderSize := GetBorderSize;
TextHeight := GetTextHeight;
Rows := (AHeight - BorderSize) div TextHeight;
if Rows < 1 then Rows := 1;
FRowCount := Rows;
UpdateBufferCount(Rows - Ord(EmptyRowVisible));
if not (csReading in ComponentState) then
AHeight := Rows * TextHeight + BorderSize;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TRxDBLookupList.SetRowCount(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 50 then Value := 50;
Height := Value * GetTextHeight + GetBorderSize;
end;
procedure TRxDBLookupList.StopTimer;
begin
if FTimerActive then begin
KillTimer(Handle, 1);
FTimerActive := False;
end;
end;
procedure TRxDBLookupList.StopTracking;
begin
if FTracking then begin
StopTimer;
FTracking := False;
MouseCapture := False;
end;
end;
procedure TRxDBLookupList.TimerScroll;
var
Delta, Distance, Interval: Integer;
begin
Delta := 0;
Distance := 0;
if FMousePos < 0 then begin
Delta := -1;
Distance := -FMousePos;
end;
if FMousePos >= ClientHeight then begin
Delta := 1;
Distance := FMousePos - ClientHeight + 1;
end;
if Delta = 0 then StopTimer
else begin
FLookupLink.DataSet.MoveBy(Delta);
SelectCurrent;
Interval := 200 - Distance * 15;
if Interval < 0 then Interval := 0;
SetTimer(Handle, 1, Interval, nil);
FTimerActive := True;
end;
end;
procedure TRxDBLookupList.UpdateScrollBar;
(*
{$IFDEF RX_D3}
var
SIOld, SINew: TScrollInfo;
begin
if FLookuplink.Active and HandleAllocated then begin
with FLookuplink.DataSet do begin
SIOld.cbSize := sizeof(SIOld);
SIOld.fMask := SIF_ALL;
GetScrollInfo(Self.Handle, SB_VERT, SIOld);
SINew := SIOld;
if IsSequenced then begin
SINew.nMin := 1;
SINew.nPage := Self.FRowCount - Ord(EmptyRowVisible);
SINew.nMax := RecordCount + SINew.nPage - 1;
if State in [dsInactive, dsBrowse, dsEdit] then
SINew.nPos := RecNo;
end
else begin
SINew.nMin := 0;
SINew.nPage := 0;
if Self.FRecordCount = (FRowCount - Ord(EmptyRowVisible)) then begin
SINew.nMax := 4;
if BOF then SINew.nPos := 0
else if EOF then SINew.nPos := 4
else SINew.nPos := 2;
end
else begin
SINew.nMax := 0;
SINew.nPos := 0;
end;
end;
if (SINew.nMin <> SIOld.nMin) or (SINew.nMax <> SIOld.nMax) or
(SINew.nPage <> SIOld.nPage) or (SINew.nPos <> SIOld.nPos) then
SetScrollInfo(Self.Handle, SB_VERT, SINew, True);
end;
end
else begin
SetScrollRange(Handle, SB_VERT, 0, 0, False);
SetScrollPos(Handle, SB_VERT, 0, True);
end;
end;
{$ELSE}
*)
var
Pos, Max: Integer;
CurPos, MaxPos: Integer;
begin
if FLookupLink.Active then begin
Pos := 0;
Max := 0;
if FRecordCount = (FRowCount - Ord(EmptyRowVisible)) then begin
Max := 4;
if not FLookupLink.DataSet.BOF then
if not FLookupLink.DataSet.EOF then Pos := 2 else Pos := 4;
end;
GetScrollRange(Handle, SB_VERT, CurPos, MaxPos);
if MaxPos = 0 then MaxPos := FRecordCount;
CurPos := GetScrollPos(Handle, SB_VERT);
if Max <> MaxPos then SetScrollRange(Handle, SB_VERT, 0, Max, False);
if CurPos <> Pos then SetScrollPos(Handle, SB_VERT, Pos, True);
end
else begin
SetScrollRange(Handle, SB_VERT, 0, 0, False);
SetScrollPos(Handle, SB_VERT, 0, True);
end;
end;
procedure TRxDBLookupList.CMCtl3DChanged(var Message: TMessage);
begin
{$IFDEF WIN32}
if NewStyleControls and (FBorderStyle = bsSingle) then begin
RecreateWnd;
if not (csReading in ComponentState) then RowCount := RowCount;
end;
inherited;
{$ELSE}
inherited;
Invalidate;
if not (csReading in ComponentState) then RowCount := RowCount;
{$ENDIF}
end;
procedure TRxDBLookupList.CMFontChanged(var Message: TMessage);
begin
inherited;
if not (csReading in ComponentState) then Height := Height;
end;
procedure TRxDBLookupList.WMCancelMode(var Message: TMessage);
begin
StopTracking;
inherited;
end;
procedure TRxDBLookupList.WMTimer(var Message: TMessage);
begin
TimerScroll;
end;
procedure TRxDBLookupList.WMNCHitTest(var Msg: TWMNCHitTest);
begin
if csDesigning in ComponentState then begin
if FLookupLink.Active then DefaultHandler(Msg)
else inherited;
end
else inherited;
end;
{$IFDEF RX_D4}
function TRxDBLookupList.DoMouseWheelDown(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelDown(Shift, MousePos);
if not Result then begin
with FLookupLink.DataSet do
Result := MoveBy(FRecordCount - FRecordIndex) <> 0;
end;
end;
function TRxDBLookupList.DoMouseWheelUp(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelUp(Shift, MousePos);
if not Result then begin
with FLookupLink.DataSet do
Result := MoveBy(-FRecordIndex - 1) <> 0;
end;
end;
{$ENDIF RX_D4}
procedure TRxDBLookupList.WMVScroll(var Message: TWMVScroll);
begin
FSearchText := '';
with Message, FLookupLink.DataSet do
case ScrollCode of
SB_LINEUP: MoveBy(-FRecordIndex - 1);
SB_LINEDOWN: MoveBy(FRecordCount - FRecordIndex);
SB_PAGEUP: MoveBy(-FRecordIndex - FRecordCount + 1);
SB_PAGEDOWN: MoveBy(FRecordCount - FRecordIndex + FRecordCount - 2);
SB_THUMBPOSITION:
begin
case Pos of
0: First;
1: MoveBy(-FRecordIndex - FRecordCount + 1);
2: Exit;
3: MoveBy(FRecordCount - FRecordIndex + FRecordCount - 2);
4: Last;
end;
end;
SB_BOTTOM: Last;
SB_TOP: First;
end;
end;
{ TRxPopupDataList }
constructor TRxPopupDataList.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is TRxLookupControl then FCombo := TRxLookupControl(AOwner);
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
{$ELSE}
ControlStyle := [csOpaque];
{$ENDIF}
FPopup := True;
TabStop := False;
ParentCtl3D := False;
Ctl3D := False;
end;
procedure TRxPopupDataList.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := WS_POPUP or WS_BORDER;
{$IFDEF WIN32}
ExStyle := WS_EX_TOOLWINDOW;
{$ENDIF}
{$IFDEF RX_D4}
AddBiDiModeExStyle(ExStyle);
{$ENDIF}
WindowClass.Style := CS_SAVEBITS;
end;
end;
{$IFNDEF WIN32}
procedure TRxPopupDataList.CreateWnd;
begin
inherited CreateWnd;
if (csDesigning in ComponentState) then SetParent(nil);
end;
{$ENDIF}
procedure TRxPopupDataList.WMMouseActivate(var Message: TMessage);
begin
Message.Result := MA_NOACTIVATE;
end;
procedure TRxPopupDataList.Click;
begin
inherited Click;
if Assigned(FCombo) and TRxDBLookupCombo(FCombo).FListVisible then
TRxDBLookupCombo(FCombo).InvalidateText;
end;
procedure TRxPopupDataList.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if Assigned(FCombo) and TRxDBLookupCombo(FCombo).FListVisible then
TRxDBLookupCombo(FCombo).InvalidateText;
end;
{ TRxDBLookupCombo }
constructor TRxDBLookupCombo.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csReplicatable] - [csSetCaption];
{$ELSE}
ControlStyle := [csFramed, csOpaque];
{$ENDIF}
Width := 145;
Height := 0;
FDataList := TRxPopupDataList.Create(Self);
FDataList.Visible := False;
FDataList.Parent := Self;
FDataList.OnMouseUp := ListMouseUp;
FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
FDropDownCount := 8;
FDisplayValues := TStringList.Create;
FSelImage := TPicture.Create;
{$IFNDEF WIN32}
FBtnGlyph := TBitmap.Create;
{ Load ComboBox button glyph }
FBtnGlyph.Handle := LoadBitmap(0, PChar(32738));
FBtnDisabled := CreateDisabledBitmap(FBtnGlyph, clBlack);
{$ENDIF}
Height := {GetMinHeight}21;
FIgnoreCase := True;
FEscapeClear := True;
end;
destructor TRxDBLookupCombo.Destroy;
begin
{$IFNDEF WIN32}
FBtnDisabled.Free;
FBtnGlyph.Free;
{$ENDIF}
FSelImage.Free;
FSelImage := nil;
FDisplayValues.Free;
FDisplayValues := nil;
inherited Destroy;
end;
procedure TRxDBLookupCombo.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
{$IFDEF WIN32}
if NewStyleControls and Ctl3D then ExStyle := ExStyle or WS_EX_CLIENTEDGE
else Style := Style or WS_BORDER;
{$ELSE}
Style := Style or WS_BORDER;
{$ENDIF}
end;
procedure TRxDBLookupCombo.CloseUp(Accept: Boolean);
var
ListValue: string;
begin
if FListVisible then begin
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
ListValue := FDataList.Value;
SetWindowPos(FDataList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
FListVisible := False;
FDataList.LookupSource := nil;
Invalidate;
FSearchText := '';
FDataList.FSearchText := '';
if Accept and CanModify and (Value <> ListValue) then
SelectKeyValue(ListValue);
if CanFocus then SetFocus;
if Assigned(FOnCloseUp) then FOnCloseUp(Self);
end;
end;
procedure TRxDBLookupCombo.DropDown;
var
P: TPoint;
I, Y: Integer;
S: string;
begin
if not FListVisible and {FListActive} CanModify then begin
if Assigned(FOnDropDown) then FOnDropDown(Self);
FDataList.Color := Color;
FDataList.Font := Font;
FDataList.ItemHeight := ItemHeight;
FDataList.ReadOnly := not CanModify;
FDataList.EmptyValue := EmptyValue;
FDataList.DisplayEmpty := DisplayEmpty;
FDataList.EmptyItemColor := EmptyItemColor;
FDataList.RowCount := FDropDownCount;
FDataList.LookupField := FLookupFieldName;
FDataList.ListStyle := FListStyle;
FDataList.FieldsDelimiter := FFieldsDelim;
FDataList.IgnoreCase := FIgnoreCase;
FDataList.IndexSwitch := FIndexSwitch;
FDataList.OnGetImage := OnGetImage;
if FDisplayField <> nil then FAlignment := FDisplayField.Alignment;
S := '';
for I := 0 to FListFields.Count - 1 do
S := S + TField(FListFields[I]).FieldName + ';';
FDataList.LookupDisplay := S;
FDataList.LookupDisplayIndex := FListFields.IndexOf(FDisplayField);
{FDataList.FLockPosition := True;}
try
FDataList.LookupSource := FLookupLink.DataSource;
finally
{FDataList.FLockPosition := False;}
end;
FDataList.SetValueKey(Value);
{FDataList.KeyValueChanged;}
if FDropDownWidth > 0 then
FDataList.Width := FDropDownWidth
else if FDropDownWidth < 0 then
FDataList.Width := Max(Width, FDataList.GetWindowWidth)
else FDataList.Width := Width;
P := Parent.ClientToScreen(Point(Left, Top));
Y := P.Y + Height;
if Y + FDataList.Height > Screen.Height then
Y := P.Y - FDataList.Height;
case FDropDownAlign of
daRight: Dec(P.X, FDataList.Width - Width);
daCenter: Dec(P.X, (FDataList.Width - Width) div 2);
end;
if P.X + FDataList.Width > Screen.Width then
P.X := Screen.Width - FDataList.Width;
SetWindowPos(FDataList.Handle, HWND_TOP, Max(P.X, 0), Y, 0, 0,
SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
FListVisible := True;
InvalidateText;
Repaint;
end;
end;
function TRxDBLookupCombo.GetMinHeight: Integer;
begin
Result := DefaultTextHeight + GetBorderSize + 3;
end;
procedure TRxDBLookupCombo.UpdateFieldText;
var
I: Integer;
S: string;
begin
if FDisplayValues <> nil then FDisplayValues.Clear;
if DisplayAllFields then begin
S := '';
for I := 0 to FListFields.Count - 1 do begin
if S <> '' then S := S + FFieldsDelim + ' ';
S := S + TField(FListFields[I]).DisplayText;
if (ListStyle = lsFixed) and Assigned(FDisplayValues) then begin
with TField(FListFields[I]) do
FDisplayValues.AddObject(DisplayText,
TObject(MakeLong(DisplayWidth, Ord(Alignment))));
end;
end;
if S = '' then S := FDisplayField.DisplayText;
inherited Text := S;
end
else inherited Text := FDisplayField.DisplayText;
FAlignment := FDisplayField.Alignment;
end;
function TRxDBLookupCombo.GetDisplayValues(Index: Integer): string;
begin
if Assigned(FDisplayValues) and (FDisplayValues.Count > Index) then
Result := FDisplayValues[Index]
else
Result := FDisplayValue;
end;
function TRxDBLookupCombo.GetText: string;
begin
Result := inherited Text;
end;
procedure TRxDBLookupCombo.InvalidateText;
var
R: TRect;
begin
SetRect(R, 1, 1, ClientWidth - FButtonWidth - 1, ClientHeight - 1);
{$IFNDEF WIN32}
InflateRect(R, -1, -1);
{$ENDIF}
InvalidateRect(Self.Handle, @R, False);
UpdateWindow(Self.Handle);
end;
procedure TRxDBLookupCombo.KeyDown(var Key: Word; Shift: TShiftState);
var
Delta: Integer;
begin
if FListActive and ((Key = VK_UP) or (Key = VK_DOWN)) then
if ssAlt in Shift then begin
if FListVisible then CloseUp(True) else DropDown;
Key := 0;
end
else if (not FListVisible) and (not ReadOnly) then begin
if not LocateKey then FLookupLink.DataSet.First
else begin
if Key = VK_UP then Delta := -1 else Delta := 1;
FLookupLink.DataSet.MoveBy(Delta);
end;
SelectKeyValue(FKeyField.AsString);
Key := 0;
end;
if (Key <> 0) and FListVisible then FDataList.KeyDown(Key, Shift);
inherited KeyDown(Key, Shift);
end;
procedure TRxDBLookupCombo.KeyPress(var Key: Char);
begin
if FListVisible then begin
if Key in [#13, #27] then begin
CloseUp(Key = #13);
Key := #0;
end
else FDataList.KeyPress(Key)
end
else begin
if Key in [#32..#255] then begin
DropDown;
if FListVisible then FDataList.KeyPress(Key);
end
else if (Key = #27) and FEscapeClear and (not ValueIsEmpty(FValue)) and
CanModify then
begin
ResetField;
Key := #0;
end;
end;
inherited KeyPress(Key);
if (Key in [#13, #27]) then
GetParentForm(Self).Perform(CM_DIALOGKEY, Byte(Key), 0);
end;
procedure TRxDBLookupCombo.DisplayValueChanged;
begin
if FListActive and LocateDisplay then begin
FValue := FKeyField.AsString;
UpdateFieldText;
end
else begin
FValue := FEmptyValue;
inherited Text := DisplayEmpty;
if FDisplayValues <> nil then FDisplayValues.Clear;
FAlignment := taLeftJustify;
end;
UpdateDisplayValue;
UpdateCurrentImage;
Invalidate;
end;
procedure TRxDBLookupCombo.KeyValueChanged;
begin
{$IFDEF WIN32}
if FLookupMode then begin
if FDisplayValues <> nil then FDisplayValues.Clear;
if FDataLink.Active and (FDataField <> nil) then begin
inherited Text := FDataField.DisplayText;
FAlignment := FDataField.Alignment;
end
else inherited Text := '';
end else
{$ENDIF}
if FListActive and LocateKey then
UpdateFieldText
else if FListActive then begin
FValue := FEmptyValue;
inherited Text := DisplayEmpty;
if FDisplayValues <> nil then FDisplayValues.Clear;
FAlignment := taLeftJustify;
end
else begin
inherited Text := '';
if FDisplayValues <> nil then FDisplayValues.Clear;
end;
UpdateDisplayValue;
UpdateCurrentImage;
Invalidate;
end;
procedure TRxDBLookupCombo.SetFieldsDelim(Value: Char);
begin
if (FFieldsDelim <> Value) then begin
inherited SetFieldsDelim(Value);
if (ListStyle = lsDelimited) and DisplayAllFields and
not (csReading in ComponentState) then KeyValueChanged;
end;
end;
procedure TRxDBLookupCombo.SetListStyle(Value: TLookupListStyle);
begin
if (FListStyle <> Value) then begin
FListStyle := Value;
if DisplayAllFields and not (csReading in ComponentState) then
KeyValueChanged;
end;
end;
function TRxDBLookupCombo.GetDisplayAll: Boolean;
begin
{$IFDEF WIN32}
if FLookupMode then Result := False else
{$ENDIF}
Result := FDisplayAll;
end;
procedure TRxDBLookupCombo.SetDisplayAll(Value: Boolean);
begin
if FDisplayAll <> Value then begin
{$IFDEF WIN32}
if FLookupMode then FDisplayAll := False else
{$ENDIF}
FDisplayAll := Value;
if not (csReading in ComponentState)
{$IFDEF WIN32} and not FLookupMode {$ENDIF} then
KeyValueChanged
else Invalidate;
end;
end;
procedure TRxDBLookupCombo.ListLinkDataChanged;
begin
if FDataLink.Active and FDataLink.DataSet.IsLinkedTo(LookupSource) then
if FListActive then DataLinkRecordChanged(nil);
end;
procedure TRxDBLookupCombo.ListLinkActiveChanged;
begin
inherited ListLinkActiveChanged;
if FListActive and Assigned(FMasterField) then UpdateKeyValue
else KeyValueChanged;
end;
procedure TRxDBLookupCombo.ListMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
CloseUp(PtInRect(FDataList.ClientRect, Point(X, Y)));
end;
procedure TRxDBLookupCombo.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if Button = mbLeft then begin
if CanFocus then SetFocus;
if not FFocused then Exit;
if FListVisible then CloseUp(False)
else if {FListActive} CanModify then begin
MouseCapture := True;
FTracking := True;
TrackButton(X, Y);
DropDown;
end;
end;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TRxDBLookupCombo.MouseMove(Shift: TShiftState; X, Y: Integer);
var
ListPos: TPoint;
MousePos: TSmallPoint;
begin
if FTracking then begin
TrackButton(X, Y);
if FListVisible then begin
ListPos := FDataList.ScreenToClient(ClientToScreen(Point(X, Y)));
if PtInRect(FDataList.ClientRect, ListPos) then begin
StopTracking;
MousePos := PointToSmallPoint(ListPos);
SendMessage(FDataList.Handle, WM_LBUTTONDOWN, 0, Longint(MousePos));
Exit;
end;
end;
end;
inherited MouseMove(Shift, X, Y);
end;
procedure TRxDBLookupCombo.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
StopTracking;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TRxDBLookupCombo.UpdateCurrentImage;
begin
FSelImage.Assign(nil);
FSelMargin := 0;
FSelImage.Graphic := inherited GetPicture(False, ValueIsEmpty(Value),
FSelMargin);
end;
function TRxDBLookupCombo.GetPicture(Current, Empty: Boolean;
var TextMargin: Integer): TGraphic;
begin
if Current then begin
TextMargin := 0;
Result := nil;
if (FSelImage <> nil) and (FSelImage.Graphic <> nil) and
not FSelImage.Graphic.Empty then
begin
Result := FSelImage.Graphic;
TextMargin := FSelMargin;
end;
end
else Result := inherited GetPicture(Current, Empty, TextMargin);
end;
procedure TRxDBLookupCombo.PaintDisplayValues(Canvas: TCanvas; R: TRect;
ALeft: Integer);
var
I, LastIndex, TxtWidth: Integer;
X, W, ATop, ARight: Integer;
S: string;
begin
if ColorToRGB(Self.Color) <> ColorToRGB(clBtnFace) then
Canvas.Pen.Color := clBtnFace
else Canvas.Pen.Color := clBtnShadow;
LastIndex := FDisplayValues.Count - 1;
TxtWidth := Canvas.TextWidth('M');
ATop := Max(0, (HeightOf(R) - Canvas.TextHeight('Xy')) div 2);
ARight := R.Right;
Inc(R.Left, ALeft);
for I := 0 to LastIndex do begin
S := FDisplayValues[I];
W := LoWord(Longint(FDisplayValues.Objects[I]));
if I < LastIndex then W := W * TxtWidth + 4
else W := ARight - R.Left;
X := 2;
R.Right := R.Left + W;
case TAlignment(HiWord(Longint(FDisplayValues.Objects[I]))) of
taRightJustify: X := W - Canvas.TextWidth(S) - 3;
taCenter: X := (W - Canvas.TextWidth(S)) div 2;
end;
Canvas.TextRect(R, R.Left + Max(0, X), ATop, S);
Inc(R.Left, W);
if I < LastIndex then begin
Canvas.MoveTo(R.Right, R.Top);
Canvas.LineTo(R.Right, R.Bottom);
Inc(R.Left);
end;
if R.Left >= ARight then Break;
end;
end;
procedure TRxDBLookupCombo.Paint;
const
TransColor: array[Boolean] of TColor = (clBtnFace, clWhite);
var
W, X, Flags, TextMargin: Integer;
AText: string;
Selected, DrawList, IsEmpty: Boolean;
R, ImageRect: TRect;
Image: TGraphic;
Bmp: TBitmap;
Alignment: TAlignment;
{$IFNDEF WIN32}
Target: TRect;
{$ENDIF}
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
Selected := FFocused and not FListVisible {$IFDEF WIN32} and
not (csPaintCopy in ControlState) {$ENDIF};
if Selected then begin
Canvas.Font.Color := clHighlightText;
Canvas.Brush.Color := clHighlight;
end
else if not Enabled and NewStyleControls then
Canvas.Font.Color := clGrayText;
AText := inherited Text;
Alignment := FAlignment;
Image := nil;
IsEmpty := False;
DrawList := DisplayAllFields;
{$IFDEF WIN32}
if (csPaintCopy in ControlState) and (FDataField <> nil) then begin
DrawList := False;
AText := FDataField.DisplayText;
Alignment := FDataField.Alignment;
end;
{$ENDIF}
TextMargin := 0;
if FListVisible then begin
DrawList := False;
if FDataList.FSearchText <> '' then begin
AText := FDataList.FSearchText;
end
else begin
if FDataList.ValueIsEmpty(FDataList.Value) then begin
AText := DisplayEmpty;
IsEmpty := True;
Image := GetPicture(False, True, TextMargin);
end
else if (FDataList.FKeyField.AsString = FDataList.Value) then begin
AText := FDataList.FDisplayField.DisplayText;
Image := FDataList.GetPicture(False, False, TextMargin);
end
else begin
Image := GetPicture(True, False, TextMargin);
end;
end;
end
else begin
{$IFDEF WIN32}
if (csPaintCopy in ControlState) then Image := nil else
{$ENDIF}
begin
IsEmpty := ValueIsEmpty(Value);
Image := GetPicture(True, IsEmpty, TextMargin);
end;
end;
{$IFDEF RX_D4}
if UseRightToLeftAlignment then ChangeBiDiModeAlignment(Alignment);
{$ENDIF}
W := ClientWidth - FButtonWidth;
if W > 4 then begin
SetRect(R, 1, 1, W - 1, ClientHeight - 1);
{$IFNDEF WIN32}
InflateRect(R, -1, -1);
{$ENDIF}
if TextMargin > 0 then Inc(TextMargin);
X := 2 + TextMargin;
if not (FListVisible and (FDataList.FSearchText <> '')) and not DrawList then
case Alignment of
taRightJustify: X := W - Canvas.TextWidth(AText) - 6;
taCenter: X := (W + TextMargin - Canvas.TextWidth(AText)) div 2;
end;
Bmp := TBitmap.Create;
try
with Bmp.Canvas do begin
Font := Self.Canvas.Font;
Brush := Self.Canvas.Brush;
Pen := Self.Canvas.Pen;
end;
{$IFDEF RX_D4}
if (BiDiMode = bdRightToLeft) then begin
Inc(X, FButtonWidth);
Inc(R.Left, FButtonWidth);
R.Right := ClientWidth;
end;
if SysLocale.MiddleEast then begin
TControlCanvas(Self.Canvas).UpdateTextFlags;
Bmp.Canvas.TextFlags := Self.Canvas.TextFlags;
end;
{$ENDIF}
Bmp.Width := WidthOf(R);
Bmp.Height := HeightOf(R);
ImageRect := Rect(0, 0, WidthOf(R), HeightOf(R));
if DrawList and (ListStyle = lsFixed) and (FDisplayValues <> nil) and
(FDisplayValues.Count > 0) then
begin
if IsEmpty then begin
AText := DisplayEmpty;
Bmp.Canvas.TextRect(ImageRect, X, Max(0, (HeightOf(R) -
Canvas.TextHeight(AText)) div 2), AText);
end
else PaintDisplayValues(Bmp.Canvas, ImageRect, TextMargin);
end
else begin
Bmp.Canvas.TextRect(ImageRect, X, Max(0, (HeightOf(R) -
Canvas.TextHeight(AText)) div 2), AText);
end;
if Image <> nil then begin
ImageRect.Right := ImageRect.Left + TextMargin + 2;
DrawPicture(Bmp.Canvas, ImageRect, Image);
end;
Canvas.Draw(R.Left, R.Top, Bmp);
finally
Bmp.Free;
end;
if Selected then Canvas.DrawFocusRect(R);
end;
SetRect(R, W, 0, ClientWidth, ClientHeight);
{$IFDEF RX_D4}
if (BiDiMode = bdRightToLeft) then begin
R.Left := 0;
R.Right:= FButtonWidth;
end;
{$ENDIF}
{$IFDEF WIN32}
if (not FListActive) or (not Enabled) or ReadOnly then
Flags := DFCS_SCROLLCOMBOBOX or DFCS_INACTIVE
else if FPressed then
Flags := DFCS_SCROLLCOMBOBOX or DFCS_FLAT or DFCS_PUSHED
else
Flags := DFCS_SCROLLCOMBOBOX;
DrawFrameControl(Canvas.Handle, R, DFC_SCROLL, Flags);
{$ELSE}
if NewStyleControls then begin
InflateRect(R, -1, -1); Dec(R.Left);
end
else begin
InflateRect(R, 1, 1); Inc(R.Left);
end;
R := DrawButtonFace(Canvas, R, 1, bsWin31, False, FPressed, False);
{ draw button glyph }
if (not FListActive) or (not Enabled) or ReadOnly then
Bmp := FBtnDisabled
else
Bmp := FBtnGlyph;
Target := Bounds(R.Left, R.Top, Bmp.Width, Bmp.Height);
OffsetRect(Target, ((R.Right - R.Left) div 2) - (Bmp.Width div 2),
((R.Bottom - R.Top) div 2) - (Bmp.Height div 2));
{ Canvas.Draw(Target.Left, Target.Top, Bmp); }
DrawBitmapTransparent(Canvas, Target.Left, Target.Top, Bmp,
TransColor[Bmp = FBtnGlyph]);
{$ENDIF}
end;
procedure TRxDBLookupCombo.ResetField;
begin
if FListVisible then CloseUp(False);
inherited ResetField;
UpdateCurrentImage;
Invalidate;
end;
procedure TRxDBLookupCombo.StopTracking;
begin
if FTracking then begin
TrackButton(-1, -1);
FTracking := False;
MouseCapture := False;
end;
end;
procedure TRxDBLookupCombo.TrackButton(X, Y: Integer);
var
NewState: Boolean;
begin
NewState := PtInRect(Rect(ClientWidth - FButtonWidth, 0, ClientWidth,
ClientHeight), Point(X, Y));
if FPressed <> NewState then begin
FPressed := NewState;
Repaint;
end;
end;
procedure TRxDBLookupCombo.UpdateDisplayEmpty(const Value: string);
begin
if Text = FDisplayEmpty then inherited Text := Value;
end;
procedure TRxDBLookupCombo.Click;
begin
inherited Click;
Change;
end;
procedure TRxDBLookupCombo.CMCancelMode(var Message: TCMCancelMode);
begin
if (Message.Sender <> Self) and (Message.Sender <> FDataList) then
CloseUp(False);
end;
{$IFDEF WIN32}
procedure TRxDBLookupCombo.CMCtl3DChanged(var Message: TMessage);
begin
if NewStyleControls then begin
RecreateWnd;
if not (csReading in ComponentState) and (Height < GetMinHeight) then
Height := GetMinHeight;
end;
inherited;
end;
procedure TRxDBLookupCombo.CNKeyDown(var Message: TWMKeyDown);
begin
if not (csDesigning in ComponentState) then
if (Message.CharCode in [VK_RETURN, VK_ESCAPE]) and FListVisible and
FLookupMode and FDataLink.DataSourceFixed then
begin
CloseUp(Message.CharCode = VK_RETURN);
Message.Result := 1;
Exit;
end;
inherited;
end;
{$ENDIF WIN32}
procedure TRxDBLookupCombo.CMFontChanged(var Message: TMessage);
begin
inherited;
if not (csReading in ComponentState) then
Height := Max(Height, GetMinHeight);
end;
procedure TRxDBLookupCombo.CMEnabledChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;
{$IFDEF WIN32}
procedure TRxDBLookupCombo.CMGetDataLink(var Message: TMessage);
begin
Message.Result := Integer(FDataLink);
end;
{$ENDIF}
procedure TRxDBLookupCombo.WMCancelMode(var Message: TMessage);
begin
StopTracking;
inherited;
end;
procedure TRxDBLookupCombo.WMGetDlgCode(var Message: TMessage);
begin
inherited;
Message.Result := DLGC_BUTTON or DLGC_WANTALLKEYS or DLGC_WANTARROWS
or DLGC_WANTCHARS;
end;
procedure TRxDBLookupCombo.WMKillFocus(var Message: TWMKillFocus);
begin
inherited;
CloseUp(False);
end;
procedure TRxDBLookupCombo.WMSetCursor(var Message: TWMSetCursor);
var
P: TPoint;
begin
GetCursorPos(P);
with ClientRect do
if PtInRect(Bounds(Right - FButtonWidth, Top, FButtonWidth, Bottom - Top),
ScreenToClient(P)) then
{$IFDEF WIN32}
Windows.SetCursor(LoadCursor(0, IDC_ARROW))
{$ELSE}
WinProcs.SetCursor(LoadCursor(0, IDC_ARROW))
{$ENDIF}
else inherited;
end;
procedure TRxDBLookupCombo.WMSize(var Message: TWMSize);
begin
inherited;
if not (csReading in ComponentState) and (Height < GetMinHeight) then
Height := GetMinHeight
else begin
if (csDesigning in ComponentState) then
FDataList.SetBounds(0, Height + 1, 10, 10);
end;
end;
{$IFDEF RX_D4}
procedure TRxDBLookupCombo.CMBiDiModeChanged(var Message: TMessage);
begin
inherited;
FDataList.BiDiMode := BiDiMode;
end;
{$ENDIF}
{ TPopupDataWindow }
constructor TPopupDataWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEditor := TWinControl(AOwner);
Visible := False;
Parent := FEditor;
OnMouseUp := PopupMouseUp;
end;
procedure TPopupDataWindow.InvalidateEditor;
var
R: TRect;
begin
if (FEditor is TCustomComboEdit) then begin
with TComboEdit(FEditor) do
SetRect(R, 0, 0, ClientWidth - Button.Width - 2, ClientHeight + 1);
end
else R := FEditor.ClientRect;
InvalidateRect(FEditor.Handle, @R, False);
UpdateWindow(FEditor.Handle);
end;
procedure TPopupDataWindow.Click;
begin
inherited Click;
if Value <> '' then
with TRxLookupEdit(FEditor) do begin
if not (FChanging or ReadOnly) then begin
FChanging := True;
try
Text := Self.DisplayValue;
if AutoSelect then SelectAll;
finally
FChanging := False;
end;
end;
end;
InvalidateEditor;
end;
procedure TPopupDataWindow.DisplayValueChanged;
begin
if not FLockPosition then
if FListActive then begin
if LocateDisplay then
FValue := FKeyField.AsString
else begin
FLookupLink.DataSet.First;
FValue := EmptyValue;
end;
end
else FValue := FEmptyValue;
end;
procedure TPopupDataWindow.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
InvalidateEditor;
end;
procedure TPopupDataWindow.PopupMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then CloseUp(PtInRect(Self.ClientRect, Point(X, Y)));
end;
procedure TPopupDataWindow.CloseUp(Accept: Boolean);
begin
if Assigned(FCloseUp) then FCloseUp(Self, Accept);
end;
function TPopupDataWindow.GetPicture(Current, Empty: Boolean;
var TextMargin: Integer): TGraphic;
begin
TextMargin := 0;
Result := nil;
if Assigned(FOnGetImage) then FOnGetImage(FEditor, Empty, Result, TextMargin);
end;
procedure TPopupDataWindow.Hide;
begin
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
Visible := False;
end;
procedure TPopupDataWindow.Show(Origin: TPoint);
begin
SetWindowPos(Handle, HWND_TOP, Origin.X, Origin.Y, 0, 0,
SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOSIZE);
Visible := True;
end;
{ TRxLookupEdit }
constructor TRxLookupEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDropDownCount := 8;
FPopupOnlyLocate := True;
ControlState := ControlState + [csCreating];
try
FPopup := TPopupDataWindow.Create(Self);
TPopupDataWindow(FPopup).OnCloseUp := PopupCloseUp;
GlyphKind := gkDropDown; { force update }
finally
ControlState := ControlState - [csCreating];
end;
end;
destructor TRxLookupEdit.Destroy;
begin
if FPopup <> nil then
with TPopupDataWindow(FPopup) do begin
OnCloseUp := nil;
OnGetImage := nil;
end;
FPopup.Free;
FPopup := nil;
inherited Destroy;
end;
procedure TRxLookupEdit.SetDropDownCount(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 50 then Value := 50;
FDropDownCount := Value;
end;
function TRxLookupEdit.GetListStyle: TLookupListStyle;
begin
Result := TPopupDataWindow(FPopup).ListStyle;
end;
procedure TRxLookupEdit.SetListStyle(Value: TLookupListStyle);
begin
TPopupDataWindow(FPopup).ListStyle := Value;
end;
function TRxLookupEdit.GetFieldsDelim: Char;
begin
Result := TPopupDataWindow(FPopup).FieldsDelimiter;
end;
procedure TRxLookupEdit.SetFieldsDelim(Value: Char);
begin
TPopupDataWindow(FPopup).FieldsDelimiter := Value;
end;
function TRxLookupEdit.GetLookupDisplay: string;
begin
Result := TPopupDataWindow(FPopup).LookupDisplay;
end;
procedure TRxLookupEdit.SetLookupDisplay(const Value: string);
begin
TPopupDataWindow(FPopup).LookupDisplay := Value;
end;
function TRxLookupEdit.GetDisplayIndex: Integer;
begin
Result := TPopupDataWindow(FPopup).LookupDisplayIndex;
end;
procedure TRxLookupEdit.SetDisplayIndex(Value: Integer);
begin
TPopupDataWindow(FPopup).LookupDisplayIndex := Value;
end;
function TRxLookupEdit.GetLookupField: string;
begin
Result := TPopupDataWindow(FPopup).LookupField;
end;
procedure TRxLookupEdit.SetLookupField(const Value: string);
begin
TPopupDataWindow(FPopup).LookupField := Value;
end;
function TRxLookupEdit.GetLookupSource: TDataSource;
begin
Result := TPopupDataWindow(FPopup).LookupSource;
end;
procedure TRxLookupEdit.SetLookupSource(Value: TDataSource);
begin
TPopupDataWindow(FPopup).LookupSource := Value;
end;
function TRxLookupEdit.GetOnGetImage: TGetImageEvent;
begin
Result := TPopupDataWindow(FPopup).OnGetImage;
end;
procedure TRxLookupEdit.SetOnGetImage(Value: TGetImageEvent);
begin
TPopupDataWindow(FPopup).OnGetImage := Value;
end;
function TRxLookupEdit.GetLookupValue: string;
begin
TPopupDataWindow(FPopup).DisplayValue := Text;
Result := TPopupDataWindow(FPopup).Value;
end;
procedure TRxLookupEdit.SetLookupValue(const Value: string);
begin
TPopupDataWindow(FPopup).Value := Value;
Text := TPopupDataWindow(FPopup).DisplayValue;
end;
procedure TRxLookupEdit.ShowPopup(Origin: TPoint);
begin
TPopupDataWindow(FPopup).Show(Origin);
end;
procedure TRxLookupEdit.HidePopup;
begin
TPopupDataWindow(FPopup).Hide;
end;
procedure TRxLookupEdit.PopupDropDown(DisableEdit: Boolean);
begin
if not (ReadOnly or PopupVisible) then begin
if Assigned(FOnDropDown) then FOnDropDown(Self);
with TPopupDataWindow(FPopup) do begin
Color := Self.Color;
Font := Self.Font;
if FDropDownWidth > 0 then
Width := FDropDownWidth
else if FDropDownWidth < 0 then
Width := Max(Self.Width, GetWindowWidth)
else Width := Self.Width;
ReadOnly := Self.ReadOnly;
RowCount := FDropDownCount;
end;
end;
inherited PopupDropDown(False);
end;
procedure TRxLookupEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
if (Key in [VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN]) and
PopupVisible then
begin
TPopupDataWindow(FPopup).KeyDown(Key, Shift);
Key := 0;
end;
inherited KeyDown(Key, Shift);
FIgnoreChange := (SelLength > 0) or (Key = VK_BACK);
if not (PopupVisible or ReadOnly) and (Key in [VK_UP, VK_DOWN]) and
(Shift = []) then
begin
with TPopupDataWindow(FPopup) do begin
KeyDown(Key, Shift);
if Value <> EmptyValue then Key := 0;
end;
end;
end;
procedure TRxLookupEdit.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
FIgnoreChange := (SelLength > 0) or (Key = Char(VK_BACK));
end;
procedure TRxLookupEdit.Change;
begin
if PopupOnlyLocate or PopupVisible then
inherited Change
else begin
PopupChange;
DoChange;
end;
end;
procedure TRxLookupEdit.PopupChange;
var
S: string;
Len: Integer;
begin
if FChanging or FIgnoreChange or ReadOnly then begin
FIgnoreChange := False;
Exit;
end;
FChanging := True;
try
S := Text;
if TPopupDataWindow(FPopup).SearchText(S) then begin
Len := Length(Text);
Text := TPopupDataWindow(FPopup).DisplayValue;
SelStart := Len;
SelLength := Length(Text) - Len;
end
else with TPopupDataWindow(FPopup) do Value := EmptyValue;
finally
FChanging := False;
end;
end;
{$IFDEF WIN32}
procedure TRxLookupEdit.SetPopupValue(const Value: Variant);
{$ELSE}
procedure TRxLookupEdit.SetPopupValue(const Value: string);
{$ENDIF}
begin
{$IFDEF WIN32}
if VarIsNull(Value) or VarIsEmpty(Value) then
TPopupDataWindow(FPopup).Value := TPopupDataWindow(FPopup).EmptyValue
else
{$ENDIF}
TPopupDataWindow(FPopup).DisplayValue := Value;
end;
{$IFDEF WIN32}
function TRxLookupEdit.GetPopupValue: Variant;
{$ELSE}
function TRxLookupEdit.GetPopupValue: string;
{$ENDIF}
begin
with TPopupDataWindow(FPopup) do
if Value <> EmptyValue then Result := DisplayValue
else Result := Self.Text;
end;
{$IFDEF WIN32}
function TRxLookupEdit.AcceptPopup(var Value: Variant): Boolean;
{$ELSE}
function TRxLookupEdit.AcceptPopup(var Value: string): Boolean;
{$ENDIF}
begin
Result := True;
if Assigned(FOnCloseUp) then FOnCloseUp(Self);
end;
end.