home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / kolekce / d456 / VOLGAPAK.ZIP / Source / VolDBEdit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-09-20  |  59.0 KB  |  1,845 lines

  1. //---------------------------------------------------------------------------
  2. //  TVolgaDBEdit - inherited from TCustomMaskEdit
  3. //  Supports styles: vdsEdit,vdsCustomDlg,vdsCombo,vdsLookup,vdsCalendar,vdsTree
  4. //  May be used as DB-aware and without setting DataField and DataSource
  5. //  Supports ENTER and cursor buttons for navigation to next and previous TVolgaDBEdit
  6. //---------------------------------------------------------------------------
  7. unit VolDBEdit;
  8.  
  9. interface
  10.  
  11. uses
  12.   Forms, Graphics, SysUtils, Windows, Messages, Classes, VolDBConst,
  13. {$IFDEF VER140} Variants, {$ENDIF}
  14.   Controls, Buttons, Mask, dbctrls, db, stdctrls, VolCalend, ComCtrls;
  15.  
  16. type
  17.  
  18.   TVolgaComboBoxStyle = (vcsDropDown, vcsDropDownList);
  19.   TVolgaDialogStyle = (vdsEdit, vdsCustomDlg, vdsCombo, vdsLookup, vdsCalendar,
  20.     vdsTree {, vdsCalculator});
  21.   //≥σΩ±≥ Ωεφ≥≡εδ  Σδ  ε≥εß≡αµσφΦ 
  22.   TGetTextEvent = function(Sender: TObject; FieldValue: string): string of object;
  23.   //≥σΩ±≥ Ωεφ≥≡εδ  Σδ  ±ε⌡≡αφσφΦ  Φτ∞σφσφΦΘ
  24.   TSetTextEvent = procedure(Sender: TObject; FieldValue: string) of object;
  25.   TCloseUpEvent = procedure(Sender: TObject; Selected: Boolean) of object;
  26.  
  27. { TVolgaListbox }
  28.  
  29. type
  30.   TVolgaListbox = class(TCustomListbox)
  31.   private
  32.     FSearchText: string;
  33.   protected
  34.     procedure CreateParams(var Params: TCreateParams); override;
  35.     procedure CreateWnd; override;
  36.     procedure KeyPress(var Key: Char); override;
  37.   public
  38.     constructor Create(AOwner: TComponent); override;
  39.   end;
  40.  
  41. { TVolgaDlgCalendar }
  42.  
  43.   TVolgaDlgCalendar = class(TVolgaCalendar)
  44.   protected
  45.     procedure CreateParams(var Params: TCreateParams); override;
  46.     procedure CreateWnd; override;
  47.   public
  48.     constructor Create(AOwner: TComponent); override;
  49.   end;
  50.  
  51. { TVolgaPopupTree }
  52.  
  53.   TVolgaPopupTree = class(TCustomTreeView)
  54.   protected
  55.     procedure CreateParams(var Params: TCreateParams); override;
  56.     procedure CreateWnd; override;
  57.     function GetFullCaption(UniqueID: string; Delimiter: char): string;
  58.     function GetFullNodeCaption(Node: TTreeNode; Delimiter: char): string;
  59.     function FindNodeByUniqueID(UniqueID: string): TTreeNode;
  60.   public
  61.     constructor Create(AOwner: TComponent); override;
  62.   end;
  63.  
  64.   TVolgaDBEdit = class;
  65.  
  66.   TVolgaComboProperties = class(TPersistent)
  67.   private
  68.     FOwner: TVolgaDBEdit;
  69.     FItems: TStrings;
  70.     FValues: TStrings;
  71.     function GetComboItems: TStrings;
  72.     function GetComboValues: TStrings;
  73.     procedure SetComboItems(const Value: TStrings);
  74.     procedure SetComboValues(const Value: TStrings);
  75.     function GetHasValues: Boolean;
  76.   public
  77.     constructor Create(AOwner: TComponent);
  78.     destructor Destroy; override;
  79.     procedure AssignList(const AList: TStrings);
  80.     property HasValues: Boolean read GetHasValues;
  81.   published
  82.     property ComboItems: TStrings read GetComboItems write SetComboItems;
  83.     property ComboValues: TStrings read GetComboValues write SetComboValues;
  84.   end;
  85.  
  86.   TVolgaLookupProperties = class(TPersistent)
  87.   private
  88.     FOwner: TVolgaDBEdit;
  89.     FListFieldIndex: Integer;
  90.     FLookupKeyField: string;
  91.     FListFieldNames: string;
  92.     FLFields: TList;
  93.     FSourceKeyField: string;
  94.     procedure SetLookupKeyField(const Value: string);
  95.     procedure SetListFieldNames(const Value: string);
  96.     function GetViewField: string;
  97.     procedure PrepareLookup;
  98.     procedure SetSourceKeyField(const Value: string);
  99.   public
  100.     constructor Create(AOwner: TComponent);
  101.     destructor Destroy; override;
  102.     property Owner: TVolgaDBEdit read FOwner;
  103.     property ViewField: string read GetViewField;  //ΓΦΣΦ∞εσ ∩εδσ, Ωε≥ε≡εσ ΓΦΣφε ∩ε±δσ ταΩ≡√≥Φ  Lookup'a
  104.   published
  105.     property SourceKeyField: string read FSourceKeyField write SetSourceKeyField;
  106.     property LookupKeyField: string read FLookupKeyField write SetLookupKeyField;
  107.     property ListFieldNames: string read FListFieldNames write SetListFieldNames;
  108.     property ViewFieldIndex: Integer read FListFieldIndex write FListFieldIndex default
  109.       0;
  110.   end;
  111.  
  112.   TVolgaTreeProperties = class(TPersistent)
  113.   private
  114.     FOwner: TVolgaDBEdit;
  115.     FUniqueField: string;
  116.     FLevelField: string;
  117.     FSeparator: char;
  118.     FTextField: string;
  119.   public
  120.     constructor Create(AOwner: TComponent);
  121.     procedure PrepareTree;
  122.     property Owner: TVolgaDBEdit read FOwner;
  123.   published
  124.     property LevelField: string read FLevelField write FLevelField;
  125.     property PathSeparator: char read FSeparator write FSeparator default '/';
  126.     property TextField: string read FTextField write FTextField;
  127.     property UniqueField: string read FUniqueField write FUniqueField;
  128.   end;
  129.  
  130.   TVolgaDBEdit = class(TCustomMaskEdit)
  131.   private
  132.     FButtonWidth: Integer;
  133.     FDroppedDown: Boolean;
  134.     FCanvas: TControlCanvas;
  135.     FTracking: Boolean;
  136.     FPressed: Boolean;
  137.     FLookupList: TDBLookupListBox;
  138.     FComboList: TVolgaListbox;
  139.     FTreeList: TVolgaPopupTree;
  140.     FCalendar: TVolgaDlgCalendar;
  141.     FActiveList: TWinControl;
  142.     FOnCustomDlg: TNotifyEvent;
  143.     FStyle: TVolgaComboBoxStyle;
  144.     FDataLink: TFieldDataLink;
  145.     FAlignment: TAlignment;
  146.     FFocused: Boolean;
  147.     FOnDisplayText: TGetTextEvent;
  148.     FOnUpdateData: TSetTextEvent;
  149.     FDialogStyle: TVolgaDialogStyle;
  150.     FDropDownWidth: Cardinal;
  151.     FDropDownRows: Cardinal;
  152.     FComboProps: TVolgaComboProperties;
  153.     FLookupProps: TVolgaLookupProperties;
  154.     FTreeProps: TVolgaTreeProperties;
  155.     FAutoDrop: Boolean;
  156.     FNextControl: integer;
  157.     FOnCloseUp: TCloseUpEvent;
  158.     FValue: Variant;
  159.     FClearValue: string;
  160.     FPrepared: Boolean;
  161.     FLookupSource: TDatasource;
  162.     FLookupDataSet: TDataSet;
  163.     FOnDropDown: TNotifyEvent;
  164.     FAsTab: Boolean;
  165.     function ButtonRect: TRect;
  166.     function GetSelectedValue: Variant;
  167.     procedure SetViewText(AValue: Variant; AText: string);
  168.     procedure DataChange(Sender: TObject);
  169.     procedure EditingChange(Sender: TObject);
  170.     function GetDataField: string;
  171.     function GetDataSource: TDataSource;
  172.     procedure SetDataField(const Value: string);
  173.     procedure SetDataSource(Value: TDataSource);
  174.     procedure SetFocused(Value: Boolean);
  175.     procedure SetDialogStyle(const Value: TVolgaDialogStyle);
  176.     function GetComboProps: TVolgaComboProperties;
  177.     procedure SetComboProps(const Value: TVolgaComboProperties);
  178.     procedure UpdateData(Sender: TObject);
  179.     procedure SetEditRect;
  180.     procedure CalSelectDate(Sender:TObject);
  181.     procedure ListMouseUp(Sender: TObject; Button: TMouseButton;
  182.       Shift: TShiftState; X, Y: Integer);
  183.     procedure StopTracking;
  184.     procedure TrackButton(X, Y: Integer);
  185.     function OverButton(const P: TPoint): Boolean;
  186.     procedure CheckDB;
  187.     function DBLinked: Boolean;
  188.     function GetViewTextNonDB: string;
  189.     procedure CMCancelMode(var Message: TCMCancelMode); message CM_CancelMode;
  190.     procedure WMCancelMode(var Message: TMessage); message WM_CancelMode;
  191.     procedure WMKillFocus(var Message: TMessage); message WM_KillFocus;
  192.     procedure WMSetFocus(var Message: TWMSetFocus); message WM_SetFocus;
  193.     procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message wm_LButtonDblClk;
  194.     procedure WMSetCursor(var Message: TWMSetCursor); message WM_SetCursor;
  195.     procedure WMCut(var Message: TMessage); message WM_CUT;
  196.     procedure WMPaste(var Message: TMessage); message WM_PASTE;
  197.     procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
  198.     procedure CMExit(var Message: TCMExit); message CM_EXIT;
  199.     procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  200.     procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
  201.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  202.     function GetLookupProps: TVolgaLookupProperties;
  203.     procedure SetLookupProps(const Value: TVolgaLookupProperties);
  204.     function GetTreeProps: TVolgaTreeProperties;
  205.     procedure SetTreeProps(const Value: TVolgaTreeProperties);
  206.     procedure SetValue(const Value: Variant);
  207.     procedure SetLookupDataSet(const Value: TDataSet);
  208.     function GetItemIndex: integer;
  209.     procedure SetItemIndex(const AValue: integer);
  210.     procedure SetAlignment(const Value: TAlignment);
  211.     procedure SetButtonWidth(const Value: integer);
  212.   protected
  213.     procedure Change; override;
  214.     procedure CloseUp(Accept: Boolean); virtual;
  215.     procedure CreateParams(var Params: TCreateParams); override;
  216.     procedure CreateWnd; override;
  217.     procedure DoDropDownKeys(var Key: Word; Shift: TShiftState);
  218.     function Editable: boolean;
  219.     function EditCanModify: Boolean; override;
  220.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  221.     procedure KeyPress(var Key: Char); override;
  222.     procedure Loaded; override;
  223.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  224.       X, Y: Integer); override;
  225.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  226.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  227.       X, Y: Integer); override;
  228.     procedure Notification(AComponent: TComponent;
  229.       Operation: TOperation); override;
  230.     procedure PaintWindow(DC: HDC); override;
  231.     procedure Reset; override;
  232.     procedure WndProc(var Message: TMessage); override;
  233.   public
  234.     constructor Create(AOwner: tcomponent); override;
  235.     destructor Destroy; override;
  236.     function ExecuteAction(Action: TBasicAction): Boolean; override;
  237.     function UpdateAction(Action: TBasicAction): Boolean; override;
  238.     procedure DropDown; virtual;
  239.     procedure CreateDropDownList;         //±ετΣα≥ⁿ-εßφεΓΦ≥ⁿ Γ√∩αΣ.δΦ±≥ ∩ε±δσ Φτ∞σφσφΦΘ
  240.     function IsLinkActive:Boolean;
  241.     property ItemIndex: integer read GetItemIndex write SetItemIndex;
  242.     property Value: Variant read FValue write SetValue;
  243.   published
  244.     property Anchors;
  245.     property AutoSelect;
  246.     property AutoSize;
  247.     property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  248.     property AutoDropDown: Boolean read FAutoDrop write FAutoDrop default false;
  249.     property ButtonWidth: integer read FButtonWidth write SetButtonWidth default 15;
  250.     property BorderStyle;
  251.     property CharCase;
  252.     property ClearValue: string read FClearValue write FClearValue;
  253.     property Color;
  254.     property Constraints;
  255.     property ComboProps: TVolgaComboProperties read GetComboProps write SetComboProps;
  256.     property Ctl3D;
  257.     property DataField: string read GetDataField write SetDataField;
  258.     property DataSource: TDataSource read GetDataSource write SetDataSource;
  259. //  property DragCursor;
  260. //  property DragMode;
  261.     property DropDownRows: Cardinal read FDropDownRows write FDropDownRows default 10;
  262.     property DropDownWidth: Cardinal read FDropDownWidth write FDropDownWidth default 0;
  263.     property DialogStyle: TVolgaDialogStyle read FDialogStyle write SetDialogStyle default
  264.       vdsEdit;
  265.     property Enabled;
  266.     property EnterAsTab: Boolean read FAsTab write FAsTab default true;
  267.     property Font;
  268.     property LookupDataSet: TDataSet read FLookupDataSet write SetLookupDataSet;                       //Volga
  269.     property LookupProps: TVolgaLookupProperties read GetLookupProps write SetLookupProps;
  270.     property MaxLength;
  271.     property ParentColor;
  272.     property ParentCtl3D;
  273.     property ParentFont;
  274.     property ParentShowHint;
  275.     property PasswordChar;
  276.     property PopupMenu;
  277.     property ReadOnly; //: Boolean read GetReadOnly write SetReadOnly default False;
  278.     property ShowHint;
  279.     property Style: TVolgaComboBoxStyle read FStyle write FStyle default vcsDropDown;
  280.     property TabOrder;
  281.     property TabStop;
  282.     property TreeProps: TVolgaTreeProperties read GetTreeProps write SetTreeProps;
  283.     property Visible;
  284.     property OnChange;
  285.     property OnClick;
  286.     property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
  287.     property OnCloseUp: TCloseUpEvent read FOnCloseUp write FOnCloseUp;
  288.     property OnCustomDlg: TNotifyEvent read FOnCustomDlg write FOnCustomDlg;
  289.     property OnDisplayText: TGetTextEvent read FOnDisplayText write FOnDisplayText;
  290.     property OnUpdateData: TSetTextEvent read FOnUpdateData write FOnUpdateData;
  291. //  property OnDragDrop;
  292. //  property OnDragOver;
  293. //  property OnEndDrag;
  294.     property OnEnter;
  295.     property OnExit;
  296.     property OnKeyDown;
  297.     property OnKeyPress;
  298.     property OnKeyUp;
  299.     property OnMouseDown;
  300.     property OnMouseMove;
  301.     property OnMouseUp;
  302.   end;
  303.  
  304. implementation
  305.  
  306. {.$R *.RES}
  307.  
  308. procedure KillMessage(Wnd: HWnd; Msg: Integer);
  309. // Delete the requested message from the queue, but throw back
  310. // any WM_QUIT msgs that PeekMessage may also return
  311. var
  312.   M: TMsg;
  313. begin
  314.   M.Message := 0;
  315.   if PeekMessage(M, Wnd, Msg, Msg, pm_Remove) and (M.Message = WM_QUIT) then
  316.     PostQuitMessage(M.wparam);
  317. end;
  318.  
  319. constructor TVolgaListbox.Create(AOwner: TComponent);
  320. begin
  321.   inherited Create(AOwner);
  322.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  323. end;
  324.  
  325. procedure TVolgaListbox.CreateParams(var Params: TCreateParams);
  326. begin
  327.   inherited CreateParams(Params);
  328.   with Params do
  329.   begin
  330.     Style := Style or WS_BORDER;
  331.     ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
  332.     AddBiDiModeExStyle(ExStyle);
  333.     WindowClass.Style := CS_SAVEBITS;
  334.   end;
  335. end;
  336.  
  337. procedure TVolgaListbox.CreateWnd;
  338. begin
  339.   inherited CreateWnd;
  340.   Windows.SetParent(Handle, 0);
  341.   CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
  342. end;
  343.  
  344. procedure TVolgaListbox.Keypress(var Key: Char);
  345. begin
  346.   case Key of
  347.     #8, #27: FSearchText := '';
  348.     #32..#255:
  349.       begin
  350.         if Length(FSearchText) < 32 then FSearchText := FSearchText + Key;
  351.         SendMessage(Handle, LB_SelectString, WORD(-1), Longint(PChar(FSearchText)));
  352.         Key := #0;
  353.       end;
  354.   end;
  355.   inherited Keypress(Key);
  356. end;
  357.  
  358. { TVolgaDlgCalendar }
  359.  
  360. constructor TVolgaDlgCalendar.Create(AOwner: TComponent);
  361. begin
  362.   inherited Create(AOwner);
  363.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  364. end;
  365.  
  366. procedure TVolgaDlgCalendar.CreateParams(var Params: TCreateParams);
  367. begin
  368.   inherited CreateParams(Params);
  369.   with Params do
  370.   begin
  371.     Style := Style or WS_BORDER;
  372.     ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
  373.     AddBiDiModeExStyle(ExStyle);
  374.     WindowClass.Style := CS_SAVEBITS;
  375.   end;
  376. end;
  377.  
  378. procedure TVolgaDlgCalendar.CreateWnd;
  379. begin
  380.   inherited CreateWnd;
  381.   Windows.SetParent(Handle, 0);
  382.   CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
  383. end;
  384.  
  385. { TVolgaPopupTree }
  386.  
  387. constructor TVolgaPopupTree.Create(AOwner: TComponent);
  388. begin
  389.   inherited Create(AOwner);
  390.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  391.   ShowLines := true;
  392. end;
  393.  
  394. procedure TVolgaPopupTree.CreateParams(var Params: TCreateParams);
  395. begin
  396.   inherited CreateParams(Params);
  397.   with Params do
  398.   begin
  399.     Style := Style or WS_BORDER;
  400.     ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
  401.     AddBiDiModeExStyle(ExStyle);
  402.     WindowClass.Style := CS_SAVEBITS;
  403.   end;
  404. end;
  405.  
  406. procedure TVolgaPopupTree.CreateWnd;
  407. begin
  408.   inherited CreateWnd;
  409.   Windows.SetParent(Handle, 0);
  410.   CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
  411. end;
  412.  
  413. function TVolgaPopupTree.FindNodeByUniqueID(UniqueID: string): TTreeNode;
  414. var i: integer;
  415. begin
  416.   {φαΘ≥Φ Node,±εε≥Γ.≤φΦΩ.ΩεΣ≤ τα∩Φ±Φ}
  417.   Result := nil;
  418.   for i := 0 to Items.Count - 1 do
  419.     if PShortString(Items[i].Data)^ = UniqueID then
  420.     begin
  421.       Result := Items[i];
  422.       Break;
  423.     end;
  424. end;
  425.  
  426. function TVolgaPopupTree.GetFullCaption(UniqueID: string; Delimiter: char): string;
  427. {∩εδφεσ φαΦ∞σφεΓαφΦσ Node ∩ε σπε ≤φΦΩ.ΩεΣ≤,φα≈Φφα  ± ∩σ≡Γεπε ≡εΣΦ≥σδ }
  428. var FindNode: TTreeNode;
  429. begin
  430.   FindNode := FindNodeByUniqueID(UniqueID);
  431.   Result := GetFullNodeCaption(FindNode, Delimiter);
  432. end;
  433.  
  434. function TVolgaPopupTree.GetFullNodeCaption(Node: TTreeNode; Delimiter: char): string;
  435. {∩εδφεσ φαΦ∞σφεΓαφΦσ Node,φα≈Φφα  ± ∩σ≡Γεπε ≡εΣΦ≥σδ }
  436. var ParentNode: TTreeNode;
  437. begin
  438.   if Node <> nil then
  439.   begin
  440.     Result := Node.Text;
  441.     if Node.Level = 0 then Exit;          //Σε°δΦ Σε ±α∞επε Γσ≡⌡φσπε ≤≡εΓφ 
  442.     ParentNode := Node.Parent;
  443.     while (ParentNode <> nil) and (ParentNode.Level >= 0) do
  444.     begin
  445.       Result := ParentNode.Text + Delimiter + Result;
  446.       try ParentNode := ParentNode.Parent; except; end;
  447.     end;
  448.   end
  449.   else
  450.     Result := '';
  451. end;
  452.  
  453. { TVolgaDBEdit }
  454.  
  455. constructor TVolgaDBEdit.Create;
  456. begin
  457.   inherited Create(AOwner);
  458.   ControlStyle := ControlStyle + [csReplicatable] - [csDoubleClicks];
  459.   DropDownRows := 10;
  460.   FDialogStyle := vdsEdit;
  461.   FAutoDrop := false;
  462.   FStyle := vcsDropDown;
  463.   FNextControl := 0;
  464.   FActiveList := nil;
  465.   FAlignment := taLeftJustify;
  466.   FPrepared := false;
  467.   FAsTab := true;
  468.   FClearValue := '';
  469.   FValue := ClearValue;      //∩≤±≥α  ±≥≡εΩα
  470.   FButtonWidth := 15;
  471.   FLookupSource := TDataSource.Create(Self);
  472.   FDataLink := TFieldDataLink.Create;
  473.   FDataLink.Control := Self;
  474.   FDataLink.OnDataChange := DataChange;
  475.   FDataLink.OnEditingChange := EditingChange; //Γε°δΦ ΦδΦ Γ√°δΦ Φτ ≡σµΦ∞α ≡σΣαΩ≥Φ≡εΓαφΦ 
  476.   FDataLink.OnUpdateData := UpdateData;
  477.   Invalidate;
  478. end;
  479.  
  480. destructor TVolgaDBEdit.Destroy;
  481. begin
  482.   FDataLink.Control := nil;
  483.   FDataLink.Free;
  484.   FDataLink := nil;
  485.   if Assigned(FLookupList) then   //ε≥÷σ∩ΦδΦ lookup-Σα≥α±σ≥
  486.     FLookupList.ListSource := nil;
  487.   FLookupSource.Dataset := nil;
  488.   FLookupSource.Free;
  489.   FLookupSource := nil;
  490.   if Assigned(FComboProps) then FComboProps.Free;
  491.   FComboProps := nil;
  492.   if Assigned(FLookupProps) then FLookupProps.Free;
  493.   FLookupProps := nil;
  494.   if Assigned(FTreeProps) then FTreeProps.Free;
  495.   FTreeProps := nil;
  496.   FCanvas.Free;
  497.   //Γ√∩αΣα■∙Φσ Ωεφ≥≡εδΦ Σσ±≥≡ε ≥±  ±α∞Φ, ≥.Ω. ≤ φΦ⌡ σ±≥ⁿ owner
  498.   inherited Destroy;
  499. end;
  500.  
  501. procedure TVolgaDBEdit.Notification(AComponent: TComponent;
  502.   Operation: TOperation);
  503. begin
  504.   inherited Notification(AComponent, Operation);
  505.   if Operation = opRemove then
  506.   begin
  507.     if (FDataLink <> nil) and (AComponent = DataSource) then begin
  508.       DataSource := nil;    FPrepared := false;
  509.     end;
  510.     if (LookupDataSet = AComponent) then
  511.     begin
  512.       LookupDataSet := nil; FPrepared := false;
  513.     end;
  514.   end;
  515. end;
  516.  
  517. procedure TVolgaDBEdit.CreateWnd;
  518. begin
  519.   inherited CreateWnd;
  520.   if DialogStyle <> vdsEdit then
  521.     SetEditRect;
  522. end;
  523.  
  524. procedure TVolgaDBEdit.SetEditRect;
  525. var
  526.   Loc: TRect;
  527. begin
  528.   SetRect(Loc, 0, 0, ClientWidth - FButtonWidth - 2, ClientHeight + 1);
  529.   SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
  530.   if not DBLinked and not (csDesigning in ComponentState) then CreateDropDownList;
  531. end;
  532.  
  533. procedure TVolgaDBEdit.CreateParams(var Params: TCreateParams);
  534. begin
  535.   inherited CreateParams(Params);
  536.   Params.Style := (Params.Style and not (ES_AUTOVSCROLL or ES_WANTRETURN) or
  537.     WS_CLIPCHILDREN or ES_MULTILINE);
  538. end;
  539.  
  540. function TVolgaDBEdit.ButtonRect: TRect;
  541. var R: TRect;
  542. begin
  543.   R := ClientRect;
  544.   Result := Rect(R.Right - FButtonWidth, R.Top, R.Right, R.Bottom);
  545. end;
  546.  
  547. procedure TVolgaDBEdit.PaintWindow(DC: HDC);
  548. var
  549.   R: TRect;
  550.   Flags: Integer;
  551.   W, X, Y: Integer;
  552. begin
  553.    //≡Φ±≤σ∞ Ωφε∩Ω≤
  554.   if FDialogStyle <> vdsEdit then
  555.   begin
  556.     R := ButtonRect;                      //≡σπΦεφ, ταφΦ∞ασ∞√Θ Ωφε∩ΩεΘ
  557.     Flags := 0;
  558.     if FDialogStyle in [vdsCombo, vdsLookup, vdsCalendar, vdsTree] then
  559.     begin
  560.       if FActiveList = nil then           //Γ√∩αΣα■∙ΦΘ Ωεφ≥≡εδⁿ φσ ±ετΣαφ
  561.         Flags := DFCS_INACTIVE
  562.       else if FPressed then               //Ωφε∩Ωα ≡Φ±≤σ≥±  φαµα≥εΘ
  563.         Flags := DFCS_FLAT or DFCS_PUSHED;
  564.       DrawFrameControl(DC, R, DFC_SCROLL, Flags or DFCS_SCROLLCOMBOBOX);
  565.     end
  566.     else                                  { vdsCustomDlg }
  567.     begin
  568.       if FPressed then Flags := BF_FLAT;  //Ωφε∩Ωα ≡Φ±≤σ≥±  φαµα≥εΘ
  569.       DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_MIDDLE or Flags);
  570.       X := R.Left + ((R.Right - R.Left) shr 1) - 1 + Ord(FPressed);
  571.       Y := R.Top + ((R.Bottom - R.Top) shr 1) - 1 + Ord(FPressed);
  572.       W := FButtonWidth shr 3;
  573.       if W = 0 then W := 1;
  574.       PatBlt(DC, X, Y, W, W, BLACKNESS);  //≡Φ±≤■≥±  ≥≡Φ ≥ε≈ΩΦ
  575.       PatBlt(DC, X - (W * 2), Y, W, W, BLACKNESS);
  576.       PatBlt(DC, X + (W * 2), Y, W, W, BLACKNESS);
  577.     end;
  578.     ExcludeClipRect(DC, R.Left, R.Top, R.Right, R.Bottom);
  579.   end;
  580.   inherited PaintWindow(DC);
  581. end;
  582.  
  583. procedure TVolgaDBEdit.WMPaint(var Message: TWMPaint);
  584. var
  585.   aLeft: Integer;
  586.   Margins: TPoint;
  587.   R: TRect;
  588.   DC: HDC;
  589.   PS: TPaintStruct;
  590.   S: string;
  591.   AAlignment: TAlignment;
  592.  
  593.   function GetTextMargins: TPoint;
  594.   var
  595.     I: Integer;
  596.   begin
  597.     if BorderStyle = bsNone then I := 0 else
  598.       if Ctl3D then I := 1 else I := 2;
  599.     Result.X := SendMessage(Handle, EM_GETMARGINS, 0, 0) and $0000FFFF + I;
  600.     Result.Y := I;
  601.   end;
  602.  
  603. begin
  604.   AAlignment := FAlignment;
  605.   if ((AAlignment = taLeftJustify) or FFocused or (FDialogStyle <> vdsEdit)) and
  606.     not (csPaintCopy in ControlState) then
  607.   begin
  608.     inherited;
  609.     Exit;
  610.   end;
  611.   if FCanvas = nil then
  612.   begin
  613.     FCanvas := TControlCanvas.Create;
  614.     FCanvas.Control := Self;
  615.   end;
  616.   DC := Message.DC;
  617.   if DC = 0 then DC := BeginPaint(Handle, PS);
  618.   FCanvas.Handle := DC;
  619.   try
  620.     FCanvas.Font := Font;
  621.     with FCanvas do
  622.     begin
  623.       R := ClientRect;
  624.       Brush.Color := Color;
  625.       if not Enabled then
  626.         Font.Color := clGrayText;
  627.       S := EditText;
  628.       Margins := GetTextMargins;
  629.       case AAlignment of
  630.         taLeftJustify: aLeft := Margins.X;
  631.         taRightJustify: aLeft := ClientWidth - TextWidth(S) - Margins.X - 1;
  632.       else
  633.         aLeft := (ClientWidth - TextWidth(S)) div 2;
  634.       end;
  635.       TextRect(R, aLeft, Margins.Y, S);
  636.     end;
  637.   finally
  638.     FCanvas.Handle := 0;
  639.     if Message.DC = 0 then EndPaint(Handle, PS);
  640.   end;
  641. end;
  642.  
  643. procedure TVolgaDBEdit.CMCancelMode(var Message: TCMCancelMode);
  644. begin //ταΩ≡√≥ⁿ Γ√∩αΣα■∙ΦΘ Ωεφ≥≡εδⁿ, σ±δΦ message ∩ε±δαφ φσ φα°σ∞≤ Ωε∞∩εφσφ≥≤
  645.   if (Message.Sender <> Self) and (Message.Sender <> FActiveList) then
  646.     if (Message.Sender <> nil) and (Message.Sender.Parent <> FActiveList)
  647.     or (Message.Sender = nil) then
  648.       CloseUp(False);
  649. end;
  650.  
  651. procedure TVolgaDBEdit.WMCancelMode(var Message: TMessage);
  652. begin
  653.   StopTracking;                           //≡Φ±≤σ∞ Ωφε∩Ω≤ ε≥µα≥εΘ
  654.   inherited;
  655. end;
  656.  
  657. procedure TVolgaDBEdit.WMKillFocus(var Message: TMessage);
  658. begin
  659.   inherited;
  660.   if FDroppedDown then
  661.     CloseUp(False);
  662. end;
  663.  
  664. procedure TVolgaDBEdit.SetViewText(AValue: Variant; AText: string);
  665. var i: integer;
  666.   strValue: string;
  667. begin //≤±≥αφεΓΦ≥ⁿ ε≥εß≡αµασ∞√Θ ≥σΩ±≥ ∩ε τφα≈σφΦ■ Φτ ∩εδ  ┴─
  668.   if (csDestroying in ComponentState) then Exit;
  669.   if not FPrepared then CreateDropDownList;
  670.   if not VarIsArray(AValue) and not VarIsNull(AValue) then
  671.     strValue := AText
  672.   else strValue := '';
  673.   if not FPrepared then
  674.     Text := strValue
  675.   else
  676.   begin
  677.     if Assigned(FOnDisplayText) then      //∩εΩατ√Γασ∞ ≥σΩ±≥, calculated ∩ε ∩εδ■!!!
  678.       Text := FOnDisplayText(self, strValue)
  679.     else if Assigned(FActiveList) then
  680.     begin
  681.       if FActiveList = FComboList then
  682.       begin
  683.         if ComboProps.HasValues then
  684.         begin                             //≥σΩ±≥ ± ∩εΣ±≥αφεΓΩεΘ Φτ Γ√∩αΣα■∙σπε ±∩Φ±Ωα
  685.           i := ComboProps.ComboValues.IndexOf(strValue);
  686.           if i >= 0 then
  687.             Text := ComboProps.ComboItems[i]
  688.           else
  689.             Text := '';
  690.         end
  691.         else if Style = vcsDropDownList then
  692.         begin
  693.           i := ComboProps.ComboItems.IndexOf(strValue);
  694.           if i >= 0 then
  695.             Text := strValue
  696.           else
  697.             Text := '';
  698.         end
  699.         else
  700.           Text := strValue;
  701.       end
  702.       else if FActiveList = FLookupList then
  703.       begin
  704.         //∩ε ΩεΣ≤ Φ∙σ∞ ≥σΩ±≥
  705.         if not VarIsNull(AValue) and IsLinkActive and
  706.           FLookupDataSet.Locate(LookupProps.LookupKeyField, AValue, []) then //τΣσ±ⁿ Value ∞.ß. ±≡ατ≤ 2 ∩εδ !!
  707.           Text := FLookupDataSet.FieldByName(LookupProps.ViewField).Text
  708.         else if Style = vcsDropDownList then
  709.           Text := ''
  710.         else
  711.           Text := strValue;
  712.       end
  713.       else if FActiveList = FTreeList then
  714.       begin
  715.         //∩ε ΩεΣ≤ Φ∙σ∞ ≥σΩ±≥ - ∩εδφεσ φαΦ∞σφεΓαφΦσ π≡≤∩∩√
  716.         if not VarIsNull(AValue) and (FTreeList.Items.Count > 0) then
  717.           Text := FTreeList.GetFullCaption(strValue, TreeProps.PathSeparator)
  718.         else
  719.           Text := '';
  720.       end
  721.       else
  722.         if (Pos('.00.',strValue)>0) or (Pos('/00/',strValue)>0) then Text := ''
  723.         else Text := strValue;                    //Σδ  Calendar
  724.     end
  725.     else
  726.       Text := strValue;
  727.   end;
  728.   EditText := Text;
  729.   case CharCase of
  730.     ecUpperCase: EditText := AnsiUpperCase(EditText);
  731.     ecLowerCase: EditText := AnsiLowerCase(EditText);
  732.   end;
  733. end;
  734.  
  735. function TVolgaDBEdit.GetViewTextNonDB: string;
  736. var ind:integer;
  737. begin //≤±≥αφεΓΦ≥ⁿ ε≥εß≡αµασ∞√Θ ≥σΩ±≥ ∩ε τφα≈σφΦ■,Γ√ß≡αφφε∞≤ Φτ Γ√∩αΣ.±∩Φ±Ωα, σ±δΦ φσ≥ ┴─
  738.   if (csDestroying in ComponentState) then Exit;
  739.   if not FPrepared then CreateDropDownList;
  740.   if not FPrepared then
  741.     Result := ''
  742.   else
  743.   begin
  744.     if Assigned(FActiveList) then
  745.     begin
  746.       if FActiveList = FComboList then begin
  747.         ind := FComboList.ItemIndex;
  748.         if ind > -1 then
  749.           Result := ComboProps.ComboItems[ind];
  750.       end else if (FActiveList = FLookupList) and (FLookupList.SelectedItem > '') then
  751.         Result := FLookupList.SelectedItem
  752.       else if (FActiveList = FTreeList) and (FTreeList.Items.Count > 0) then
  753.         Result := FTreeList.GetFullNodeCaption(FTreeList.Selected, TreeProps.PathSeparator)
  754.       else if (FActiveList = FCalendar) then
  755.         Result := DateToStr(FCalendar.Date)
  756.       else
  757.         Result := '';
  758.     end;
  759.   end;
  760. end;
  761.  
  762. function TVolgaDBEdit.GetSelectedValue: Variant;
  763. //∩≡Φ±ΓεΦ≥ⁿ ∩εδ■ τφα≈σφΦσ ∩ε Γ√ß≡αφφε∞≤ ≥σΩ±≥≤ φα Σαφφ√Θ ∞ε∞σφ≥
  764. var ind: integer;
  765. begin
  766.   if not FPrepared then CreateDropDownList;
  767.   if not FPrepared then
  768.     Result := Text
  769.   else
  770.   begin
  771.     if Assigned(FActiveList) then
  772.     begin
  773.       if (FActiveList = FLookupList) and (FLookupList.SelectedItem > '') then
  774.         Result := FLookupList.KeyValue  //ΩεΣ Σδ  Γ√ß≡αφφεπε ≥σΩ±≥α Γ lookup'e
  775.       else if (FActiveList = FTreeList) and (FTreeList.Selected <> nil) then
  776.         Result := PShortString(FTreeList.Selected.Data)^  //ΩεΣ Σδ  Γ√ß≡αφφεπε ≥σΩ±≥α Γ Tree
  777.       else if FActiveList = FComboList then
  778.       begin
  779.         ind := FComboList.ItemIndex;
  780.         if ind > -1 then
  781.           if ComboProps.HasValues then
  782.             Result := ComboProps.ComboValues[ind]
  783.           else
  784.             Result := ComboProps.ComboItems[ind]
  785.         else if (Style = vcsDropDownList) and DBLinked then
  786.           Result := FDataLink.Field.Text  //φσ ∞σφ σ∞ φα φσ∩≡αΓΦδⁿφ√Θ!
  787.         else
  788.           Result := Text;
  789.       end
  790.       else if FActiveList = FCalendar then
  791.         Result := FCalendar.Date;
  792.     end
  793.     else                                  //Tree???????
  794.       Result := Text;
  795.   end;
  796. end;
  797.  
  798. procedure TVolgaDBEdit.CloseUp(Accept: boolean);
  799. begin
  800.   if Accept then Modified := True;
  801.   if FDroppedDown then
  802.   begin
  803.     //╤εεß∙σφΦσ ∩ε±√δασ≥±  εΩφ≤, Φ∞σ■∙σ∞≤ ⌠εΩ≤± ∩≡Φ ε≥εß≡αµσφΦΦ ∞εΣαδⁿφ√⌡ ⌠ε≡∞
  804.     //- ΣΦαδεπεΓ Φ ±εεß∙σφΦΘ εß ε°ΦßΩα⌡. ─ασ≥ Γετ∞εµφε±≥ⁿ εΩφ≤ ταΩ≡√≥ⁿ±  Φ ε±ΓεßεµΣασ≥ ∞√°ⁿ.
  805.     if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  806.     //±∩≡ ≥α≥ⁿ Γ√∩αΣα■∙ΦΘ Ωεφ≥≡εδⁿ
  807.     SetWindowPos(FActiveList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  808.       SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  809.     FDroppedDown := False;
  810.     if Accept and EditCanModify then      //τφα≈σφΦσ τα∩Φ±√Γασ∞ Γ ∩εδσ Σα≥α±σ≥α
  811.     try
  812.       FValue := GetSelectedValue;         //Σαµσ φσ Σδ  DB-ε≡Φσφ≥Φ≡!, ∞.ß. >1 ∩εδ , σ±δΦ ²≥ε lookup ∩ε ΣΓ≤∞ ∩εδ ∞!!
  813.       if DBLinked then
  814.         FDataLink.Modified
  815.       else begin //φσ DB-oriented
  816.         Text := GetViewTextNonDB;
  817.         EditText := Text;
  818.         case CharCase of
  819.           ecUpperCase: EditText := AnsiUpperCase(EditText);
  820.           ecLowerCase: EditText := AnsiLowerCase(EditText);
  821.         end;
  822.       end;
  823.       UpdateData(Self);
  824.     except
  825.       SelectAll;
  826.       SetFocus;
  827.       raise;
  828.     end;
  829.     Invalidate;
  830.     if Assigned(FOnCloseUp) then FOnCloseUp(self, Accept);
  831.   end;
  832. end;
  833.  
  834. function TVolgaDBEdit.EditCanModify: Boolean;
  835. begin
  836.   Result := (FDataLink.Field = nil) or (FDataLink.Dataset.CanModify and FDataLink.Edit);
  837. end;
  838.  
  839. procedure TVolgaDBEdit.DropDown;
  840. var I, J, X, Y: integer; P: TPoint;
  841. begin
  842.   if not FDroppedDown and Assigned(FActiveList) then
  843.   begin
  844.     if Assigned(FOnDropDown) then FOnDropDown(Self);
  845.     FDroppedDown := True;
  846.     if DropDownWidth > 0 then
  847.       FActiveList.Width := DropDownWidth  //°Φ≡Φφα ≤Ωαταφα  Γφε
  848.     else
  849.       FActiveList.Width := Width;
  850.     if FActiveList = FLookupList then begin   //∩√≥ασ∞±  Φ±Ωα≥ⁿ Γ ±∩Φ±Ωσ φ≤µφεσ τφα≈σφΦσ
  851.       FLookupList.KeyValue := FValue;
  852.       LookupDataset.Locate(LookupProps.LookupKeyField,FValue,[]);
  853.     end else if FActiveList = FTreeList then
  854.     begin
  855.       FTreeList.FullCollapse;
  856.       //∩√≥ασ∞±  Φ±Ωα≥ⁿ Γ ±∩Φ±Ωσ φ≤µφεσ τφα≈σφΦσ
  857.       if VarToStr(FValue) > '' then
  858.         FTreeList.Selected := FTreeList.FindNodeByUniqueID(VarToStr(FValue));
  859.       FTreeList.Height := 200;
  860.     end
  861.     else if FActiveList = FComboList then
  862.     begin
  863.       FComboList.FSearchText := '';       //ε≈Φ∙ασ∞ ≥σΩ±≥ ∩≡Φ ΩαµΣε∞ Γ√∩αΣσφΦΦ!!
  864.       //≡α±±≈Φ≥√Γασ∞ Γ√±ε≥≤ Γ√∩αΣα■∙σπε ±∩Φ±Ωα
  865.       if FComboList.Items.Count >= Integer(DropDownRows) then
  866.         FComboList.Height := Integer(DropDownRows) * FComboList.ItemHeight + 4
  867.       else
  868.         FComboList.Height := FComboList.Items.Count * FComboList.ItemHeight + 4;
  869.       if VarToStr(FValue) = '' then
  870.         FComboList.ItemIndex := -1
  871.       else if ComboProps.HasValues then
  872.         FComboList.ItemIndex := ComboProps.ComboValues.IndexOf(VarToStr(FValue))
  873.       else
  874.         FComboList.ItemIndex := ComboProps.ComboItems.IndexOf(VarToStr(FValue));
  875.       //≡α±±≈Φ≥√Γασ∞ °Φ≡Φφ≤ ∞αΩ±Φ∞αδⁿφε ΣδΦφφεπε ²δσ∞σφ≥α
  876.       J := FComboList.ClientWidth;
  877.       for I := 0 to FComboList.Items.Count - 1 do
  878.       begin
  879.         Y := FComboList.Canvas.TextWidth(FComboList.Items[I]);
  880.         if Y > J then J := Y;
  881.       end;
  882.       FComboList.ClientWidth := J;
  883.     end
  884.     else if FActiveList = FCalendar then
  885.     begin                                 //ΩαδσφΣα≡ⁿ
  886.       if VarIsNull(FValue) then
  887.         FCalendar.Date := Date
  888.       else
  889.         try
  890.           FCalendar.Date := VarAsType(FValue, varDate);
  891.         except FCalendar.Date := Date; end;
  892.     end;
  893.     P := Parent.ClientToScreen(Point(Left, Top));
  894.     X := P.X;
  895.     Y := P.Y + Height;
  896.     if X + FActiveList.Width > Screen.Width then X := Screen.Width - FActiveList.Width;
  897.     //εφ ß≤Σσ≥ ±Γσ≡⌡≤ ΦδΦ ±φΦτ≤ ∩α≡σφ≥-Ωεφ≥≡εδ ?
  898.     if Y + FActiveList.Height > Screen.Height then Y := P.Y - FActiveList.Height;
  899.     //∩εΩατα≥ⁿ Γ√∩αΣα■∙ΦΘ Ωεφ≥≡εδⁿ φσαΩ≥ΦΓφ√∞ ±Γσ≡⌡≤
  900.     SetWindowPos(FActiveList.Handle, HWND_TOP, X, Y, 0, 0,
  901.       SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  902.     FDroppedDown := True;
  903.     Invalidate;
  904.     Windows.SetFocus(Handle);             //⌠εΩ≤± ε±≥αδ±  φα edit-Ωεφ≥≡εδσ
  905.   end
  906.   else if Assigned(FOnCustomDlg) then
  907.   begin
  908.     FDroppedDown := True;
  909.     Invalidate;
  910.     try                                   { If exception then clean-up }
  911.       if DBLinked and FDataLink.Dataset.CanModify then
  912.         FDataLink.Edit;
  913.       FOnCustomDlg(self);
  914.     finally
  915.       if (not editable) then              //±∩≡ ≥α≥ⁿ Ω≤≡±ε≡
  916.         HideCaret(Handle);                { Support csDropDownList style }
  917.       Invalidate;
  918.       FDroppedDown := False;              {CustomDialog ταΩ≡√δ±  Φ dropdown ταΩεφ≈Φδ± }
  919.     end;
  920.   end;
  921. end;
  922.  
  923. function TVolgaDBEdit.Editable: boolean;
  924. begin
  925.   Result := (FStyle <> vcsDropDownList) or FDroppedDown;
  926. end;
  927.  
  928. procedure TVolgaDBEdit.DoDropDownKeys(var Key: Word; Shift: TShiftState);
  929. begin
  930.   FNextControl := 0;
  931.   case Key of
  932.     VK_UP, VK_DOWN:
  933.       if ssAlt in Shift then
  934.       begin
  935.         if FDroppedDown then
  936.           CloseUp(True)
  937.         else
  938.           DropDown;
  939.         Key := 0;
  940.       end
  941.       else if not FDroppedDown then
  942.       begin
  943.         if Key = VK_Down then
  944.           FNextControl := 1
  945.         else
  946.           FNextControl := -1;
  947.       end;
  948.     VK_RETURN, VK_ESCAPE:
  949.       begin
  950.         if FDroppedDown and not (ssAlt in Shift) then
  951.         begin                             //ταΩ≡√Γασ∞ Γ√∩αΣ.Ωεφ≥≡εδⁿ ∩ε ENTER Φ ESC
  952.           CloseUp(Key = VK_RETURN);
  953.           Key := 0;
  954.         end;
  955.       end;
  956.   end;
  957. end;
  958.  
  959. procedure TVolgaDBEdit.KeyDown(var Key: Word; Shift: TShiftState);
  960. begin
  961.   if (FDialogStyle = vdsCustomDlg) and (Key = VK_RETURN) and (Shift = [ssCtrl]) then
  962.   begin
  963.     if Assigned(FOnCustomDlg) then FOnCustomDlg(self);  //φαµα≥α Ωφε∩Ωα ∩≡εΦτΓ.≡σΣαΩ≥Φ≡εΓαφΦ 
  964.     KillMessage(Handle, WM_CHAR);
  965.   end
  966.   else
  967.   begin
  968.     if GetKeyState(VK_MENU) < 0 then
  969.       Include(Shift, ssAlt);
  970.     DoDropDownKeys(Key, Shift);
  971.     if FNextControl = 0 then
  972.     begin
  973.       inherited KeyDown(Key, Shift);
  974.       if ((Key = VK_DELETE) or (Key = VK_BACK) or ((Key = VK_INSERT) and (ssShift in Shift)))
  975.         and DBLinked and FDataLink.Dataset.CanModify then
  976.         FDataLink.Edit;
  977.     end
  978.     else if FNextControl > 0 then
  979.       if Parent is TCustomForm then       //≥.Ω. Σδ  TabSheet φσ ≡αßε≥ασ≥!!!!!!!!
  980.         PostMessage(Parent.Handle, WM_NEXTDLGCTL, 0, 0)
  981.       else if Owner is TCustomForm then
  982.         PostMessage(TWinControl(Owner).Handle, WM_NEXTDLGCTL, 0, 0)
  983.       else
  984.     else if Parent is TCustomForm then
  985.       PostMessage(Parent.Handle, WM_NEXTDLGCTL, 1, 0)
  986.     else if Owner is TCustomForm then
  987.       PostMessage(TWinControl(Owner).Handle, WM_NEXTDLGCTL, 1, 0)
  988.     else
  989.   end;
  990. end;
  991.  
  992. procedure TVolgaDBEdit.KeyPress(var Key: Char);
  993. begin
  994.   { Disregard tab key since inherited maskedit event will beep }
  995. //if isMasked and (Key = #9) then exit;
  996.   inherited KeyPress(Key);
  997.   //ΣεßαΓΦ≥ⁿ σ∙σ ±■Σα σ±δΦ Ωε∞ßε ßστ values ΦδΦ Σα≥α
  998.   if (Style <> vcsDropDownList) and (Key in [#32..#255]) and DBLinked
  999.     and not FDataLink.Field.IsValidChar(Key) then
  1000.   begin
  1001.     MessageBeep(0);
  1002.     Key := #0;
  1003.   end;
  1004.   case Key of
  1005.     ^H, ^V, ^X, #32..#255:
  1006.       begin
  1007.         if (Key = #32) and not FDroppedDown and (Style = vcsDropDownList) then
  1008.         begin
  1009.           Key := #0;
  1010.           DropDown;                       //∩ε ∩≡εßσδ≤ Γ√∩αΣασ∞
  1011.         end
  1012.         else
  1013.         begin
  1014.           if DBLinked and FDataLink.Dataset.CanModify and not FDataLink.Editing then
  1015.             FDataLink.Edit;
  1016.           if SelLength > 0 then ClearSelection;
  1017.         end;
  1018.       end;
  1019.     #13:                                  //∩σ≡σ⌡εΣΦ∞ φα ±δσΣ≤■∙ΦΘ Ωεφ≥≡εδⁿ!
  1020.       if not FDroppedDown then
  1021.         if EnterAsTab then
  1022.         begin
  1023.           Key := #0;
  1024.           if Parent is TCustomForm then     //≥.Ω. Σδ  TabSheet φσ ≡αßε≥ασ≥!!!!!!!!
  1025.             PostMessage(Parent.Handle, WM_NEXTDLGCTL, 0, 0)
  1026.           else if Owner is TCustomForm then
  1027.             PostMessage(TWinControl(Owner).Handle, WM_NEXTDLGCTL, 0, 0);
  1028.         end
  1029.         else GetParentForm(Self).Perform(CM_DIALOGKEY, 13, 0);  //Γ√τεΓ Default-Ωφε∩ΩΦ
  1030.     #27:
  1031.       begin
  1032.         Reset;
  1033.         Key := #0;
  1034.       end;
  1035.   end;
  1036. end;
  1037.  
  1038. procedure TVolgaDBEdit.CalSelectDate(Sender: TObject);
  1039. begin
  1040.   CloseUp(true);
  1041. end;
  1042.  
  1043. procedure TVolgaDBEdit.ListMouseUp(Sender: TObject; Button: TMouseButton;
  1044.   Shift: TShiftState; X, Y: Integer);
  1045. var TreeButton: Boolean;
  1046. begin  //εß≡αßε≥≈ΦΩ OnMouseUp Σδ  Γ√∩αΣα■∙Φ⌡ Ωεφ≥≡εδσΘ
  1047.   TreeButton := Assigned(FActiveList) and (FActiveList = FTreeList);
  1048.   if TreeButton then
  1049.     TreeButton := (htOnButton in FTreeList.GetHitTestInfoAt(X, Y));
  1050.   if (Button = mbLeft) and not TreeButton then
  1051.     CloseUp(PtInRect(FActiveList.ClientRect, Point(X, Y)));
  1052. end;
  1053.  
  1054. procedure TVolgaDBEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1055.   X, Y: Integer);
  1056. begin
  1057.   if (Button = mbLeft) and (FDialogStyle <> vdsEdit) and
  1058.     (OverButton(Point(X, Y)) or (Style = vcsDropDownList)) then //ΩδΦΩ φαΣ Ωφε∩ΩεΘ
  1059.   begin
  1060.     if FDroppedDown then
  1061.       CloseUp(False)                      //ταΩ≡√≥ⁿ Γ√∩αΣ.Ωεφ≥≡εδⁿ
  1062.     else
  1063.     begin
  1064.       MouseCapture := True;
  1065.       FTracking := True;                  //∞√°ⁿ φαµα≥α
  1066.       TrackButton(X, Y);                  //∩σ≡σ≡Φ±εΓα≥ⁿ Ωφε∩Ω≤ φαµα≥εΘ
  1067.       if Assigned(FActiveList) then
  1068.         DropDown;                         //ε≥Ω≡√≥ⁿ Γ√∩αΣ.Ωεφ≥≡εδⁿ
  1069.     end;
  1070.   end;
  1071.   inherited MouseDown(Button, Shift, X, Y);
  1072. end;
  1073.  
  1074. procedure TVolgaDBEdit.MouseMove(Shift: TShiftState; X, Y: Integer);
  1075. var
  1076.   ListPos: TPoint;
  1077.   MousePos: TSmallPoint;
  1078. begin
  1079.   if FTracking then                       //∞√°ⁿ ß√δα φαµα≥α?
  1080.   begin
  1081.     TrackButton(X, Y); //∩σ≡σ≡Φ±εΓα≥ⁿ Ωφε∩Ω≤ φαµα≥εΘ/ε≥µα≥εΘ Γ ταΓΦ±Φ∞ε±≥Φ ε≥ Ωεε≡ΣΦφα≥√ ≥ε≈ΩΦ
  1082.     if FDroppedDown then
  1083.     begin
  1084.       ListPos := FActiveList.ScreenToClient(ClientToScreen(Point(X, Y)));
  1085.       if PtInRect(FActiveList.ClientRect, ListPos) then
  1086.       begin                               //σ±δΦ φαµαδΦ Γ εßδα±≥Φ Γ√∩αΣα■∙σπε Ωεφ≥≡εδ 
  1087.         StopTracking;                     //≡Φ±±≤σ∞ Ωφε∩Ω≤ ε≥µα≥εΘ
  1088.         MousePos := PointToSmallPoint(ListPos);
  1089.         //∩ε±√δασ∞ ∞σ±±απ≤ ε φαµα≥ΦΦ φα εßδα±≥ⁿ Γ√∩αΣα■∙σπε Ωεφ≥≡εδ 
  1090.         SendMessage(FActiveList.Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
  1091.         Exit;
  1092.       end;
  1093.     end;
  1094.   end;
  1095.   inherited MouseMove(Shift, X, Y);
  1096. end;
  1097.  
  1098. procedure TVolgaDBEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
  1099.   X, Y: Integer);
  1100. var
  1101.   WasPressed: Boolean;
  1102. begin
  1103.   WasPressed := FPressed;                 //Ωφε∩Ωα ß√δα φαµα≥α/φσ≥
  1104.   StopTracking;                           //ε≥µα≥ⁿ Ωφε∩Ω≤
  1105.   if (Button = mbLeft) and (FDialogStyle = vdsCustomDlg) and WasPressed then
  1106.     if Assigned(FOnCustomDlg) then FOnCustomDlg(self);  //φαµα≥α Ωφε∩Ωα ∩≡εΦτΓ.≡σΣαΩ≥Φ≡εΓαφΦ 
  1107.   inherited MouseUp(Button, Shift, X, Y);
  1108. end;
  1109.  
  1110. procedure TVolgaDBEdit.StopTracking;
  1111. begin
  1112.   if FTracking then
  1113.   begin
  1114.     TrackButton(-1, -1);                  //∩σ≡σ≡Φ±εΓα≥ⁿ Ωφε∩Ω≤ ε≥µα≥εΘ
  1115.     FTracking := False;
  1116.     MouseCapture := False;
  1117.   end;
  1118. end;
  1119.  
  1120. procedure TVolgaDBEdit.TrackButton(X, Y: Integer);
  1121. var //∩≡εΓσ≡Ωα, φαΣε δΦ ∩σ≡σ≡Φ±εΓα≥ⁿ Ωφε∩Ω≤ φαµα≥εΘ/ε≥µα≥εΘ
  1122.   NewState: Boolean;
  1123.   R: TRect;
  1124. begin
  1125.   R := ButtonRect;                        //τΣσ±ⁿ φα°α Ωφε∩Ωα
  1126.   NewState := PtInRect(R, Point(X, Y));   //²≥α ≥ε≈Ωα φα Ωφε∩Ωσ?
  1127.   if FPressed <> NewState then //σ±δΦ φαµαδΦ φα Ωφε∩Ωσ, α Ωφε∩Ωα ß√δα ε≥µα≥α ΦδΦ φαεßε≡ε≥
  1128.   begin
  1129.     FPressed := NewState;
  1130.     InvalidateRect(Handle, @R, False);    //∩σ≡σ≡Φ±εΓα≥ⁿ Ωφε∩Ω≤ Γ φεΓε∞ ±ε±≥ε φΦΦ
  1131.   end;
  1132. end;
  1133.  
  1134. function TVolgaDBEdit.OverButton(const P: TPoint): Boolean;
  1135. begin
  1136.   Result := PtInRect(ButtonRect, P);
  1137. end;
  1138.  
  1139. procedure TVolgaDBEdit.WMLButtonDblClk(var Message: TWMLButtonDblClk);
  1140. begin
  1141.   with Message do
  1142.     if (FDialogStyle <> vdsEdit) and OverButton(Point(XPos, YPos)) then
  1143.       Exit;
  1144.   inherited;
  1145. end;
  1146.  
  1147. procedure TVolgaDBEdit.WMSetCursor(var Message: TWMSetCursor);
  1148. var
  1149.   P: TPoint;
  1150. begin                                     //⌠ε≡∞α Ω≤≡±ε≡α φαΣ Ωφε∩ΩεΘ - ∩αδσ÷
  1151.   GetCursorPos(P);
  1152.   P := ScreenToClient(P);
  1153.   if not (csDesigning in ComponentState) and (FDialogStyle <> vdsEdit)
  1154.     and (OverButton(P) or (Style = vcsDropDownList)) then
  1155.     Windows.SetCursor(Screen.Cursors[crHandPoint])
  1156.   else
  1157.     inherited;
  1158. end;
  1159.  
  1160. procedure TVolgaDBEdit.WndProc(var Message: TMessage);
  1161. var DC: HDC;
  1162.     PS: TPaintStruct;
  1163. begin
  1164.   case Message.Msg of
  1165.     WM_KEYDOWN, WM_SYSKEYDOWN, WM_CHAR:
  1166.       if DialogStyle in [vdsCombo, vdsLookup, vdsCalendar, vdsTree] then
  1167.         with TWMKey(Message) do
  1168.         begin
  1169.           DoDropDownKeys(CharCode, KeyDataToShiftState(KeyData));
  1170.           if (Message.Msg = wm_Char) and (CharCode > 32) and FAutoDrop and not
  1171.             FDroppedDown and (DialogStyle in [vdsCombo, vdsLookup]) then
  1172.             DropDown; //Γ√∩αΣασ∞, σ±δΦ ≤±≥αφεΓδσφε AutoDropDown Φ φαµα≥α ß≤ΩΓα
  1173.           if (CharCode <> 0) and FDroppedDown then
  1174.           begin
  1175.             with TMessage(Message) do //∩σ≡σφα∩≡αΓδ σ∞ ±Φ∞Γεδ Γ√∩αΣ.Ωεφ≥≡εδ■ Σδ  ∩≡εΓσΣσφΦ  ∩εΦ±Ωα
  1176.               SendMessage(FActiveList.Handle, Msg, WParam, LParam);
  1177.           end;
  1178.         end;
  1179.     WM_SETTEXT:
  1180.       ;
  1181.     WM_PAINT:
  1182.       if DialogStyle <> vdsEdit then begin
  1183.         DC := TWMPaint(Message).DC;
  1184.         if DC = 0 then DC := BeginPaint(Handle, PS);
  1185.         try
  1186.           PaintWindow(DC);
  1187.         finally
  1188.           if TWMPaint(Message).DC = 0 then EndPaint(Handle, PS);
  1189.         end;
  1190.       end;
  1191.   end;
  1192.   inherited;
  1193. end;
  1194.  
  1195. procedure TVolgaDBEdit.Loaded;
  1196. begin
  1197.   inherited Loaded;
  1198.   if (csDesigning in ComponentState) then DataChange(Self);
  1199.   Invalidate;
  1200. end;
  1201.  
  1202. procedure TVolgaDBEdit.WMSetFocus(var Message: TWMSetFocus);
  1203. begin
  1204.   inherited;
  1205.   Invalidate;
  1206. end;
  1207.  
  1208. procedure TVolgaDBEdit.Reset;
  1209. begin
  1210.   if DBLinked then
  1211.     FDataLink.Reset;                      //Φπφε≡Φ≡≤σ∞ Γ±σ ∩≡σΣ√Σ≤∙Φσ Φτ∞σφσφΦ  Γ ∩εδσ
  1212.   SelectAll;
  1213. end;
  1214.  
  1215. procedure TVolgaDBEdit.SetFocused(Value: Boolean);
  1216. begin
  1217.   if FFocused <> Value then
  1218.   begin
  1219.     FFocused := Value;
  1220.     if (FAlignment <> taLeftJustify) and not IsMasked then Invalidate;
  1221.     if DBLinked then FDataLink.Reset;
  1222.   end;
  1223. end;
  1224.  
  1225. procedure TVolgaDBEdit.Change;
  1226. begin
  1227.   if DBLinked and FDataLink.DataSet.CanModify then FDataLink.Modified;
  1228.   if Modified and not FDroppedDown then
  1229.     if Text > '' then
  1230.       FValue := Text
  1231.     else
  1232.       FValue := ClearValue;
  1233.   inherited Change;
  1234. end;
  1235.  
  1236. function TVolgaDBEdit.GetDataSource: TDataSource;
  1237. begin
  1238.   Result := FDataLink.DataSource;
  1239. end;
  1240.  
  1241. procedure TVolgaDBEdit.SetDataSource(Value: TDataSource);
  1242. begin
  1243.   if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
  1244.     FDataLink.DataSource := Value;
  1245.   if Value <> nil then Value.FreeNotification(Self);
  1246.   CheckDB;
  1247. end;
  1248.  
  1249. function TVolgaDBEdit.GetDataField: string;
  1250. begin
  1251.   Result := FDataLink.FieldName;
  1252. end;
  1253.  
  1254. procedure TVolgaDBEdit.SetDataField(const Value: string);
  1255. begin
  1256.   if Value > '' then
  1257.     FDataLink.FieldName := Value;
  1258.   CheckDB;
  1259. end;
  1260.  
  1261. procedure TVolgaDBEdit.CheckDB;
  1262. begin
  1263.   if (FDataLink.Field <> nil) and (FDataLink.DataSource <> nil) then
  1264.   begin
  1265.     ReadOnly := FDataLink.ReadOnly;
  1266.     Alignment := FDataLink.Field.Alignment;
  1267.     //Σδ  lookup-∩εδ  ∩≡ε±≥αΓδ σ∞ ∩εδ 
  1268.     if FDataLink.Field.FieldKind = fkLookup then begin
  1269.       DialogStyle := vdsLookup;
  1270.       LookupDataSet := FDataLink.Field.LookupDataSet;
  1271.       LookupProps.SourceKeyField := FDataLink.Field.KeyFields;
  1272.       LookupProps.LookupKeyField := FDataLink.Field.LookupKeyFields;
  1273.       LookupProps.ListFieldNames := FDataLink.Field.LookupResultField;
  1274.     end;
  1275.   end;
  1276. end;
  1277.  
  1278. procedure TVolgaDBEdit.DataChange(Sender: TObject);
  1279. begin
  1280.   VarClear(FValue);
  1281.   if DBLinked then
  1282.   begin
  1283.     //Σδ  Lookup ²≥ε ∩εδ  δΦφΩα!!!
  1284.     if (DialogStyle = vdsLookup) and (LookupProps.SourceKeyField>'') then
  1285.       FValue := FDatalink.DataSet.FieldValues[LookupProps.SourceKeyField]
  1286.     else FValue := FDataLink.Field.Value;
  1287.     EditMask := FDataLink.Field.EditMask;
  1288.     SetViewText(FValue, FDataLink.Field.DisplayText);    //≤±≥αφαΓδΦΓασ≥±  ±ΓεΘ±≥Γε Text!
  1289.   end
  1290.   else if csDesigning in ComponentState then
  1291.     SetViewText(Name, Name)
  1292.   else
  1293.     SetViewText('', '');
  1294.   if DBLinked and FDataLink.Dataset.CanModify and FDataLink.Editing {and FDataLink.FModified} then
  1295.     Modified := True;
  1296. end;
  1297.  
  1298. procedure TVolgaDBEdit.EditingChange(Sender: TObject);
  1299. begin
  1300.   if DBLinked then begin
  1301.     ReadOnly := not FDataLink.Editing;
  1302.   end;
  1303. end;
  1304.  
  1305. procedure TVolgaDBEdit.UpdateData(Sender: TObject);
  1306. begin //≤±≥αφεΓΦ≥ⁿ ∩ε Γ√ß≡αφφε∞≤ ≥σΩ±≥≤ ∩εδσ Γ Σα≥α±σ≥σ
  1307.   ValidateEdit;   //Validates the EditText against the current mask
  1308.   if Assigned(FOnUpdateData) then         //Φτ∞σφσφε calculated ∩εδσ!!!!!!!
  1309.     FOnUpdateData(self, Text)
  1310.   else if DBLinked then
  1311.     if (DialogStyle = vdsLookup) and (LookupProps.SourceKeyField>'') then begin  //∩εδ  δΦφΩα
  1312.       if VarIsNull(FValue) or VarIsEmpty(FValue) then
  1313.         FDataLink.DataSet.FieldByName(LookupProps.SourceKeyField).Clear
  1314.       else  //Φ±∩εδⁿτ≤σ∞ ±ΓεΘ±≥Γε Text, ≈≥εß√ ±≡αßε≥αδ OnSetText Σδ  ∩εδ 
  1315.         FDataLink.DataSet.FieldByName(LookupProps.SourceKeyField).Text := string(FValue);
  1316.       if (LookupProps.SourceKeyField <> DataField) and
  1317.       (FDataLink.Field.FieldKind = fkData) then
  1318.         FDataLink.Field.Text := Text;   //ΓΦΣΦ∞εσ ∩εδσ
  1319.     end else
  1320.       if not FDataLink.Field.Calculated then
  1321.         if VarIsNull(FValue) or VarIsEmpty(FValue) then
  1322.           FDataLink.Field.Clear
  1323.         else
  1324.           FDataLink.Field.Text := string(FValue);
  1325. end;
  1326.  
  1327. procedure TVolgaDBEdit.WMPaste(var Message: TMessage);
  1328. begin
  1329.   if not EditCanModify then Exit;
  1330.   if DBLinked then FDataLink.Edit;
  1331.   inherited;
  1332. end;
  1333.  
  1334. procedure TVolgaDBEdit.WMCut(var Message: TMessage);
  1335. begin
  1336.   if not EditCanModify then Exit;
  1337.   if DBLinked then FDataLink.Edit;
  1338.   inherited;
  1339. end;
  1340.  
  1341. procedure TVolgaDBEdit.CMEnter(var Message: TCMEnter);
  1342. begin
  1343.   SetFocused(True);
  1344.   inherited;
  1345.   if AutoSelect and not (csLButtonDown in ControlState) then SelectAll;
  1346. end;
  1347.  
  1348. procedure TVolgaDBEdit.CMExit(var Message: TCMExit);
  1349. begin
  1350.   try
  1351.     if DBLinked then FDataLink.UpdateRecord;
  1352.   except
  1353.     SelectAll;
  1354.     SetFocus;
  1355.     raise;
  1356.   end;
  1357.   SetFocused(False);
  1358.   CheckCursor;                            //Γ±≥ασ∞ φα Ωεφσ÷ ≡σΣαΩ≥Φ≡≤σ∞επε ∩εδ ?
  1359.   DoExit;
  1360. end;
  1361.  
  1362. procedure TVolgaDBEdit.CMGetDataLink(var Message: TMessage);
  1363. begin
  1364.   Message.Result := Integer(FDataLink);
  1365. end;
  1366.  
  1367. function TVolgaDBEdit.ExecuteAction(Action: TBasicAction): Boolean;
  1368. begin
  1369.   Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
  1370.     FDataLink.ExecuteAction(Action);
  1371. end;
  1372.  
  1373. function TVolgaDBEdit.UpdateAction(Action: TBasicAction): Boolean;
  1374. begin
  1375.   Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
  1376.     FDataLink.UpdateAction(Action);
  1377. end;
  1378.  
  1379. procedure TVolgaDBEdit.SetDialogStyle(const Value: TVolgaDialogStyle);
  1380. begin
  1381.   if FDialogStyle = Value then Exit;
  1382.   FDialogStyle := Value;
  1383.   FPrepared := false;
  1384.   if FDialogStyle<>vdsEdit then FAlignment := taLeftJustify;
  1385.   if (csDesigning in ComponentState) then DataChange(Self);
  1386.   Invalidate;
  1387. end;
  1388.  
  1389. procedure TVolgaDBEdit.CreateDropDownList;
  1390. begin
  1391.   if (csDestroying in ComponentState) then Exit;
  1392.   FPrepared := true;
  1393.   case FDialogStyle of
  1394.     vdsCombo:
  1395.       begin
  1396.         if FComboList = nil then
  1397.         begin
  1398.           FComboList := TVolgaListbox.Create(Self);
  1399.           FComboList.Visible := False;
  1400.           FComboList.Parent := Self;
  1401.           FComboList.OnMouseUp := ListMouseUp;
  1402.           FComboList.IntegralHeight := True;
  1403.           FComboList.ItemHeight := 11;
  1404.         end;
  1405.         FComboList.Color := Color;
  1406.         FComboList.Font := Font;
  1407.         FComboList.Items.Assign(ComboProps.ComboItems);
  1408.         if ComboProps.HasValues then
  1409.         begin
  1410.           Style := vcsDropDownList;
  1411.           FAutoDrop := true;
  1412.         end
  1413.         else
  1414.           Style := vcsDropDown;
  1415.         FActiveList := FComboList;
  1416.       end;
  1417.     vdsLookup:
  1418.       begin
  1419.         if FLookupList = nil then
  1420.         begin
  1421.           FLookupList := TPopupDataList.Create(Self); //Φτ DBCtrls.pas
  1422.           FLookupList.Visible := False;
  1423.           FLookupList.Parent := Self;
  1424.           FLookupList.OnMouseUp := ListMouseUp;
  1425.         end;
  1426.         FLookupList.Color := Color;
  1427.         FLookupList.Font := Font;
  1428.         FLookupList.RowCount := DropDownRows;
  1429.         FLookupList.KeyField := LookupProps.LookupKeyField;
  1430.         FLookupList.ListField := LookupProps.ListFieldNames;
  1431.         FLookupList.ListFieldIndex := LookupProps.ViewFieldIndex;
  1432.         FLookupSource.DataSet := LookupDataSet;
  1433.         FLookupList.ListSource := FLookupSource;
  1434.         LookupProps.PrepareLookup;
  1435.         if not IsLinkActive then FPrepared := false;  //φσ ≤Σαδε±ⁿ ∩εΣπε≥εΓΦ≥ⁿ!!!
  1436.         FActiveList := FLookupList;
  1437.       end;
  1438.     vdsCalendar:
  1439.       begin
  1440.         if FCalendar = nil then
  1441.         begin
  1442.           FCalendar := TVolgaDlgCalendar.Create(Self);
  1443.           FCalendar.Visible := False;
  1444.           FCalendar.Parent := Self;
  1445.           FCalendar.OnMouseUp := ListMouseUp;
  1446.           FCalendar.OnSelectDate := CalSelectDate;
  1447.         end;
  1448.         FActiveList := FCalendar;
  1449.       end;
  1450.     vdsTree:
  1451.       begin
  1452.         if FTreeList = nil then
  1453.         begin
  1454.           FTreeList := TVolgaPopupTree.Create(Self);
  1455.           FTreeList.Visible := False;
  1456.           FTreeList.Parent := Self;
  1457.           FTreeList.OnMouseUp := ListMouseUp;
  1458.         end;
  1459.         FTreeList.Color := Color;
  1460.         FTreeList.Font := Font;
  1461.         TreeProps.PrepareTree;
  1462.         if not IsLinkActive then FPrepared := false;  //φσ ≤Σαδε±ⁿ ∩εΣπε≥εΓΦ≥ⁿ!!!
  1463.         Style := vcsDropDownList;
  1464.         FActiveList := FTreeList;
  1465.       end;
  1466.   else
  1467.     FActiveList := nil;
  1468.   end;
  1469.   if FPrepared and DBLinked then
  1470.     if (DialogStyle = vdsLookup) and (LookupProps.SourceKeyField>'') then
  1471.       SetViewText(FDataLink.DataSet[LookupProps.SourceKeyField], FDataLink.Field.DisplayText)
  1472.     else
  1473.       SetViewText(FDataLink.Field.Value, FDataLink.Field.DisplayText);    //≤±≥αφαΓδΦΓασ≥±  ±ΓεΘ±≥Γε Text!
  1474.   Invalidate;
  1475. end;
  1476.  
  1477. function TVolgaDBEdit.GetComboProps: TVolgaComboProperties;
  1478. begin
  1479.   if FComboProps = nil then
  1480.     FComboProps := TVolgaComboProperties.Create(self);
  1481.   Result := FComboProps;
  1482. end;
  1483.  
  1484. procedure TVolgaDBEdit.SetComboProps(const Value: TVolgaComboProperties);
  1485. begin
  1486.   if Value = nil then
  1487.   begin
  1488.     FComboProps.Free;
  1489.     FComboProps := nil;
  1490.     Exit;
  1491.   end;
  1492.   FComboProps.ComboItems.Assign(Value.ComboItems);
  1493.   FComboProps.ComboValues.Assign(Value.ComboValues);
  1494.   FPrepared := false;
  1495. end;
  1496.  
  1497. function TVolgaDBEdit.GetLookupProps: TVolgaLookupProperties;
  1498. begin
  1499.   if FLookupProps = nil then
  1500.     FLookupProps := TVolgaLookupProperties.Create(self);
  1501.   Result := FLookupProps;
  1502. end;
  1503.  
  1504. procedure TVolgaDBEdit.SetLookupProps(const Value: TVolgaLookupProperties);
  1505. begin
  1506.   if Value = nil then
  1507.   begin
  1508.     FLookupProps.Free;
  1509.     FLookupProps := nil;
  1510.     Exit;
  1511.   end;
  1512.   FLookupProps.ViewFieldIndex := Value.ViewFieldIndex;
  1513.   FLookupProps.SourceKeyField := Value.SourceKeyField;
  1514.   FLookupProps.LookupKeyField := Value.LookupKeyField;
  1515.   FLookupProps.ListFieldNames := Value.ListFieldNames;
  1516.   FPrepared := false;
  1517. end;
  1518.  
  1519. function TVolgaDBEdit.GetTreeProps: TVolgaTreeProperties;
  1520. begin
  1521.   if FTreeProps = nil then
  1522.     FTreeProps := TVolgaTreeProperties.Create(self);
  1523.   Result := FTreeProps;
  1524. end;
  1525.  
  1526. procedure TVolgaDBEdit.SetTreeProps(const Value: TVolgaTreeProperties);
  1527. begin
  1528.   if Value = nil then
  1529.   begin
  1530.     FTreeProps.Free;
  1531.     FTreeProps := nil;
  1532.     Exit;
  1533.   end;
  1534.   FTreeProps.UniqueField := Value.UniqueField;
  1535.   FTreeProps.TextField := Value.TextField;
  1536.   FTreeProps.LevelField := Value.LevelField;
  1537.   FPrepared := false;
  1538. end;
  1539.  
  1540. procedure TVolgaDBEdit.SetValue(const Value: Variant);
  1541. begin
  1542.   if DBLinked then
  1543.     Exit //Σδ  Dataset-ε≡Φσφ≥Φ≡εΓαφφ√⌡ Ωεφ≥≡εδσΘ φσδⁿτ  ≤±≥αφεΓΦ≥ⁿ Value!!!!!!
  1544.   else
  1545.   begin
  1546.     FValue := Value;
  1547.     SetViewText(FValue, VarToStr(Value));         //≤±≥αφεΓΦ≥ⁿ ≥σΩ±≥ ∩ε Γ√ß≡αφφε∞≤ τφα≈σφΦ■
  1548.   end;
  1549. end;
  1550.  
  1551. function TVolgaDBEdit.DBLinked: Boolean;
  1552. begin
  1553.   Result := (FDataLink.Field <> nil) and FDataLink.Active;
  1554. end;
  1555.  
  1556. procedure TVolgaDBEdit.SetLookupDataSet(const Value: TDataSet);
  1557. begin
  1558. //  CheckInactive;
  1559.   if (Value <> nil) and (FDataLink.Field <> nil) and (Value = FDataLink.DataSet) then
  1560.     DatabaseError(V_LOOKUPSOURCEERROR, Self);
  1561.   FLookupDataSet := Value;
  1562. end;
  1563.  
  1564. function TVolgaDBEdit.IsLinkActive: Boolean;
  1565. begin
  1566.   try
  1567.     Result := (LookupDataSet <> nil) and LookupDataSet.Active;
  1568.     if Result then
  1569.       if FDialogStyle=vdsLookup then
  1570.         Result := (FLookupProps.LookupKeyField > '') and (FLookupProps.ListFieldNames >'')
  1571.       else if FDialogStyle=vdsTree then
  1572.         Result := (FTreeProps.TextField > '') and (FTreeProps.UniqueField >'')
  1573.         and (FTreeProps.LevelField > '');
  1574.   except Result := false; end;
  1575. end;
  1576.  
  1577. function TVolgaDBEdit.GetItemIndex: integer;
  1578. begin
  1579.   Result := -1;
  1580.   if Assigned(FActiveList) then
  1581.   begin
  1582.     if (FActiveList = FLookupList) and (FLookupList.SelectedItem > '')
  1583.     and FLookupDataSet.IsSequenced then
  1584.       Result := FLookupDataSet.RecNo - 1
  1585.     else if (FActiveList = FTreeList) and (FTreeList.Selected <> nil) then
  1586.       Result := FTreeList.Selected.AbsoluteIndex
  1587.     else if FActiveList = FComboList then
  1588.       Result := FComboList.ItemIndex;
  1589.   end;
  1590. end;
  1591.  
  1592. procedure TVolgaDBEdit.SetItemIndex(const AValue: integer);
  1593. var tekvalue: Variant;
  1594. begin
  1595.   if DBLinked then
  1596.     Exit //Σδ  Dataset-ε≡Φσφ≥Φ≡εΓαφφ√⌡ Ωεφ≥≡εδσΘ φσδⁿτ  ≤±≥αφεΓΦ≥ⁿ ItemIndex
  1597.   else
  1598.   begin
  1599.     if Assigned(FActiveList) then
  1600.     begin
  1601.       tekvalue := NULL;
  1602.       if AValue >= 0 then
  1603.       try
  1604.         if FActiveList = FComboList then begin
  1605.           if ComboProps.HasValues then
  1606.             tekvalue := ComboProps.ComboValues[AValue]
  1607.           else
  1608.             tekvalue := ComboProps.ComboItems[AValue];
  1609.           FComboList.ItemIndex := AValue;
  1610.         end
  1611.         else if FActiveList = FLookupList then
  1612.           if FLookupDataSet.IsSequenced then begin
  1613.             FLookupDataSet.RecNo := AValue + 1;
  1614.             tekvalue := FLookupDataSet.FieldValues[LookupProps.LookupKeyField];
  1615.           end else
  1616.         else if FActiveList = FTreeList then begin
  1617.           tekvalue := PShortString(FTreeList.Items[AValue].Data)^;
  1618.           FTreeList.Items[AValue].Selected := true;
  1619.         end;
  1620.       except ; end;
  1621.       if tekvalue <> NULL then begin
  1622.         FValue := tekvalue;
  1623.         SetViewText(FValue, VarToStr(FValue));
  1624.       end;
  1625.     end;
  1626.   end;
  1627. end;
  1628.  
  1629. procedure TVolgaDBEdit.SetAlignment(const Value: TAlignment);
  1630. begin
  1631.   if FDialogStyle = vdsEdit then
  1632.     FAlignment := Value
  1633.   else FAlignment := taLeftJustify;
  1634.   Invalidate;
  1635. end;
  1636.  
  1637. procedure TVolgaDBEdit.SetButtonWidth(const Value: integer);
  1638. begin
  1639.   if (Value > 4) and (Value < Round(Width/2)) then
  1640.     FButtonWidth := Value;
  1641.   Invalidate;
  1642. end;
  1643.  
  1644. procedure TVolgaDBEdit.CMDialogKey(var Message: TCMDialogKey);
  1645. begin
  1646.   Broadcast(Message);
  1647. end;
  1648.  
  1649. { TVolgaComboProperties }
  1650.  
  1651. constructor TVolgaComboProperties.Create(AOwner: TComponent);
  1652. begin
  1653.   inherited Create;
  1654.   if AOwner is TVolgaDBEdit then
  1655.     FOwner := TVolgaDBEdit(AOwner)
  1656.   else
  1657.     FOwner := nil;
  1658. end;
  1659.  
  1660. destructor TVolgaComboProperties.Destroy;
  1661. begin
  1662.   if FItems <> nil then FItems.Free;
  1663.   FItems := nil;
  1664.   if FValues <> nil then FValues.Free;
  1665.   FValues := nil;
  1666.   inherited Destroy;
  1667. end;
  1668.  
  1669. procedure TVolgaComboProperties.AssignList(const AList: TStrings);
  1670. var i:integer;
  1671. begin //∩≡Φ±ΓεΦ≥ⁿ ±≡ατ≤ Items Φ Values Φτ ±∩Φ±Ωα ≥Φ∩α Name=Value
  1672.   if FItems = nil then
  1673.     FItems := TStringList.Create
  1674.   else FItems.Clear;
  1675.   if FValues = nil then
  1676.     FValues := TStringList.Create
  1677.   else FValues.Clear;
  1678.   for i := 0 to AList.Count-1 do begin
  1679.     FItems.Add(AList.Names[i]);
  1680.     FValues.Add(AList.Values[AList.Names[i]]);
  1681.   end;
  1682.   if Assigned(FOwner) then FOwner.FPrepared := false;
  1683. end;
  1684.  
  1685. function TVolgaComboProperties.GetComboItems: TStrings;
  1686. begin
  1687.   if FItems = nil then
  1688.     FItems := TStringList.Create;
  1689.   Result := FItems;
  1690. end;
  1691.  
  1692. function TVolgaComboProperties.GetComboValues: TStrings;
  1693. begin
  1694.   if FValues = nil then
  1695.     FValues := TStringList.Create;
  1696.   Result := FValues;
  1697. end;
  1698.  
  1699. function TVolgaComboProperties.GetHasValues: Boolean;
  1700. begin
  1701.   Result := (FValues <> nil) and (FValues.Count = FItems.Count);
  1702. end;
  1703.  
  1704. procedure TVolgaComboProperties.SetComboItems(const Value: TStrings);
  1705. begin
  1706.   if Value = nil then
  1707.   begin
  1708.     FItems.Free;
  1709.     FItems := nil;
  1710.     Exit;
  1711.   end;
  1712.   FItems.Assign(Value);
  1713.   if Assigned(FOwner) then FOwner.FPrepared := false;
  1714. end;
  1715.  
  1716. procedure TVolgaComboProperties.SetComboValues(const Value: TStrings);
  1717. begin
  1718.   if Value = nil then
  1719.   begin
  1720.     FValues.Free;
  1721.     FValues := nil;
  1722.     Exit;
  1723.   end;
  1724.   FValues.Assign(Value);
  1725.   if Assigned(FOwner) then FOwner.FPrepared := false;
  1726. end;
  1727.  
  1728. { TVolgaLookupProperties }
  1729.  
  1730. constructor TVolgaLookupProperties.Create(AOwner: TComponent);
  1731. begin
  1732.   inherited Create;
  1733.   if AOwner is TVolgaDBEdit then
  1734.     FOwner := TVolgaDBEdit(AOwner)
  1735.   else
  1736.     FOwner := nil;
  1737.   FListFieldIndex := 0;
  1738.   FLFields := TList.Create;
  1739. end;
  1740.  
  1741. destructor TVolgaLookupProperties.Destroy;
  1742. begin
  1743.   FLFields.Free;
  1744.   inherited Destroy;
  1745. end;
  1746.  
  1747. function TVolgaLookupProperties.GetViewField: string;
  1748. begin
  1749.   if FLFields.Count = 0 then PrepareLookup;
  1750.   Result := TField(FLFields[ViewFieldIndex]).FieldName;
  1751. end;
  1752.  
  1753. procedure TVolgaLookupProperties.PrepareLookup;
  1754. begin
  1755.   if (FListFieldNames > '') and (FOwner.LookupDataSet <> nil) then
  1756.   try
  1757.     if FOwner.DBLinked or not (csDesigning in FOwner.ComponentState) then
  1758.       if not FOwner.LookupDataSet.Active then FOwner.LookupDataSet.Open;
  1759.     FOwner.LookupDataSet.GetFieldList(FLFields, FListFieldNames);
  1760.   except; end;
  1761. end;
  1762.  
  1763. procedure TVolgaLookupProperties.SetLookupKeyField(const Value: string);
  1764. begin
  1765.   FLookupKeyField := Value;
  1766.   if Assigned(FOwner) then FOwner.FPrepared := false;
  1767. end;
  1768.  
  1769. procedure TVolgaLookupProperties.SetListFieldNames(const Value: string);
  1770. begin
  1771.   FListFieldNames := Value;
  1772.   if Assigned(FOwner) then FOwner.FPrepared := false;
  1773. end;
  1774.  
  1775. procedure TVolgaLookupProperties.SetSourceKeyField(const Value: string);
  1776. begin
  1777.   FSourceKeyField := Value;
  1778.   if Assigned(FOwner) then FOwner.FPrepared := false;
  1779. end;
  1780.  
  1781. { TVolgaTreeProperties }
  1782.  
  1783. constructor TVolgaTreeProperties.Create(AOwner: TComponent);
  1784. begin
  1785.   inherited Create;
  1786.   if AOwner is TVolgaDBEdit then
  1787.     FOwner := TVolgaDBEdit(AOwner)
  1788.   else
  1789.     FOwner := nil;
  1790.   FSeparator := '/';
  1791. end;
  1792.  
  1793. procedure TVolgaTreeProperties.PrepareTree;
  1794. var ActNode1, ActNode2, ActNode3, ActNode4, ActNode5, ActNode6: TTreeNode;
  1795.   ptrUID: PShortString;
  1796. begin
  1797.   if (FTextField = '') or (FUniqueField = '') or (FLevelField = '')
  1798.     or (FOwner = nil) or not Assigned(FOwner.LookupDataset) then Exit;
  1799.   if not FOwner.LookupDataSet.Active then
  1800.   try FOwner.LookupDataSet.Open;
  1801.   except Exit; end;
  1802.   if FOwner.FTreeList = nil then Exit;
  1803.   with FOwner.FTreeList, FOwner.LookupDataSet do
  1804.   begin                                   {±ετΣα≥ⁿ Σσ≡σΓε Φτ ≥αßδΦ÷√}
  1805.     ActNode1 := nil; ActNode2 := nil; ActNode3 := nil;
  1806.     ActNode4 := nil; ActNode5 := nil; ActNode6 := nil;
  1807.     Items.Clear;
  1808.     //═σ ≡Φ±εΓα≥ⁿ TreeView ∩εΩα φσ Γφσ±σφ√ Γ±σ Φτ∞σφσφΦ 
  1809.     Items.BeginUpdate;
  1810.     DisableControls;
  1811.     First; //±≈Φ≥ασ∞, ≈≥ε ≥αßδΦ÷α ≤∩ε≡ Σε≈σφα ∩ε ∩εδ■ IndexField!!!!!!!!!!
  1812.     while not Eof do
  1813.     begin
  1814.       New(ptrUID);
  1815.       ptrUID^ := FieldByName(UniqueField).AsString;
  1816.       if FieldByName(LevelField).AsInteger = 1 then {φσ Σε≈σ≡φ   φΦ Ω ≈σ∞≤}
  1817.         ActNode1 := Items.AddObject(nil, FieldByName(TextField).AsString, ptrUID)
  1818.       else if FieldByName(LevelField).AsInteger = 2 then
  1819.         ActNode2 := Items.AddChildObject(ActNode1, FieldByName(TextField).AsString,
  1820.           ptrUID)
  1821.       else if FieldByName(LevelField).AsInteger = 3 then
  1822.         ActNode3 := Items.AddChildObject(ActNode2, FieldByName(TextField).AsString,
  1823.           ptrUID)
  1824.       else if FieldByName(LevelField).AsInteger = 4 then
  1825.         ActNode4 := Items.AddChildObject(ActNode3, FieldByName(TextField).AsString,
  1826.           ptrUID)
  1827.       else if FieldByName(LevelField).AsInteger = 5 then
  1828.         ActNode5 := Items.AddChildObject(ActNode4, FieldByName(TextField).AsString,
  1829.           ptrUID)
  1830.       else if FieldByName(LevelField).AsInteger = 6 then
  1831.         ActNode6 := Items.AddChildObject(ActNode5, FieldByName(TextField).AsString,
  1832.           ptrUID)
  1833.       else
  1834.         Items.AddChildObject(ActNode6, FieldByName(TextField).AsString, ptrUID);
  1835.       Next;
  1836.     end;
  1837.     EnableControls;
  1838.     // ≥σ∩σ≡ⁿ φα≡Φ±εΓα≥ⁿ TTreeView ∩ε±δσ ταπ≡≤τΩΦ Γ±σ⌡ Σαφφ√⌡
  1839.     Items.EndUpdate;
  1840.   end;
  1841. end;
  1842.  
  1843. end.
  1844.  
  1845.