1440 lines
41 KiB
ObjectPascal
1440 lines
41 KiB
ObjectPascal
|
|
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressBars extended DB items }
|
|
{ }
|
|
{ Copyright (c) 1998-2009 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSBARS AND ALL ACCOMPANYING VCL }
|
|
{ CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{*******************************************************************}
|
|
|
|
unit dxBarExtDBItems;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Db, StdCtrls, Forms,
|
|
dxCommon, dxBar;
|
|
|
|
type
|
|
TdxBarLookupCombo = class;
|
|
TdxBarPopupLookupControl = class;
|
|
|
|
TdxBarLookupLink = class(TDataLink)
|
|
private
|
|
FBarLookupCombo: TdxBarLookupCombo;
|
|
protected
|
|
procedure ActiveChanged; override;
|
|
procedure DataSetChanged; override;
|
|
procedure LayoutChanged; override;
|
|
end;
|
|
|
|
TdxBarLookupCombo = class(TCustomdxBarCombo)
|
|
private
|
|
FAllowResizing: Boolean;
|
|
FCurKeyValue: Variant;
|
|
FListLink: TdxBarLookupLink;
|
|
FPopupList: TdxBarPopupLookupControl;
|
|
FKeyFieldName: string;
|
|
FListFieldName: string;
|
|
FListFieldIndex: Integer;
|
|
FKeyField: TField;
|
|
FListField: TField;
|
|
FListFields: TList;
|
|
FKeyValue: Variant;
|
|
FSetValue: Boolean;
|
|
FListActive: Boolean;
|
|
FColor: TColor;
|
|
FImmediateDropDown : Boolean;
|
|
FPopupWidth: Integer;
|
|
|
|
FRowCount: Integer;
|
|
|
|
FListVisible: Boolean;
|
|
FFindSelection: Boolean;
|
|
FFindStr: string;
|
|
FInFindSelection: Boolean;
|
|
|
|
FLocateEdit: TEdit;
|
|
FLocateList: TdxBarPopupLookupControl;
|
|
|
|
FOnKeyValueChange: TNotifyEvent;
|
|
|
|
FForm: TForm;
|
|
ButtonOk, ButtonCancel: TButton;
|
|
|
|
function GetListSource: TDataSource;
|
|
procedure SetKeyFieldName(const Value: string);
|
|
procedure SetKeyValue(const Value: Variant);
|
|
procedure SetListFieldIndex(Value: Integer);
|
|
procedure SetListFieldName(const Value: string);
|
|
procedure SetListSource(Value: TDataSource);
|
|
procedure SetRowCount(Value: Integer);
|
|
|
|
function GetEditHandle : Integer;
|
|
function GetEditText : String;
|
|
procedure SetEditText(AText : String);
|
|
procedure DoKeyPress(Sender: TObject; var Key: Char);
|
|
procedure DoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
|
|
procedure FormSize(Sender: TObject);
|
|
protected
|
|
procedure CloseUp; override;
|
|
procedure DoEnter; override;
|
|
procedure DropDown(X, Y: Integer); override;
|
|
function GetDropDownWindow: HWND; override;
|
|
function CheckKeyForDropDownWindow(Key: Word; Shift: TShiftState): Boolean; override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure KeyPress(var Key: Char); override;
|
|
|
|
procedure UpdateListFields;
|
|
procedure ListLinkDataChanged;
|
|
procedure KeyValueChanged;
|
|
function LocateKey: Boolean;
|
|
procedure ResetFindStr;
|
|
|
|
property EditText: string read GetEditText write SetEditText;
|
|
property ListFields: TList read FListFields;
|
|
property ListLink: TdxBarLookupLink read FListLink;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure DoClick; override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
|
|
property KeyValue: Variant read FKeyValue write SetKeyValue;
|
|
published
|
|
property AllowResizing: Boolean read FAllowResizing write FAllowResizing default True;
|
|
property Color: TColor read FColor write FColor default clWindow;
|
|
property ImmediateDropDown: Boolean read FImmediateDropDown write FImmediateDropDown default False;
|
|
property KeyField: string read FKeyFieldName write SetKeyFieldName;
|
|
property ListField: string read FListFieldName write SetListFieldName;
|
|
property ListFieldIndex: Integer read FListFieldIndex write SetListFieldIndex default 0;
|
|
property ListSource: TDataSource read GetListSource write SetListSource;
|
|
property RowCount: Integer read FRowCount write SetRowCount;
|
|
property Text stored False;
|
|
property PopupWidth: Integer read FPopupWidth write FPopupWidth default 0;
|
|
|
|
property OnKeyValueChange: TNotifyEvent read FOnKeyValueChange write FOnKeyValueChange;
|
|
end;
|
|
|
|
TdxBarLookupComboControl = class(TCustomdxBarComboControl)
|
|
protected
|
|
procedure SetFocused(Value: Boolean); override;
|
|
procedure WndProc(var Message: TMessage); override;
|
|
end;
|
|
|
|
TdxBarPopupLookupLink = class(TDataLink)
|
|
private
|
|
FBarPopupLookup: TdxBarPopupLookupControl;
|
|
protected
|
|
procedure ActiveChanged; override;
|
|
procedure DataSetChanged; override;
|
|
procedure LayoutChanged; override;
|
|
procedure DataSetScrolled(Distance: Integer); override;
|
|
end;
|
|
|
|
TdxBarPopupLookupControl = class(TCustomControl)
|
|
private
|
|
FListLink: TdxBarPopupLookupLink;
|
|
FListFieldName: string;
|
|
FListFieldIndex: Integer;
|
|
FListField: TField;
|
|
FListFields: TList;
|
|
FListActive : Boolean;
|
|
|
|
FRecordIndex: Integer;
|
|
FRecordCount: Integer;
|
|
FRowCount: Integer;
|
|
FTracking: Boolean;
|
|
FTimerActive: Boolean;
|
|
FMousePos: Integer;
|
|
FSelectedItem: string;
|
|
|
|
FHScrollWidth : Integer;
|
|
FVScrollWidth : Integer;
|
|
FCloseBtnDown : Boolean;
|
|
FCloseBtnPaint : Boolean;
|
|
FComboTop : Integer;
|
|
|
|
FCombo: TdxBarLookupCombo;
|
|
FCorner: TdxCorner;
|
|
FCloseButtonRect, FGripRect: TRect;
|
|
FCloseButtonIsTracking: Boolean;
|
|
FMouseAboveCloseButton: Boolean;
|
|
|
|
function GetListSource: TDataSource;
|
|
function GetPainter: TdxBarPainter;
|
|
procedure SetListFieldName(const Value: string);
|
|
procedure SetListSource(Value: TDataSource);
|
|
|
|
procedure SelectCurrent;
|
|
procedure SelectItemAt(X, Y: Integer);
|
|
procedure SetRowCount(Value: Integer);
|
|
procedure StopTimer;
|
|
procedure StopTracking;
|
|
procedure TimerScroll;
|
|
procedure UpdateScrollBar;
|
|
|
|
procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
|
|
procedure WMCaptureChanged(var Message: TMessage); message WM_CAPTURECHANGED;
|
|
procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
|
|
procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE;
|
|
procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
|
|
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
|
|
procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
|
|
procedure WMNCHitTest(var Message: TWMNCHITTEST); message WM_NCHITTEST;
|
|
procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
|
|
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
|
|
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
|
procedure WMTimer(var Message: TMessage); message WM_TIMER;
|
|
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
|
|
procedure WMWindowPosChanging(var Message : TWMWINDOWPOSCHANGING); message WM_WINDOWPOSCHANGING;
|
|
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
|
|
protected
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
procedure CreateWnd; override;
|
|
procedure DblClick; override;
|
|
procedure Notification(AComponent: TComponent;
|
|
Operation: TOperation); override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure ListLinkDataChanged;
|
|
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;
|
|
|
|
function GetTextHeight: Integer;
|
|
procedure UpdateListFields;
|
|
|
|
property ListField: string read FListFieldName write SetListFieldName;
|
|
property ListFieldIndex: Integer read FListFieldIndex write FListFieldIndex default 0;
|
|
property ListFields: TList read FListFields;
|
|
property ListLink: TdxBarPopupLookupLink read FListLink;
|
|
property ListSource: TDataSource read GetListSource write SetListSource;
|
|
property Painter: TdxBarPainter read GetPainter;
|
|
public
|
|
IsPopup: Boolean;
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
property ComboTop: Integer read FComboTop write FComboTop;
|
|
property RowCount: Integer read FRowCount write SetRowCount stored False;
|
|
property SelectedItem: string read FSelectedItem;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$R dxBarExtDBItems.res}
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}Variants,{$ENDIF} dxBarCommon, cxClasses, dxBarStrs, cxControls;
|
|
|
|
function VarEquals(const V1, V2: Variant): Boolean;
|
|
begin
|
|
Result := False;
|
|
try
|
|
Result := V1 = V2;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
{ TdxBarLookupLink }
|
|
|
|
procedure TdxBarLookupLink.ActiveChanged;
|
|
begin
|
|
if FBarLookupCombo <> nil then FBarLookupCombo.UpdateListFields;
|
|
end;
|
|
|
|
procedure TdxBarLookupLink.DataSetChanged;
|
|
begin
|
|
if FBarLookupCombo <> nil then FBarLookupCombo.ListLinkDataChanged;
|
|
end;
|
|
|
|
procedure TdxBarLookupLink.LayoutChanged;
|
|
begin
|
|
if FBarLookupCombo <> nil then FBarLookupCombo.UpdateListFields;
|
|
end;
|
|
|
|
{ TdxBarLookupCombo }
|
|
|
|
constructor TdxBarLookupCombo.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Glyph.LoadFromResourceName(HInstance, 'DXBARLOOKUPCOMBO');
|
|
|
|
FAllowResizing := True;
|
|
FListLink := TdxBarLookupLink.Create;
|
|
FListLink.FBarLookupCombo := Self;
|
|
FListFields := TList.Create;
|
|
FKeyValue := Null;
|
|
FRowCount := 7;
|
|
FPopupList := TdxBarPopupLookupControl.Create(nil);
|
|
FColor := clWindow;
|
|
with FPopupList do
|
|
begin
|
|
FCombo := Self;
|
|
end;
|
|
end;
|
|
|
|
destructor TdxBarLookupCombo.Destroy;
|
|
begin
|
|
FPopupList.Free;
|
|
FListFields.Free;
|
|
FListLink.FBarLookupCombo := nil;
|
|
FListLink.Free;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if Operation = opRemove then
|
|
if (FListLink <> nil) and (AComponent = ListSource) then ListSource := nil;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.CloseUp;
|
|
begin
|
|
if GetCapture = FPopupList.Handle then ReleaseCapture;
|
|
|
|
RowCount := FPopupList.RowCount;
|
|
FPopupWidth := FPopupList.Width;
|
|
FListVisible := False;
|
|
ResetFindStr;
|
|
if FKeyField = nil then
|
|
FCurKeyValue := Null
|
|
else
|
|
FCurKeyValue := FKeyField.Value;
|
|
|
|
inherited;
|
|
|
|
FPopupList.ListSource := nil;
|
|
FPopupList.Parent := nil;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.DoEnter;
|
|
begin
|
|
ResetFindStr;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.DropDown(X, Y: Integer);
|
|
var
|
|
AControlWidth: Integer;
|
|
R: TRect;
|
|
W: Integer;
|
|
begin
|
|
FSetValue := False;
|
|
|
|
with FPopupList do
|
|
begin
|
|
IsPopup := True;
|
|
Parent := CurItemLink.Control.Parent;
|
|
R := cxGetWindowRect(TdxBarLookupComboControl(CurItemLink.Control).Handle);
|
|
ComboTop := R.Top + (R.Bottom - R.Top) div 2;
|
|
InternalInitDropDownWindow(FPopupList);
|
|
if Self.Color <> clWindow then
|
|
Color := Self.Color;
|
|
|
|
if Self.ListField <> '' then
|
|
ListField := Self.ListField
|
|
else
|
|
ListField := Self.KeyField;
|
|
ListFieldIndex := Self.ListFieldIndex;
|
|
RowCount := Self.RowCount;
|
|
ListSource := Self.ListSource;
|
|
if FListLink.Active then
|
|
FRecordCount := FListLink.RecordCount;
|
|
if not FInFindSelection and not VarIsNull(FCurKeyValue) and FListLink.Active then
|
|
FListLink.DataSet.Locate(FKeyFieldName, FCurKeyValue, []);
|
|
end;
|
|
|
|
with CurItemLink.ItemRect do
|
|
W := Right - Left - TdxBarLookupComboControl(CurItemLink.Control).GetCaptionAreaWidth;
|
|
if W > FPopupWidth then
|
|
AControlWidth := W
|
|
else
|
|
AControlWidth := FPopupWidth;
|
|
|
|
SetWindowPos(FPopupList.Handle, 0, 0, 0, AControlWidth, FPopupList.Height,
|
|
SWP_NOZORDER or SWP_NOMOVE or SWP_NOACTIVATE);
|
|
FListVisible := True;
|
|
|
|
inherited DropDown(X, Y);
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.DoClick;
|
|
var
|
|
W, H, D, I, J: Integer;
|
|
begin
|
|
inherited DoClick;
|
|
if Assigned(OnClick) or ReadOnly then
|
|
Exit;
|
|
|
|
FForm := TForm.Create(nil);
|
|
with FForm do
|
|
begin
|
|
if FAllowResizing then
|
|
BorderIcons := []
|
|
else
|
|
BorderStyle := bsDialog;
|
|
Caption := cxGetResourceString(@dxSBAR_LOOKUPDIALOGCAPTION);
|
|
Font := BarManager.Font;
|
|
Position := poScreenCenter;
|
|
|
|
FLocateEdit := TEdit.Create(FForm);
|
|
with FLocateEdit do
|
|
begin
|
|
Parent := FForm;
|
|
OnKeyPress := DoKeyPress;
|
|
OnKeyDown := DoKeyDown;
|
|
end;
|
|
FLocateList := TdxBarPopupLookupControl.Create(FForm);
|
|
with FLocateList do
|
|
begin
|
|
FCombo := Self;
|
|
IsPopup := False;
|
|
Parent := FForm;
|
|
Color := clWindow;
|
|
if Self.ListField <> '' then
|
|
ListField := Self.ListField
|
|
else
|
|
ListField := Self.KeyField;
|
|
ListFieldIndex := Self.ListFieldIndex;
|
|
ListSource := Self.ListSource;
|
|
|
|
Height := 2 * 2 + Self.RowCount * GetTextHeight;
|
|
if Self.FPopupWidth = 0 then
|
|
Width := FLocateEdit.Width
|
|
else
|
|
Width := Self.FPopupWidth;
|
|
end;
|
|
ButtonOk := TButton.Create(FForm);
|
|
with ButtonOk do
|
|
begin
|
|
Caption := cxGetResourceString(@dxSBAR_LOOKUPDIALOGOK);
|
|
Default := True;
|
|
ModalResult := mrOk;
|
|
Parent := FForm;
|
|
end;
|
|
ButtonCancel := TButton.Create(FForm);
|
|
with ButtonCancel do
|
|
begin
|
|
Caption := cxGetResourceString(@dxSBAR_LOOKUPDIALOGCANCEL);
|
|
Cancel := True;
|
|
ModalResult := mrCancel;
|
|
Parent := FForm;
|
|
end;
|
|
|
|
H := MulDiv(FLocateEdit.Height, 43, 42);
|
|
W := MulDiv(H, 13, 4);
|
|
D := FLocateEdit.Height div 4;
|
|
|
|
FLocateEdit.SetBounds(D, D, FLocateList.Width, FLocateEdit.Height);
|
|
with FLocateList do
|
|
begin
|
|
Left := D;
|
|
Top := FLocateEdit.BoundsRect.Bottom + D;
|
|
end;
|
|
ButtonOk.SetBounds(FLocateList.BoundsRect.Right + D, D, W, H);
|
|
ButtonCancel.SetBounds(ButtonOk.Left, ButtonOk.BoundsRect.Bottom + D, W, H);
|
|
I := D + FLocateList.Width + D + W + D;
|
|
J := D + FLocateEdit.Height + D + FLocateList.Height + D;
|
|
if J < 3 * D + 2 * H then J := 3 * D + 2 * H;
|
|
while (ClientWidth <> I) or (ClientHeight <> J) do
|
|
begin
|
|
ClientWidth := I;
|
|
ClientHeight := J;
|
|
end;
|
|
|
|
OnResize := FormSize;
|
|
FLocateEdit.Text := Text;
|
|
LocateKey;
|
|
FListVisible := True;
|
|
if (ShowModal = mrOk) and FListActive then
|
|
begin
|
|
if FKeyField <> nil then FKeyValue := FKeyField.Value;
|
|
KeyValueChanged;
|
|
end;
|
|
RowCount := FLocateList.RowCount;
|
|
FPopupWidth := FLocateList.Width;
|
|
ResetFindStr;
|
|
FListVisible := False;
|
|
Free;
|
|
FLocateEdit := nil;
|
|
end;
|
|
end;
|
|
|
|
function TdxBarLookupCombo.GetEditHandle: Integer;
|
|
begin
|
|
if FLocateEdit = nil then
|
|
Result := TCustomdxBarComboControl(CurItemLink.Control).Handle
|
|
else
|
|
Result := FLocateEdit.Handle;
|
|
end;
|
|
|
|
function TdxBarLookupCombo.GetEditText: string;
|
|
begin
|
|
if FLocateEdit = nil then
|
|
Result := CurText
|
|
else
|
|
Result := FLocateEdit.Text;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetEditText(AText: string);
|
|
begin
|
|
if FLocateEdit = nil then
|
|
CurText := AText
|
|
else
|
|
FLocateEdit.Text := AText;
|
|
end;
|
|
|
|
function TdxBarLookupCombo.GetDropDownWindow: HWND;
|
|
begin
|
|
Result := inherited GetDropDownWindow;
|
|
if Result = 0 then Result := FPopupList.Handle;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.DoKeyPress(Sender: TObject; var Key: Char);
|
|
begin
|
|
KeyPress(Key);
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.DoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if CheckKeyForDropDownWindow(Key, Shift) then
|
|
begin
|
|
FLocateList.KeyDown(Key, Shift);
|
|
Key := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.FormSize(Sender: TObject);
|
|
var
|
|
H, W, D: Integer;
|
|
begin
|
|
H := MulDiv(FLocateEdit.Height, 43, 42);
|
|
W := MulDiv(H, 13, 4);
|
|
D := FLocateEdit.Height div 4;
|
|
|
|
FLocateEdit.SetBounds(D, D, FForm.ClientWidth - (D + D + W + D), FLocateEdit.Height);
|
|
with FLocateList do
|
|
begin
|
|
Left := D;
|
|
Top := FLocateEdit.Top + FLocateEdit.Height + D;
|
|
Width := FLocateEdit.Width;
|
|
Height := FForm.ClientHeight - D - Top;
|
|
end;
|
|
ButtonOk.SetBounds(FForm.ClientWidth - D - W, D, W, H);
|
|
ButtonCancel.SetBounds(ButtonOk.Left, ButtonOk.Top + ButtonOk.Height + D, W, H);
|
|
end;
|
|
|
|
function TdxBarLookupCombo.CheckKeyForDropDownWindow(Key: Word; Shift: TShiftState): Boolean;
|
|
begin
|
|
// if {(FCombo <> nil) and }(Key = VK_RETURN) then
|
|
if Key in [VK_RETURN, VK_TAB] then
|
|
FSetValue := True;
|
|
Result := Key in [VK_UP, VK_LEFT, VK_DOWN, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_HOME, VK_END];
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if Key = VK_ESCAPE then
|
|
ResetFindStr;
|
|
inherited KeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.KeyPress(var Key: Char);
|
|
var
|
|
lFind, ASelectedAll: Boolean;
|
|
AStartPos, AEndPos: Integer;
|
|
begin
|
|
if FListField <> nil then
|
|
try
|
|
if Key = #8 then // BkSpace
|
|
begin
|
|
SendMessage(GetEditHandle, EM_GETSEL, Longint(@AStartPos), Longint(@AEndPos));
|
|
ASelectedAll := (AEndPos - AStartPos) = Length(EditText);
|
|
if ASelectedAll then
|
|
begin
|
|
ResetFindStr;
|
|
EditText := '';
|
|
end
|
|
else
|
|
if FFindSelection then
|
|
begin
|
|
FFindStr := Copy(FFindStr, 0, Length(FFindStr)-1);
|
|
SendMessage(GetEditHandle, EM_SETSEL, Length(FFindStr), Length(EditText));
|
|
end;
|
|
end
|
|
else
|
|
if IsTextChar(Key) then
|
|
begin
|
|
FInFindSelection := True;
|
|
try
|
|
if FFindSelection then begin
|
|
FFindStr := FFindStr + Key;
|
|
end else begin
|
|
FFindSelection := true;
|
|
FFindStr := Key;
|
|
end;
|
|
lFind := False;
|
|
try
|
|
lFind := FListLink.DataSet.Locate(FListField.FieldName, FFindStr, [loCaseInsensitive, loPartialKey])
|
|
except end;
|
|
if lFind then
|
|
begin
|
|
EditText := FListField.DisplayText;
|
|
SendMessage(GetEditHandle, EM_SETSEL, Length(FFindStr), Length(EditText));
|
|
// FSetValue := True;
|
|
end
|
|
else
|
|
begin
|
|
if FFindSelection and (Length(FFindStr) > 1) then
|
|
begin
|
|
FFindStr := Copy(FFindStr, 1, Length(FFindStr)-1);
|
|
if not FListVisible then DroppedDown := True;
|
|
end
|
|
else
|
|
begin
|
|
ResetFindStr;
|
|
EditText := '';
|
|
end;
|
|
if not FListVisible then DroppedDown := True;
|
|
end;
|
|
if FImmediateDropDown and not FListVisible then
|
|
begin
|
|
DroppedDown := True;
|
|
end;
|
|
finally
|
|
FInFindSelection := False;
|
|
end;
|
|
end;
|
|
finally
|
|
Key := #0;
|
|
inherited KeyPress(Key);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.UpdateListFields;
|
|
var
|
|
DataSet: TDataSet;
|
|
begin
|
|
FKeyField := nil;
|
|
FListField := nil;
|
|
FListFields.Clear;
|
|
FListActive := False;
|
|
if FListLink.Active {and (FKeyFieldName <> '') }then
|
|
begin
|
|
DataSet := FListLink.DataSet;
|
|
FKeyField := DataSet.FindField(FKeyFieldName);
|
|
try
|
|
DataSet.GetFieldList(FListFields, FListFieldName);
|
|
except
|
|
raise;
|
|
end;
|
|
if (FListFields.Count = 0) and (FKeyField <> nil) then
|
|
FListFields.Add(FKeyField);
|
|
if FListFields.Count <> 0 then
|
|
if (0 <= FListFieldIndex) and (FListFieldIndex < FListFields.Count) then
|
|
FListField := FListFields[FListFieldIndex]
|
|
else
|
|
FListField := FListFields[0];
|
|
FListActive := FListField <> nil;
|
|
end;
|
|
if FKeyField = nil then FKeyValue := Null;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.ListLinkDataChanged;
|
|
begin
|
|
if FListActive then
|
|
begin
|
|
if not VarIsNull(FKeyValue) and VarEquals(FKeyValue, FKeyField.Value) then
|
|
Text := FListField.DisplayText;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.KeyValueChanged;
|
|
begin
|
|
if FListActive and not LocateKey then
|
|
ListLink.DataSet.First;
|
|
if (FListField <> nil) {and not VarIsNULL(FKeyValue) }then
|
|
CurText := FListField.DisplayText
|
|
else
|
|
CurText := '';
|
|
if Assigned(FOnKeyValueChange) then FOnKeyValueChange(Self);
|
|
Text := CurText;
|
|
end;
|
|
|
|
function TdxBarLookupCombo.LocateKey: Boolean;
|
|
var
|
|
KeySave: Variant;
|
|
begin
|
|
if FKeyField = nil then
|
|
Result := True
|
|
else
|
|
begin
|
|
Result := False;
|
|
try
|
|
KeySave := FKeyValue;
|
|
if not VarIsNull(FKeyValue) and FListLink.Active and
|
|
FListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then
|
|
begin
|
|
Result := True;
|
|
FKeyValue := KeySave;
|
|
end;
|
|
except
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.ResetFindStr;
|
|
begin
|
|
FFindStr := '';
|
|
FFindSelection := False;
|
|
// FSetValue := False;
|
|
end;
|
|
|
|
function TdxBarLookupCombo.GetListSource: TDataSource;
|
|
begin
|
|
Result := FListLink.DataSource;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetKeyFieldName(const Value: string);
|
|
begin
|
|
if FKeyFieldName <> Value then
|
|
begin
|
|
FKeyFieldName := Value;
|
|
UpdateListFields;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetKeyValue(const Value: Variant);
|
|
begin
|
|
if not VarEquals(FKeyValue, Value) then
|
|
begin
|
|
FKeyValue := Value;
|
|
KeyValueChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetListFieldIndex(Value: Integer);
|
|
begin
|
|
if Value < 0 then Exit;
|
|
FListFieldIndex := Value;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetListFieldName(const Value: string);
|
|
begin
|
|
if FListFieldName <> Value then
|
|
begin
|
|
FListFieldName := Value;
|
|
UpdateListFields;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetListSource(Value: TDataSource);
|
|
begin
|
|
FListLink.DataSource := Value;
|
|
if Value <> nil then Value.FreeNotification(Self);
|
|
end;
|
|
|
|
procedure TdxBarLookupCombo.SetRowCount(Value: Integer);
|
|
begin
|
|
if Value < 1 then Exit;
|
|
FRowCount := Value;
|
|
end;
|
|
|
|
{ TdxBarLookupComboControl }
|
|
|
|
procedure TdxBarLookupComboControl.SetFocused(Value: Boolean);
|
|
var
|
|
FCombo: TdxBarLookupCombo;
|
|
begin
|
|
if Focused <> Value then
|
|
begin
|
|
inherited SetFocused(Value);
|
|
FCombo := TdxBarLookupCombo(Item);
|
|
if Value then
|
|
FCombo.FCurKeyValue := FCombo.FKeyValue;
|
|
if FCombo.FListActive and FCombo.FSetValue then
|
|
if Value then
|
|
FCombo.LocateKey
|
|
else
|
|
if (Text <> '') and (FCombo.FKeyField <> nil) then
|
|
FCombo.KeyValue := FCombo.FKeyField.Value
|
|
else
|
|
FCombo.KeyValue := Null;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarLookupComboControl.WndProc(var Message: TMessage);
|
|
begin
|
|
with Message do
|
|
if (Msg = WM_KEYDOWN) and ((wParam = VK_RETURN) or (wParam = VK_TAB)) then
|
|
with TdxBarLookupCombo(Item) do
|
|
begin
|
|
if FKeyField <> nil then FKeyValue := FKeyField.Value;
|
|
KeyValueChanged;
|
|
end;
|
|
inherited WndProc(Message);
|
|
end;
|
|
|
|
{ TdxBarPopupLookupLink }
|
|
|
|
procedure TdxBarPopupLookupLink.ActiveChanged;
|
|
begin
|
|
if FBarPopupLookup <> nil then FBarPopupLookup.UpdateListFields;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupLink.DataSetChanged;
|
|
begin
|
|
if FBarPopupLookup <> nil then FBarPopupLookup.ListLinkDataChanged;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupLink.LayoutChanged;
|
|
begin
|
|
if FBarPopupLookup <> nil then FBarPopupLookup.UpdateListFields;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupLink.DataSetScrolled(Distance: Integer);
|
|
begin
|
|
if FBarPopupLookup <> nil then FBarPopupLookup.ListLinkDataChanged;
|
|
end;
|
|
|
|
{ TdxBarPopupLookupControl }
|
|
|
|
constructor TdxBarPopupLookupControl.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
ControlStyle := ControlStyle - [csCaptureMouse];
|
|
|
|
FListLink := TdxBarPopupLookupLink.Create;
|
|
FListLink.FBarPopupLookup := Self;
|
|
FListFields := TList.Create;
|
|
FRowCount := 7;
|
|
end;
|
|
|
|
destructor TdxBarPopupLookupControl.Destroy;
|
|
begin
|
|
FListFields.Free;
|
|
FListLink.FBarPopupLookup := nil;
|
|
FListLink.Free;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMCancelMode(var Message: TMessage);
|
|
begin
|
|
StopTracking;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMCaptureChanged(var Message: TMessage);
|
|
begin
|
|
inherited;
|
|
if FCloseButtonIsTracking then
|
|
begin
|
|
FCloseButtonIsTracking := False;
|
|
FMouseAboveCloseButton := False;
|
|
SendMessage(Handle, WM_NCPAINT, 0, 0);
|
|
end;
|
|
StopTracking;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMEraseBkgnd(var Message: TWmEraseBkgnd);
|
|
begin
|
|
Message.Result := 1;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMGetDlgCode(var Message: TMessage);
|
|
begin
|
|
Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
|
|
begin
|
|
inherited;
|
|
Message.MinMaxInfo^.ptMinTrackSize := Point(100, 100);
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMLButtonUp(var Message: TWMLButtonUp);
|
|
begin
|
|
inherited;
|
|
if FCloseButtonIsTracking then
|
|
begin
|
|
FCloseButtonIsTracking := False;
|
|
ReleaseCapture;
|
|
if FMouseAboveCloseButton then
|
|
FCombo.BarManager.HideAll
|
|
else
|
|
SendMessage(Handle, WM_NCPAINT, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMNCCalcSize(var Message: TWMNCCalcSize);
|
|
begin
|
|
inherited;
|
|
if IsPopup then
|
|
Painter.SysPanelCalcSize(Handle, Message.CalcSize_Params^.rgrc[0],
|
|
FCorner, FCombo, FCombo.AllowResizing);
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMNCHitTest(var Message : TWMNCHITTEST);
|
|
var
|
|
PrevMouseAboveCloseButton: Boolean;
|
|
begin
|
|
inherited;
|
|
with Message do
|
|
if PtInRect(FGripRect, SmallPointToPoint(Pos)) then
|
|
Result := GetHitTestByCorner(FCorner)
|
|
else
|
|
begin
|
|
PrevMouseAboveCloseButton := FMouseAboveCloseButton;
|
|
FMouseAboveCloseButton := (GetTopWindow(0) = Handle) and
|
|
((GetCapture = 0) or FCloseButtonIsTracking) and
|
|
PtInRect(FCloseButtonRect, SmallPointToPoint(Pos));
|
|
if FMouseAboveCloseButton then Result := HTBORDER;
|
|
if PrevMouseAboveCloseButton <> FMouseAboveCloseButton then
|
|
SendMessage(Handle, WM_NCPAINT, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMNCLButtonDown(var Message: TWMNCLButtonDown);
|
|
begin
|
|
inherited;
|
|
if FMouseAboveCloseButton then
|
|
begin
|
|
FCloseButtonIsTracking := True;
|
|
SetCapture(Handle);
|
|
SendMessage(Handle, WM_NCPAINT, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMNCPaint(var Message: TWMNCPaint);
|
|
begin
|
|
inherited;
|
|
if IsPopup then
|
|
Painter.SysPanelDraw(Handle, FCombo.AllowResizing,
|
|
FMouseAboveCloseButton, FCloseButtonIsTracking, FCloseButtonRect, FGripRect, FCorner);
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMSize(var Message: TWMSize);
|
|
var
|
|
TextHeight, Rows: Integer;
|
|
begin
|
|
inherited;
|
|
TextHeight := GetTextHeight;
|
|
Rows := Message.Height div TextHeight;
|
|
if Rows < 1 then Rows := 1;
|
|
FRowCount := Rows;
|
|
if ListLink.BufferCount <> Rows then
|
|
begin
|
|
ListLink.BufferCount := Rows;
|
|
ListLinkDataChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMTimer(var Message: TMessage);
|
|
begin
|
|
TimerScroll;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMVScroll(var Message: TWMVScroll);
|
|
var
|
|
SI: TScrollInfo;
|
|
begin
|
|
with Message, ListLink.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:
|
|
if IsSequenced then
|
|
begin
|
|
SI.cbSize := sizeof(SI);
|
|
SI.fMask := SIF_ALL;
|
|
GetScrollInfo(Self.Handle, SB_VERT, SI);
|
|
if SI.nTrackPos <= 1 then First
|
|
else if SI.nTrackPos >= RecordCount then Last
|
|
else RecNo := SI.nTrackPos;
|
|
end
|
|
else
|
|
case Pos of
|
|
0: First;
|
|
1: MoveBy(-FRecordIndex - FRecordCount + 1);
|
|
2: Exit;
|
|
3: MoveBy(FRecordCount - FRecordIndex + FRecordCount - 2);
|
|
4: Last;
|
|
end;
|
|
SB_BOTTOM: Last;
|
|
SB_TOP: First;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.WMWindowPosChanging(var Message : TWMWINDOWPOSCHANGING);
|
|
var
|
|
BorderSize, TextHeight, Rows, AHeight: Integer;
|
|
begin
|
|
if IsPopup then
|
|
begin
|
|
BorderSize := 2 + Byte(FCombo.AllowResizing) * dxDropDownNCHeight;
|
|
TextHeight := GetTextHeight;
|
|
with Message.WindowPos^ do
|
|
AHeight := cy;
|
|
Rows := (AHeight - BorderSize) div TextHeight;
|
|
if Rows < 1 then Rows := 1;
|
|
with Message.WindowPos^ do
|
|
if ComboTop < y + cy then
|
|
cy := Rows * TextHeight + BorderSize
|
|
else
|
|
if (AHeight <> 0) then begin
|
|
cy := Rows * TextHeight + BorderSize;
|
|
y := y + AHeight - cy;
|
|
end;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.CMMouseLeave(var Message: TMessage);
|
|
begin
|
|
inherited;
|
|
if FMouseAboveCloseButton then
|
|
begin
|
|
FMouseAboveCloseButton := False;
|
|
if HandleAllocated then SendMessage(Handle, WM_NCPAINT, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
with Params do
|
|
if IsPopup then
|
|
ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST
|
|
else
|
|
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.CreateWnd;
|
|
begin
|
|
inherited CreateWnd;
|
|
if IsPopup then
|
|
begin
|
|
Windows.SetParent(Handle, 0);
|
|
CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
|
|
FHScrollWidth := GetSystemMetrics(SM_CYHSCROLL);
|
|
FVScrollWidth := GetSystemMetrics(SM_CXVSCROLL);
|
|
FCloseBtnDown := False;
|
|
FCloseBtnPaint := False;
|
|
end;
|
|
UpdateScrollBar;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.DblClick;
|
|
begin
|
|
inherited;
|
|
if not IsPopup then
|
|
FCombo.FForm.ModalResult := mrOk;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if Operation = opRemove then
|
|
if (FListLink <> nil) and (AComponent = ListSource) then ListSource := nil;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.KeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
Delta: Integer;
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
if not FListActive then Exit;
|
|
Delta := 0;
|
|
case Key of
|
|
VK_UP, VK_LEFT: Delta := -1;
|
|
VK_DOWN, VK_RIGHT: Delta := 1;
|
|
VK_PRIOR: Delta := 1 - FRowCount;
|
|
VK_NEXT: Delta := FRowCount - 1;
|
|
VK_HOME: Delta := -Maxint;
|
|
VK_END: Delta := Maxint;
|
|
end;
|
|
if Delta <> 0 then
|
|
begin
|
|
if Delta = -Maxint then
|
|
ListLink.DataSet.First
|
|
else
|
|
if Delta = Maxint then
|
|
ListLink.DataSet.Last
|
|
else
|
|
ListLink.DataSet.MoveBy(Delta);
|
|
SelectCurrent;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.ListLinkDataChanged;
|
|
begin
|
|
if FListActive then
|
|
begin
|
|
FRecordIndex := ListLink.ActiveRecord;
|
|
FRecordCount := ListLink.RecordCount;
|
|
end else
|
|
begin
|
|
FRecordIndex := 0;
|
|
FRecordCount := 0;
|
|
end;
|
|
if HandleAllocated then
|
|
begin
|
|
UpdateScrollBar;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if (Button = mbLeft) and
|
|
Assigned(ListLink.DataSet) {and ListLink.DataSet.CanModify} then
|
|
if ssDouble in Shift then
|
|
if FRecordIndex = Y div GetTextHeight then
|
|
DblClick
|
|
else
|
|
else
|
|
begin
|
|
MouseCapture := True;
|
|
FTracking := True;
|
|
SelectItemAt(X, Y);
|
|
end;
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.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 TdxBarPopupLookupControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if FTracking then
|
|
begin
|
|
StopTracking;
|
|
SelectItemAt(X, Y);
|
|
if (FCombo <> nil) and ListLink.Active and IsPopup then
|
|
begin
|
|
if Y < 0 then Y := 0;
|
|
if Y >= ClientHeight then Y := ClientHeight - 1;
|
|
Y := Y div GetTextHeight;
|
|
if Y >= ListLink.RecordCount then Exit;
|
|
with FCombo do
|
|
try
|
|
if FKeyField <> nil then FKeyValue := FKeyField.Value;
|
|
KeyValueChanged;
|
|
finally
|
|
if (CurItemLink <> nil) and (CurItemLink.RealItemLink <> nil) then
|
|
CurItemLink.RealItemLink.BringToTopInRecentList(True);
|
|
try
|
|
BarManager.HideAll;
|
|
except
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.Paint;
|
|
var
|
|
I, J, W, X, TextWidth, TextHeight, LastFieldIndex, SelectedRecord: Integer;
|
|
Selected : Boolean;
|
|
S: string;
|
|
R: TRect;
|
|
Field: TField;
|
|
AAlignment: TAlignment;
|
|
begin
|
|
if not FListActive then
|
|
begin
|
|
Canvas.FillRect(ClientRect);
|
|
Exit;
|
|
end;
|
|
|
|
Canvas.Font := Font;
|
|
TextWidth := Canvas.TextWidth('0');
|
|
TextHeight := Canvas.TextHeight('0');
|
|
LastFieldIndex := ListFields.Count - 1;
|
|
if ColorToRGB(Color) <> ColorToRGB(clBtnFace) then
|
|
Canvas.Pen.Color := clBtnFace else
|
|
Canvas.Pen.Color := clBtnShadow;
|
|
SelectedRecord := ListLink.ActiveRecord;
|
|
for I := 0 to FRowCount - 1 do
|
|
begin
|
|
Canvas.Font.Color := Font.Color;
|
|
Canvas.Brush.Color := Color;
|
|
R.Top := I * TextHeight;
|
|
R.Bottom := R.Top + TextHeight;
|
|
Selected := False;
|
|
if I < FRecordCount then
|
|
begin
|
|
ListLink.ActiveRecord := I;
|
|
if (SelectedRecord = I) then
|
|
begin
|
|
Canvas.Font.Color := clHighlightText;
|
|
Canvas.Brush.Color := clHighlight;
|
|
Selected := True;
|
|
end;
|
|
R.Right := 0;
|
|
for J := 0 to LastFieldIndex do
|
|
begin
|
|
Field := ListFields[J];
|
|
if J < LastFieldIndex then
|
|
W := Field.DisplayWidth * TextWidth + 4 else
|
|
W := ClientWidth - R.Right;
|
|
S := Field.DisplayText;
|
|
X := 2;
|
|
AAlignment := Field.Alignment;
|
|
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;
|
|
Canvas.TextRect(R, R.Left + X, R.Top, 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;
|
|
end;
|
|
R.Left := 0;
|
|
R.Right := ClientWidth;
|
|
if I >= FRecordCount then Canvas.FillRect(R);
|
|
if Selected then
|
|
Canvas.DrawFocusRect(R);
|
|
end;
|
|
R.Top := R.Bottom;
|
|
R.Bottom := ClientHeight;
|
|
Canvas.Brush.Color := Color;
|
|
Canvas.FillRect(R);
|
|
if FRecordCount <> 0 then ListLink.ActiveRecord := FRecordIndex;
|
|
end;
|
|
|
|
function TdxBarPopupLookupControl.GetTextHeight: 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;
|
|
|
|
procedure TdxBarPopupLookupControl.UpdateListFields;
|
|
var
|
|
DataSet: TDataSet;
|
|
begin
|
|
FListField := nil;
|
|
FListFields.Clear;
|
|
FListActive := False;
|
|
if FListLink.Active then
|
|
begin
|
|
DataSet := FListLink.DataSet;
|
|
try
|
|
DataSet.GetFieldList(FListFields, FListFieldName);
|
|
except
|
|
raise;
|
|
end;
|
|
if (FListFieldIndex >= 0) and (FListFieldIndex < FListFields.Count) then
|
|
FListField := FListFields[FListFieldIndex]
|
|
else
|
|
if (FListFields.Count > 0) then
|
|
FListField := FListFields[0];
|
|
FListActive := FListField <> nil;
|
|
end;
|
|
end;
|
|
|
|
function TdxBarPopupLookupControl.GetListSource: TDataSource;
|
|
begin
|
|
Result := FListLink.DataSource;
|
|
end;
|
|
|
|
function TdxBarPopupLookupControl.GetPainter: TdxBarPainter;
|
|
begin
|
|
if IsPopup then
|
|
Result := FCombo.CurItemLink.Control.Painter
|
|
else
|
|
Result := FCombo.BarManager.DefaultPainter;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.SetListFieldName(const Value: string);
|
|
begin
|
|
if FListFieldName <> Value then
|
|
begin
|
|
FListFieldName := Value;
|
|
UpdateListFields;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.SetListSource(Value: TDataSource);
|
|
begin
|
|
FListLink.DataSource := Value;
|
|
if Value <> nil then Value.FreeNotification(Self);
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.SelectCurrent;
|
|
begin
|
|
if FCombo <> nil then
|
|
begin
|
|
FCombo.EditText := FListField.DisplayText;
|
|
FCombo.ResetFindStr;
|
|
SendMessage(FCombo.GetEditHandle, EM_SETSEL, 0, Length(FCombo.EditText));
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.SelectItemAt(X, Y: Integer);
|
|
var
|
|
Delta: Integer;
|
|
begin
|
|
if not FCombo.FListActive then Exit;
|
|
if Y < 0 then Y := 0;
|
|
if Y >= ClientHeight then Y := ClientHeight - 1;
|
|
Delta := Y div GetTextHeight - FRecordIndex;
|
|
ListLink.DataSet.MoveBy(Delta);
|
|
SelectCurrent;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.SetRowCount(Value: Integer);
|
|
begin
|
|
if Value < 1 then Value := 1;
|
|
if Value > 100 then Value := 100;
|
|
Height := Value * GetTextHeight + 2 +
|
|
Byte(IsPopup and FCombo.AllowResizing) * dxDropDownNCHeight;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.StopTimer;
|
|
begin
|
|
if FTimerActive then
|
|
begin
|
|
KillTimer(Handle, 1);
|
|
FTimerActive := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.StopTracking;
|
|
begin
|
|
if FTracking then
|
|
begin
|
|
StopTimer;
|
|
FTracking := False;
|
|
MouseCapture := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.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
|
|
if ListLink.DataSet.MoveBy(Delta) <> 0 then SelectCurrent;
|
|
Interval := 200 - Distance * 15;
|
|
if Interval < 0 then Interval := 0;
|
|
SetTimer(Handle, 1, Interval, nil);
|
|
FTimerActive := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxBarPopupLookupControl.UpdateScrollBar;
|
|
var
|
|
SIOld, SINew: TScrollInfo;
|
|
begin
|
|
if FListLink.Active and HandleAllocated then
|
|
with ListLink.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 := FRowCount;
|
|
SINew.nMax := Integer(DWORD(RecordCount) + SINew.nPage - 1);
|
|
if State in [dsInactive, dsBrowse, dsEdit] then
|
|
SINew.nPos := RecNo;
|
|
end
|
|
else
|
|
begin
|
|
SINew.nMin := 0;
|
|
SINew.nPage := 0;
|
|
SINew.nMax := 4;
|
|
if BOF then SINew.nPos := 0
|
|
else if EOF then SINew.nPos := 4
|
|
else SINew.nPos := 2;
|
|
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;
|
|
|
|
initialization
|
|
dxBarRegisterItem(TdxBarLookupCombo, TdxBarLookupComboControl, True);
|
|
|
|
end.
|