ToolEdit.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:70k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9. unit ToolEdit;
  10. interface
  11. {$I RX.INC}
  12. uses Windows, RTLConsts, Variants, Classes,
  13.   StdCtrls, Controls, Messages, SysUtils, Forms, Graphics, Menus, Buttons,
  14.   Dialogs, RxCtrls, FileCtrl, Mask, DateUtil;
  15. const
  16.   scAltDown = scAlt + vk_Down;
  17.   DefEditBtnWidth = 21;
  18. type
  19. {$IFDEF WIN32}
  20.   TFileExt = type string;
  21. {$ENDIF}
  22. { TPopupWindow }
  23.   TCloseUpEvent = procedure (Sender: TObject; Accept: Boolean) of object;
  24.   TPopupAlign = (epaRight, epaLeft);
  25.   TPopupWindow = class(TCustomControl)
  26.   private
  27.     FEditor: TWinControl;
  28.     FCloseUp: TCloseUpEvent;
  29.     procedure WMMouseActivate(var Message: TMessage); message WM_MOUSEACTIVATE;
  30.   protected
  31.     procedure CreateParams(var Params: TCreateParams); override;
  32. {$IFDEF WIN32}
  33.     function GetValue: Variant; virtual; abstract;
  34.     procedure SetValue(const Value: Variant); virtual; abstract;
  35. {$ELSE}
  36.     procedure CreateWnd; override;
  37.     function GetValue: string; virtual; abstract;
  38.     procedure SetValue(const Value: string); virtual; abstract;
  39. {$ENDIF}
  40.     procedure InvalidateEditor;
  41.     procedure PopupMouseUp(Sender: TObject; Button: TMouseButton;
  42.       Shift: TShiftState; X, Y: Integer);
  43.     procedure CloseUp(Accept: Boolean); virtual;
  44.   public
  45.     constructor Create(AOwner: TComponent); override;
  46.     function GetPopupText: string; virtual;
  47.     procedure Hide;
  48.     procedure Show(Origin: TPoint);
  49.     property OnCloseUp: TCloseUpEvent read FCloseUp write FCloseUp;
  50.   end;
  51. { TCustomComboEdit }
  52.   TEditButton = class(TRxSpeedButton)
  53.   private
  54.     FNoAction: Boolean;
  55.   protected
  56.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  57.       X, Y: Integer); override;
  58. {$IFDEF WIN32}
  59.     procedure Paint; override;
  60. {$ENDIF WIN32}
  61.   public
  62.     constructor Create(AOwner: TComponent); override;
  63.     procedure Click; override;
  64.   end;
  65.   TGlyphKind = (gkCustom, gkDefault, gkDropDown, gkEllipsis);
  66.   TCustomComboEdit = class(TCustomMaskEdit)
  67.   private
  68.     FButton: TEditButton;
  69.     FBtnControl: TWinControl;
  70.     FOnButtonClick: TNotifyEvent;
  71.     FClickKey: TShortCut;
  72.     FReadOnly: Boolean;
  73.     FDirectInput: Boolean;
  74.     FAlwaysEnable: Boolean;
  75.     FAlignment: TAlignment;
  76.     FPopupVisible: Boolean;
  77.     FFocused: Boolean;
  78.     FPopupAlign: TPopupAlign;
  79.     FGlyphKind: TGlyphKind;
  80.     procedure SetEditRect;
  81.     procedure RecreateGlyph;
  82.     procedure UpdateBtnBounds;
  83.     procedure EditButtonClick(Sender: TObject);
  84.     function GetMinHeight: Integer;
  85.     function GetTextHeight: Integer;
  86.     procedure SetShowCaret;
  87.     function GetGlyph: TBitmap;
  88.     procedure SetGlyph(Value: TBitmap);
  89.     function GetPopupVisible: Boolean;
  90.     function GetNumGlyphs: TNumGlyphs;
  91.     procedure SetNumGlyphs(Value: TNumGlyphs);
  92.     function GetButtonWidth: Integer;
  93.     procedure SetButtonWidth(Value: Integer);
  94.     function GetButtonHint: string;
  95.     procedure SetButtonHint(const Value: string);
  96.     function GetDirectInput: Boolean;
  97.     procedure SetDirectInput(Value: Boolean);
  98.     procedure SetReadOnly(Value: Boolean);
  99.     procedure SetAlignment(Value: TAlignment);
  100.     function IsCustomGlyph: Boolean;
  101.     function BtnWidthStored: Boolean;
  102.     procedure SetGlyphKind(Value: TGlyphKind);
  103.     procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  104.     procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  105.     procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
  106.     procedure CMEnter(var Message: TMessage); message CM_ENTER;
  107.     procedure CNCtlColor(var Message: TMessage); message
  108.       {$IFDEF WIN32} CN_CTLCOLOREDIT {$ELSE} CN_CTLCOLOR {$ENDIF};
  109.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  110.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  111.     procedure WMSetFocus(var Message: TMessage); message WM_SETFOCUS;
  112.     procedure WMPaste(var Message: TWMPaste); message WM_PASTE;
  113.     procedure WMCut(var Message: TWMCut); message WM_CUT;
  114. {$IFDEF WIN32}
  115.     procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
  116. {$ENDIF}
  117. {$IFDEF RX_D4}
  118.     procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED;
  119. {$ENDIF}
  120.   protected
  121.     FPopup: TCustomControl;
  122.     FDefNumGlyphs: TNumGlyphs;
  123.     function GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap; virtual;
  124.     procedure PopupDropDown(DisableEdit: Boolean); virtual;
  125.     procedure PopupCloseUp(Sender: TObject; Accept: Boolean);
  126.     procedure ShowPopup(Origin: TPoint); virtual;
  127.     procedure HidePopup; virtual;
  128.     procedure UpdatePopupVisible;
  129.     procedure DoChange;
  130. {$IFDEF WIN32}
  131.     function AcceptPopup(var Value: Variant): Boolean; virtual;
  132.     procedure AcceptValue(const Value: Variant); virtual;
  133.     procedure SetPopupValue(const Value: Variant); virtual;
  134.     function GetPopupValue: Variant; virtual;
  135. {$ELSE}
  136.     function AcceptPopup(var Value: string): Boolean; virtual;
  137.     procedure AcceptValue(const Value: string); virtual;
  138.     procedure SetPopupValue(const Value: string); virtual;
  139.     function GetPopupValue: string; virtual;
  140. {$ENDIF}
  141.     procedure Change; override;
  142.     procedure PopupChange; virtual;
  143.     procedure CreateParams(var Params: TCreateParams); override;
  144.     procedure CreateWnd; override;
  145.     function EditCanModify: Boolean; override;
  146.     function GetReadOnly: Boolean; virtual;
  147.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  148.     procedure KeyPress(var Key: Char); override;
  149.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  150.       X, Y: Integer); override;
  151.     procedure ButtonClick; dynamic;
  152.     property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  153.     property AlwaysEnable: Boolean read FAlwaysEnable write FAlwaysEnable default False;
  154.     property Button: TEditButton read FButton;
  155.     property ClickKey: TShortCut read FClickKey write FClickKey
  156.       default scAltDown;
  157.     property Glyph: TBitmap read GetGlyph write SetGlyph stored IsCustomGlyph;
  158.     property GlyphKind: TGlyphKind read FGlyphKind write SetGlyphKind default gkCustom;
  159.     property ButtonWidth: Integer read GetButtonWidth write SetButtonWidth
  160.       stored BtnWidthStored;
  161.     property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs;
  162.     property ButtonHint: string read GetButtonHint write SetButtonHint;
  163.     property DirectInput: Boolean read GetDirectInput write SetDirectInput default True;
  164.     property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  165.     property PopupAlign: TPopupAlign read FPopupAlign write FPopupAlign default epaRight;
  166.     property PopupVisible: Boolean read GetPopupVisible;
  167.     property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
  168.   public
  169.     constructor Create(AOwner: TComponent); override;
  170.     destructor Destroy; override;
  171.     procedure DoClick;
  172.     procedure SelectAll;
  173.   end;
  174. { TComboEdit }
  175.   TComboEdit = class(TCustomComboEdit)
  176.   public
  177.     property Button;
  178.   published
  179.     property Alignment;
  180.     property AutoSelect;
  181.     property BorderStyle;
  182.     property ButtonHint;
  183.     property CharCase;
  184.     property ClickKey;
  185.     property Color;
  186.     property Ctl3D;
  187.     property DirectInput;
  188.     property DragCursor;
  189.     property DragMode;
  190.     property EditMask;
  191.     property Enabled;
  192.     property Font;
  193.     property GlyphKind;
  194.     { Ensure GlyphKind is published before Glyph and ButtonWidth }
  195.     property Glyph;
  196.     property ButtonWidth;
  197.     property HideSelection;
  198. {$IFDEF RX_D4}
  199.     property Anchors;
  200.     property BiDiMode;
  201.     property Constraints;
  202.     property DragKind;
  203.     property ParentBiDiMode;
  204. {$ENDIF}
  205. {$IFDEF WIN32}
  206.   {$IFNDEF VER90}
  207.     property ImeMode;
  208.     property ImeName;
  209.   {$ENDIF}
  210. {$ENDIF}
  211.     property MaxLength;
  212.     property NumGlyphs;
  213.     property OEMConvert;
  214.     property ParentColor;
  215.     property ParentCtl3D;
  216.     property ParentFont;
  217.     property ParentShowHint;
  218.     property PopupMenu;
  219.     property ReadOnly;
  220.     property ShowHint;
  221.     property TabOrder;
  222.     property TabStop;
  223.     property Text;
  224.     property Visible;
  225.     property OnButtonClick;
  226.     property OnChange;
  227.     property OnClick;
  228.     property OnDblClick;
  229.     property OnDragDrop;
  230.     property OnDragOver;
  231.     property OnEndDrag;
  232.     property OnEnter;
  233.     property OnExit;
  234.     property OnKeyDown;
  235.     property OnKeyPress;
  236.     property OnKeyUp;
  237.     property OnMouseDown;
  238.     property OnMouseMove;
  239.     property OnMouseUp;
  240. {$IFDEF WIN32}
  241.     property OnStartDrag;
  242. {$ENDIF}
  243. {$IFDEF RX_D5}
  244.     property OnContextPopup;
  245. {$ENDIF}
  246. {$IFDEF RX_D4}
  247.     property OnEndDock;
  248.     property OnStartDock;
  249. {$ENDIF}
  250.   end;
  251. { TFileDirEdit }
  252. { The common parent of TFilenameEdit and TDirectoryEdit          }
  253. { For internal use only; it's not intended to be used separately }
  254. {$IFNDEF WIN32}
  255. const
  256.   MaxFileLength = SizeOf(TFileName) - 1;
  257. {$ENDIF}
  258. type
  259.   TExecOpenDialogEvent = procedure(Sender: TObject; var Name: string;
  260.     var Action: Boolean) of object;
  261.   TFileDirEdit = class(TCustomComboEdit)
  262.   private
  263.     FErrMode: Cardinal;
  264.     FAcceptFiles: Boolean;
  265.     FMultipleDirs: Boolean;
  266.     FOnDropFiles: TNotifyEvent;
  267.     FOnBeforeDialog: TExecOpenDialogEvent;
  268.     FOnAfterDialog: TExecOpenDialogEvent;
  269.     procedure SetDragAccept(Value: Boolean);
  270.     procedure SetAcceptFiles(Value: Boolean);
  271.     procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
  272.   protected
  273.     procedure CreateHandle; override;
  274.     procedure DestroyWindowHandle; override;
  275.     function GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap; override;
  276. {$IFDEF WIN32}
  277.     function GetLongName: string; virtual; abstract;
  278.     function GetShortName: string; virtual; abstract;
  279. {$ENDIF}
  280.     procedure DoAfterDialog(var FileName: string; var Action: Boolean); dynamic;
  281.     procedure DoBeforeDialog(var FileName: string; var Action: Boolean); dynamic;
  282.     procedure ReceptFileDir(const AFileName: string); virtual; abstract;
  283.     procedure ClearFileList; virtual;
  284.     procedure DisableSysErrors;
  285.     procedure EnableSysErrors;
  286.     property GlyphKind default gkDefault;
  287.     property MaxLength {$IFNDEF WIN32} default MaxFileLength {$ENDIF};
  288.   public
  289.     constructor Create(AOwner: TComponent); override;
  290. {$IFDEF WIN32}
  291.     property LongName: string read GetLongName;
  292.     property ShortName: string read GetShortName;
  293. {$ENDIF}
  294.   published
  295.     property AcceptFiles: Boolean read FAcceptFiles write SetAcceptFiles default False;
  296.     property OnBeforeDialog: TExecOpenDialogEvent read FOnBeforeDialog
  297.       write FOnBeforeDialog;
  298.     property OnAfterDialog: TExecOpenDialogEvent read FOnAfterDialog
  299.       write FOnAfterDialog;
  300.     property OnDropFiles: TNotifyEvent read FOnDropFiles write FOnDropFiles;
  301.     property OnButtonClick;
  302.   end;
  303. { TFilenameEdit }
  304.   TFileDialogKind = (dkOpen, dkSave {$IFDEF RX_D3}, dkOpenPicture,
  305.     dkSavePicture {$ENDIF});
  306.   TFilenameEdit = class(TFileDirEdit)
  307.   private
  308.     FDialog: TOpenDialog;
  309.     FDialogKind: TFileDialogKind;
  310.     procedure CreateEditDialog;
  311.     function GetFileName: string;
  312.     function GetDefaultExt: TFileExt;
  313.     function GetFileEditStyle: TFileEditStyle;
  314.     function GetFilter: string;
  315.     function GetFilterIndex: Integer;
  316.     function GetInitialDir: string;
  317.     function GetHistoryList: TStrings;
  318.     function GetOptions: TOpenOptions;
  319.     function GetDialogTitle: string;
  320.     function GetDialogFiles: TStrings;
  321.     procedure SetDialogKind(Value: TFileDialogKind);
  322.     procedure SetFileName(const Value: string);
  323.     procedure SetDefaultExt(Value: TFileExt);
  324.     procedure SetFileEditStyle(Value: TFileEditStyle);
  325.     procedure SetFilter(const Value: string);
  326.     procedure SetFilterIndex(Value: Integer);
  327.     procedure SetInitialDir(const Value: string);
  328.     procedure SetHistoryList(Value: TStrings);
  329.     procedure SetOptions(Value: TOpenOptions);
  330.     procedure SetDialogTitle(const Value: string);
  331.     function IsCustomTitle: Boolean;
  332.     function IsCustomFilter: Boolean;
  333.   protected
  334.     procedure ButtonClick; override;
  335.     procedure ReceptFileDir(const AFileName: string); override;
  336.     procedure ClearFileList; override;
  337. {$IFDEF WIN32}
  338.     function GetLongName: string; override;
  339.     function GetShortName: string; override;
  340. {$ENDIF}
  341.   public
  342.     constructor Create(AOwner: TComponent); override;
  343.     property Dialog: TOpenDialog read FDialog;
  344.     property DialogFiles: TStrings read GetDialogFiles;
  345.   published
  346.     property DialogKind: TFileDialogKind read FDialogKind write SetDialogKind
  347.       default dkOpen;
  348.     property DefaultExt: TFileExt read GetDefaultExt write SetDefaultExt;
  349.     property FileEditStyle: TFileEditStyle read GetFileEditStyle write SetFileEditStyle
  350.       default fsEdit;
  351.     property FileName: string read GetFileName write SetFileName stored False;
  352.     property Filter: string read GetFilter write SetFilter stored IsCustomFilter;
  353.     property FilterIndex: Integer read GetFilterIndex write SetFilterIndex default 1;
  354.     property InitialDir: string read GetInitialDir write SetInitialDir;
  355.     property HistoryList: TStrings read GetHistoryList write SetHistoryList;
  356.     property DialogOptions: TOpenOptions read GetOptions write SetOptions
  357.       default [ofHideReadOnly];
  358.     property DialogTitle: string read GetDialogTitle write SetDialogTitle
  359.       stored IsCustomTitle;
  360.     property AutoSelect;
  361.     property ButtonHint;
  362.     property BorderStyle;
  363.     property CharCase;
  364.     property ClickKey;
  365.     property Color;
  366.     property Ctl3D;
  367.     property DirectInput;
  368.     property DragCursor;
  369.     property DragMode;
  370.     property EditMask;
  371.     property Enabled;
  372.     property Font;
  373.     property GlyphKind;
  374.     { Ensure GlyphKind is declared before Glyph and ButtonWidth }
  375.     property Glyph;
  376.     property ButtonWidth;
  377.     property HideSelection;
  378. {$IFDEF RX_D4}
  379.     property Anchors;
  380.     property BiDiMode;
  381.     property Constraints;
  382.     property DragKind;
  383.     property ParentBiDiMode;
  384. {$ENDIF}
  385. {$IFDEF WIN32}
  386.   {$IFNDEF VER90}
  387.     property ImeMode;
  388.     property ImeName;
  389.   {$ENDIF}
  390. {$ENDIF}
  391.     property NumGlyphs;
  392.     property ParentColor;
  393.     property ParentCtl3D;
  394.     property ParentFont;
  395.     property ParentShowHint;
  396.     property PopupMenu;
  397.     property ReadOnly;
  398.     property ShowHint;
  399.     property TabOrder;
  400.     property TabStop;
  401.     property Text;
  402.     property Visible;
  403.     property OnChange;
  404.     property OnClick;
  405.     property OnDblClick;
  406.     property OnDragDrop;
  407.     property OnDragOver;
  408.     property OnEndDrag;
  409.     property OnEnter;
  410.     property OnExit;
  411.     property OnKeyDown;
  412.     property OnKeyPress;
  413.     property OnKeyUp;
  414.     property OnMouseDown;
  415.     property OnMouseMove;
  416.     property OnMouseUp;
  417. {$IFDEF WIN32}
  418.     property OnStartDrag;
  419. {$ENDIF}
  420. {$IFDEF RX_D5}
  421.     property OnContextPopup;
  422. {$ENDIF}
  423. {$IFDEF RX_D4}
  424.     property OnEndDock;
  425.     property OnStartDock;
  426. {$ENDIF}
  427.   end;
  428. { TDirectoryEdit }
  429. {$IFDEF WIN32}
  430.   TDirDialogKind = (dkVCL, dkWin32);
  431. {$ENDIF}
  432.   TDirectoryEdit = class(TFileDirEdit)
  433.   private
  434.     FOptions: TSelectDirOpts;
  435.     FInitialDir: string;
  436. {$IFDEF WIN32}
  437.     FDialogText: string;
  438.     FDialogKind: TDirDialogKind;
  439. {$ENDIF}
  440.   protected
  441.     procedure ButtonClick; override;
  442.     procedure ReceptFileDir(const AFileName: string); override;
  443. {$IFDEF WIN32}
  444.     function GetLongName: string; override;
  445.     function GetShortName: string; override;
  446. {$ENDIF}
  447.   public
  448.     constructor Create(AOwner: TComponent); override;
  449.   published
  450. {$IFDEF WIN32}
  451.     property DialogKind: TDirDialogKind read FDialogKind write FDialogKind
  452.       default dkVCL;
  453.     property DialogText: string read FDialogText write FDialogText;
  454. {$ENDIF}
  455.     property DialogOptions: TSelectDirOpts read FOptions write FOptions default [];
  456.     property InitialDir: string read FInitialDir write FInitialDir;
  457.     property MultipleDirs: Boolean read FMultipleDirs write FMultipleDirs default False;
  458.     property AutoSelect;
  459.     property ButtonHint;
  460.     property BorderStyle;
  461.     property CharCase;
  462.     property ClickKey;
  463.     property Color;
  464.     property Ctl3D;
  465.     property DirectInput;
  466.     property DragCursor;
  467.     property DragMode;
  468.     property EditMask;
  469.     property Enabled;
  470.     property Font;
  471.     property GlyphKind;
  472.     { Ensure GlyphKind is declared before Glyph and ButtonWidth }
  473.     property Glyph;
  474.     property NumGlyphs;
  475.     property ButtonWidth;
  476.     property HideSelection;
  477. {$IFDEF RX_D4}
  478.     property Anchors;
  479.     property BiDiMode;
  480.     property Constraints;
  481.     property DragKind;
  482.     property ParentBiDiMode;
  483. {$ENDIF}
  484. {$IFDEF WIN32}
  485.   {$IFNDEF VER90}
  486.     property ImeMode;
  487.     property ImeName;
  488.   {$ENDIF}
  489. {$ENDIF}
  490.     property ParentColor;
  491.     property ParentCtl3D;
  492.     property ParentFont;
  493.     property ParentShowHint;
  494.     property PopupMenu;
  495.     property ReadOnly;
  496.     property ShowHint;
  497.     property TabOrder;
  498.     property TabStop;
  499.     property Text;
  500.     property Visible;
  501.     property OnChange;
  502.     property OnClick;
  503.     property OnDblClick;
  504.     property OnDragDrop;
  505.     property OnDragOver;
  506.     property OnEndDrag;
  507.     property OnEnter;
  508.     property OnExit;
  509.     property OnKeyDown;
  510.     property OnKeyPress;
  511.     property OnKeyUp;
  512.     property OnMouseDown;
  513.     property OnMouseMove;
  514.     property OnMouseUp;
  515. {$IFDEF WIN32}
  516.     property OnStartDrag;
  517. {$ENDIF}
  518. {$IFDEF RX_D5}
  519.     property OnContextPopup;
  520. {$ENDIF}
  521. {$IFDEF RX_D4}
  522.     property OnEndDock;
  523.     property OnStartDock;
  524. {$ENDIF}
  525.   end;
  526. { TCustomDateEdit }
  527.   TCalendarStyle = (csPopup, csDialog);
  528.   TYearDigits = (dyDefault, dyFour, dyTwo);
  529. const
  530. {$IFDEF DEFAULT_POPUP_CALENDAR}
  531.   dcsDefault = csPopup;
  532. {$ELSE}
  533.   dcsDefault = csDialog;
  534. {$ENDIF DEFAULT_POPUP_CALENDAR}
  535. type
  536.   TExecDateDialog = procedure(Sender: TObject; var ADate: TDateTime;
  537.     var Action: Boolean) of object;
  538.   TCustomDateEdit = class(TCustomComboEdit)
  539.   private
  540.     FTitle: PString;
  541.     FOnAcceptDate: TExecDateDialog;
  542.     FDefaultToday: Boolean;
  543.     FHooked: Boolean;
  544.     FPopupColor: TColor;
  545.     FCheckOnExit: Boolean;
  546.     FBlanksChar: Char;
  547.     FCalendarHints: TStrings;
  548.     FStartOfWeek: TDayOfWeekName;
  549.     FWeekends: TDaysOfWeek;
  550.     FWeekendColor: TColor;
  551.     FYearDigits: TYearDigits;
  552.     FDateFormat: string[10];
  553.     FFormatting: Boolean;
  554.     function GetDate: TDateTime;
  555.     procedure SetDate(Value: TDateTime);
  556.     procedure SetYearDigits(Value: TYearDigits);
  557.     function GetPopupColor: TColor;
  558.     procedure SetPopupColor(Value: TColor);
  559.     function GetDialogTitle: string;
  560.     procedure SetDialogTitle(const Value: string);
  561.     function IsCustomTitle: Boolean;
  562.     function GetCalendarStyle: TCalendarStyle;
  563.     procedure SetCalendarStyle(Value: TCalendarStyle);
  564.     procedure SetCalendarHints(Value: TStrings);
  565.     procedure CalendarHintsChanged(Sender: TObject);
  566.     procedure SetWeekendColor(Value: TColor);
  567.     procedure SetWeekends(Value: TDaysOfWeek);
  568.     procedure SetStartOfWeek(Value: TDayOfWeekName);
  569.     procedure SetBlanksChar(Value: Char);
  570.     function TextStored: Boolean;
  571.     function FourDigitYear: Boolean;
  572.     function FormatSettingsChange(var Message: TMessage): Boolean;
  573.     procedure CMExit(var Message: TCMExit); message CM_EXIT;
  574.   protected
  575.     procedure Change; override;
  576.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  577.     procedure KeyPress(var Key: Char); override;
  578.     procedure CreateWindowHandle(const Params: TCreateParams); override;
  579.     procedure DestroyWindowHandle; override;
  580. {$IFDEF WIN32}
  581.     function AcceptPopup(var Value: Variant): Boolean; override;
  582.     procedure AcceptValue(const Value: Variant); override;
  583.     procedure SetPopupValue(const Value: Variant); override;
  584. {$ELSE}
  585.     function AcceptPopup(var Value: string): Boolean; override;
  586. {$ENDIF}
  587.     function GetDateFormat: string;
  588.     procedure ApplyDate(Value: TDateTime); virtual;
  589.     function GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap; override;
  590.     procedure UpdateFormat;
  591.     procedure UpdatePopup;
  592.     procedure ButtonClick; override;
  593.     property BlanksChar: Char read FBlanksChar write SetBlanksChar default ' ';
  594.     property CalendarHints: TStrings read FCalendarHints write SetCalendarHints;
  595.     property CheckOnExit: Boolean read FCheckOnExit write FCheckOnExit default False;
  596.     property DefaultToday: Boolean read FDefaultToday write FDefaultToday
  597.       default False;
  598.     property DialogTitle: string read GetDialogTitle write SetDialogTitle
  599.       stored IsCustomTitle;
  600.     property EditMask stored False;
  601.     property Formatting: Boolean read FFormatting;
  602.     property GlyphKind default gkDefault;
  603.     property PopupColor: TColor read GetPopupColor write SetPopupColor
  604.       default clBtnFace;
  605.     property CalendarStyle: TCalendarStyle read GetCalendarStyle
  606.       write SetCalendarStyle default dcsDefault;
  607.     property StartOfWeek: TDayOfWeekName read FStartOfWeek write SetStartOfWeek default Mon;
  608.     property Weekends: TDaysOfWeek read FWeekends write SetWeekends default [Sun];
  609.     property WeekendColor: TColor read FWeekendColor write SetWeekendColor default clRed;
  610.     property YearDigits: TYearDigits read FYearDigits write SetYearDigits default dyDefault;
  611.     property OnAcceptDate: TExecDateDialog read FOnAcceptDate write FOnAcceptDate;
  612.     property MaxLength stored False;
  613.     property Text stored TextStored;
  614.   public
  615.     constructor Create(AOwner: TComponent); override;
  616.     destructor Destroy; override;
  617.     procedure CheckValidDate;
  618.     function GetDateMask: string;
  619.     procedure UpdateMask; virtual;
  620.     property Date: TDateTime read GetDate write SetDate;
  621.     property PopupVisible;
  622.   end;
  623. { TDateEdit }
  624.   TDateEdit = class(TCustomDateEdit)
  625.   public
  626.     constructor Create(AOwner: TComponent); override;
  627.     property EditMask;
  628.   published
  629.     property AutoSelect;
  630.     property BlanksChar;
  631.     property BorderStyle;
  632.     property ButtonHint;
  633.     property CalendarHints;
  634.     property CheckOnExit;
  635.     property ClickKey;
  636.     property Color;
  637.     property Ctl3D;
  638.     property DefaultToday;
  639.     property DialogTitle;
  640.     property DirectInput;
  641.     property DragCursor;
  642.     property DragMode;
  643.     property Enabled;
  644.     property Font;
  645.     property GlyphKind;
  646.     { Ensure GlyphKind is declared before Glyph and ButtonWidth }
  647.     property Glyph;
  648.     property ButtonWidth;
  649.     property HideSelection;
  650. {$IFDEF RX_D4}
  651.     property Anchors;
  652.     property BiDiMode;
  653.     property Constraints;
  654.     property DragKind;
  655.     property ParentBiDiMode;
  656. {$ENDIF}
  657. {$IFDEF WIN32}
  658.   {$IFNDEF VER90}
  659.     property ImeMode;
  660.     property ImeName;
  661.   {$ENDIF}
  662. {$ENDIF}
  663.     property MaxLength;
  664.     property NumGlyphs;
  665.     property ParentColor;
  666.     property ParentCtl3D;
  667.     property ParentFont;
  668.     property ParentShowHint;
  669.     property PopupAlign;
  670.     property PopupColor;
  671.     property PopupMenu;
  672.     property ReadOnly;
  673.     property ShowHint;
  674.     property CalendarStyle;
  675.     property StartOfWeek;
  676.     property Weekends;
  677.     property WeekendColor;
  678.     property YearDigits;
  679.     property TabOrder;
  680.     property TabStop;
  681.     property Text;
  682.     property Visible;
  683.     property OnAcceptDate;
  684.     property OnButtonClick;
  685.     property OnChange;
  686.     property OnClick;
  687.     property OnDblClick;
  688.     property OnDragDrop;
  689.     property OnDragOver;
  690.     property OnEndDrag;
  691.     property OnEnter;
  692.     property OnExit;
  693.     property OnKeyDown;
  694.     property OnKeyPress;
  695.     property OnKeyUp;
  696.     property OnMouseDown;
  697.     property OnMouseMove;
  698.     property OnMouseUp;
  699. {$IFDEF WIN32}
  700.     property OnStartDrag;
  701. {$ENDIF}
  702. {$IFDEF RX_D5}
  703.     property OnContextPopup;
  704. {$ENDIF}
  705. {$IFDEF RX_D4}
  706.     property OnEndDock;
  707.     property OnStartDock;
  708. {$ENDIF}
  709.   end;
  710.   EComboEditError = class(Exception);
  711. { Utility routines }
  712. procedure DateFormatChanged;
  713. function EditorTextMargins(Editor: TCustomComboEdit): TPoint;
  714. function PaintComboEdit(Editor: TCustomComboEdit; const AText: string;
  715.   AAlignment: TAlignment; StandardPaint: Boolean;
  716.   var ACanvas: TControlCanvas; var Message: TWMPaint): Boolean;
  717. implementation
  718. uses ShellAPI, Consts, {$IFDEF RX_D3} ExtDlgs, {$ENDIF} RXCConst, VCLUtils,
  719.   rxStrUtils, FileUtil, PickDate, MaxMin;
  720. {$IFDEF WIN32}
  721.  {$R *.R32}
  722. {$ELSE}
  723.  {$R *.R16}
  724. {$ENDIF}
  725. const
  726.   sFileBmp = 'FEDITBMP'; { Filename and directory editor button glyph }
  727.   sDateBmp = 'DEDITBMP'; { Date editor button glyph }
  728. { Utility routines }
  729. function EditorTextMargins(Editor: TCustomComboEdit): TPoint;
  730. var
  731.   DC: HDC;
  732.   SaveFont: HFont;
  733.   I: Integer;
  734.   SysMetrics, Metrics: TTextMetric;
  735. begin
  736.   with Editor do begin
  737. {$IFDEF WIN32}
  738.     if NewStyleControls then begin
  739.       if BorderStyle = bsNone then I := 0
  740.       else if Ctl3D then I := 1
  741.       else I := 2;
  742.       Result.X := SendMessage(Handle, EM_GETMARGINS, 0, 0) and $0000FFFF + I;
  743.       Result.Y := I;
  744.     end
  745.     else begin
  746. {$ENDIF}
  747.       if BorderStyle = bsNone then I := 0
  748.       else begin
  749.         DC := GetDC(0);
  750.         GetTextMetrics(DC, SysMetrics);
  751.         SaveFont := SelectObject(DC, Font.Handle);
  752.         GetTextMetrics(DC, Metrics);
  753.         SelectObject(DC, SaveFont);
  754.         ReleaseDC(0, DC);
  755.         I := SysMetrics.tmHeight;
  756.         if I > Metrics.tmHeight then I := Metrics.tmHeight;
  757.         I := I div 4;
  758.       end;
  759.       Result.X := I;
  760.       Result.Y := I;
  761. {$IFDEF WIN32}
  762.     end;
  763. {$ENDIF}
  764.   end;
  765. end;
  766. function PaintComboEdit(Editor: TCustomComboEdit; const AText: string;
  767.   AAlignment: TAlignment; StandardPaint: Boolean;
  768.   var ACanvas: TControlCanvas; var Message: TWMPaint): Boolean;
  769. var
  770.   AWidth, ALeft: Integer;
  771.   Margins: TPoint;
  772.   R: TRect;
  773.   DC: HDC;
  774.   PS: TPaintStruct;
  775.   S: string;
  776. {$IFDEF RX_D4}
  777.   ExStyle: DWORD;
  778. const
  779.   AlignStyle: array[Boolean, TAlignment] of DWORD =
  780.    ((WS_EX_LEFT, WS_EX_RIGHT, WS_EX_LEFT),
  781.     (WS_EX_RIGHT, WS_EX_LEFT, WS_EX_LEFT));
  782. {$ENDIF}
  783. begin
  784.   Result := True;
  785.   with Editor do begin
  786. {$IFDEF RX_D4}
  787.     if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
  788. {$ENDIF}
  789.     if StandardPaint {$IFDEF WIN32} and not
  790.       (csPaintCopy in ControlState) {$ENDIF} then
  791.     begin
  792. {$IFDEF RX_D4}
  793.       if SysLocale.MiddleEast and HandleAllocated and (IsRightToLeft) then
  794.       begin { This keeps the right aligned text, right aligned }
  795.         ExStyle := DWORD(GetWindowLong(Handle, GWL_EXSTYLE)) and (not WS_EX_RIGHT) and
  796.           (not WS_EX_RTLREADING) and (not WS_EX_LEFTSCROLLBAR);
  797.         if UseRightToLeftReading then
  798.           ExStyle := ExStyle or WS_EX_RTLREADING;
  799.         if UseRightToLeftScrollbar then
  800.           ExStyle := ExStyle or WS_EX_LEFTSCROLLBAR;
  801.         ExStyle := ExStyle or
  802.           AlignStyle[UseRightToLeftAlignment, AAlignment];
  803.         if DWORD(GetWindowLong(Handle, GWL_EXSTYLE)) <> ExStyle then
  804.           SetWindowLong(Handle, GWL_EXSTYLE, ExStyle);
  805.       end;
  806. {$ENDIF RX_D4}
  807.       Result := False;
  808.       { return false if we need to use standard paint handler }
  809.       Exit;
  810.     end;
  811.     { Since edit controls do not handle justification unless multi-line (and
  812.       then only poorly) we will draw right and center justify manually unless
  813.       the edit has the focus. }
  814.     if ACanvas = nil then begin
  815.       ACanvas := TControlCanvas.Create;
  816.       ACanvas.Control := Editor;
  817.     end;
  818.     DC := Message.DC;
  819.     if DC = 0 then DC := BeginPaint(Handle, PS);
  820.     ACanvas.Handle := DC;
  821.     try
  822.       ACanvas.Font := Font;
  823.       if not Enabled and NewStyleControls and not
  824.         (csDesigning in ComponentState) and
  825.         (ColorToRGB(Color) <> ColorToRGB(clGrayText)) then
  826.         ACanvas.Font.Color := clGrayText;
  827.       with ACanvas do begin
  828.         R := ClientRect;
  829.         if {$IFDEF WIN32} not (NewStyleControls and Ctl3D) and {$ENDIF}
  830.           (BorderStyle = bsSingle) then
  831.         begin
  832.           Brush.Color := clWindowFrame;
  833.           FrameRect(R);
  834.           InflateRect(R, -1, -1);
  835.         end;
  836.         Brush.Color := Color;
  837.         S := AText;
  838.         AWidth := TextWidth(S);
  839.         Margins := EditorTextMargins(Editor);
  840.         if PopupVisible then ALeft := Margins.X
  841.         else begin
  842.           if ButtonWidth > 0 then Inc(AWidth);
  843.           case AAlignment of
  844.             taLeftJustify:
  845.               ALeft := Margins.X;
  846.             taRightJustify:
  847.               ALeft := ClientWidth - ButtonWidth - AWidth - Margins.X - 2;
  848.             else
  849.               ALeft := (ClientWidth - ButtonWidth - AWidth) div 2;
  850.           end;
  851.         end;
  852. {$IFDEF RX_D4}
  853.         if SysLocale.MiddleEast then UpdateTextFlags;
  854. {$ENDIF}
  855.         TextRect(R, ALeft, Margins.Y, S);
  856.       end;
  857.     finally
  858.       ACanvas.Handle := 0;
  859.       if Message.DC = 0 then EndPaint(Handle, PS);
  860.     end;
  861.   end;
  862. end;
  863. { TEditButton }
  864. constructor TEditButton.Create(AOwner: TComponent);
  865. begin
  866.   inherited Create(AOwner);
  867. {$IFDEF WIN32}
  868.   ControlStyle := ControlStyle + [csReplicatable];
  869. {$ELSE}
  870.   Style := bsWin31;
  871. {$ENDIF}
  872.   ParentShowHint := True;
  873. end;
  874. {$IFDEF WIN32}
  875. procedure TEditButton.Paint;
  876. begin
  877.   inherited Paint;
  878.   if (FState <> rbsDown) then
  879.     with Canvas do begin
  880.       if NewStyleControls then Pen.Color := clBtnFace
  881.       else Pen.Color := clBtnShadow;
  882.       MoveTo(0, 0);
  883.       LineTo(0, Self.Height - 1);
  884.       Pen.Color := clBtnHighlight;
  885.       MoveTo(1, 1);
  886.       LineTo(1, Self.Height - 2);
  887.     end;
  888. end;
  889. {$ENDIF WIN32}
  890. procedure TEditButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  891.   X, Y: Integer);
  892. begin
  893.   if (Button = mbLeft) then
  894.     with TCustomComboEdit(Owner) do begin
  895.       FNoAction := (FPopup <> nil) and FPopupVisible;
  896.       if not FPopupVisible then begin
  897.         if TabStop and CanFocus and (GetFocus <> Handle) then SetFocus;
  898.       end
  899.       else PopupCloseUp(FPopup, True);
  900.     end;
  901.   inherited MouseDown(Button, Shift, X, Y);
  902. end;
  903. procedure TEditButton.Click;
  904. begin
  905.   if not FNoAction then inherited Click else FNoAction := False;
  906. end;
  907. { TPopupWindow }
  908. constructor TPopupWindow.Create(AOwner: TComponent);
  909. begin
  910.   inherited Create(AOwner);
  911.   FEditor := TWinControl(AOwner);
  912. {$IFDEF WIN32}
  913.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable,
  914.     csAcceptsControls];
  915. {$ELSE}
  916.   ControlStyle := ControlStyle + [csAcceptsControls];
  917. {$ENDIF}
  918.   Ctl3D := False;
  919.   ParentCtl3D := False;
  920.   Visible := False;
  921.   Parent := FEditor;
  922.   OnMouseUp := PopupMouseUp;
  923. end;
  924. procedure TPopupWindow.CreateParams(var Params: TCreateParams);
  925. begin
  926.   inherited CreateParams(Params);
  927.   with Params do begin
  928.     Style := WS_POPUP or WS_BORDER or WS_CLIPCHILDREN;
  929. {$IFDEF WIN32}
  930.     ExStyle := WS_EX_TOOLWINDOW;
  931. {$ENDIF}
  932.     WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
  933.   end;
  934. end;
  935. {$IFNDEF WIN32}
  936. procedure TPopupWindow.CreateWnd;
  937. begin
  938.   inherited CreateWnd;
  939.   if (csDesigning in ComponentState) then SetParent(nil);
  940. end;
  941. {$ENDIF}
  942. procedure TPopupWindow.WMMouseActivate(var Message: TMessage);
  943. begin
  944.   Message.Result := MA_NOACTIVATE;
  945. end;
  946. function TPopupWindow.GetPopupText: string;
  947. begin
  948.   Result := '';
  949. end;
  950. procedure TPopupWindow.InvalidateEditor;
  951. var
  952.   R: TRect;
  953. begin
  954.   if (FEditor is TCustomComboEdit) then begin
  955.     with TCustomComboEdit(FEditor) do
  956.       SetRect(R, 0, 0, ClientWidth - FBtnControl.Width - 2, ClientHeight + 1);
  957.   end
  958.   else R := FEditor.ClientRect;
  959.   InvalidateRect(FEditor.Handle, @R, False);
  960.   UpdateWindow(FEditor.Handle);
  961. end;
  962. procedure TPopupWindow.PopupMouseUp(Sender: TObject; Button: TMouseButton;
  963.   Shift: TShiftState; X, Y: Integer);
  964. begin
  965.   if Button = mbLeft then CloseUp(PtInRect(Self.ClientRect, Point(X, Y)));
  966. end;
  967. procedure TPopupWindow.CloseUp(Accept: Boolean);
  968. begin
  969.   if Assigned(FCloseUp) then FCloseUp(Self, Accept);
  970. end;
  971. procedure TPopupWindow.Hide;
  972. begin
  973.   SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  974.     SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  975.   Visible := False;
  976. end;
  977. procedure TPopupWindow.Show(Origin: TPoint);
  978. begin
  979.   SetWindowPos(Handle, HWND_TOP, Origin.X, Origin.Y, 0, 0,
  980.     SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOSIZE);
  981.   Visible := True;
  982. end;
  983. { TCustomComboEdit }
  984. constructor TCustomComboEdit.Create(AOwner: TComponent);
  985. begin
  986.   inherited Create(AOwner);
  987. {$IFDEF RX_D3}
  988.   ControlStyle := ControlStyle + [csCaptureMouse];
  989. {$ENDIF}
  990.   AutoSize := False;
  991.   FDirectInput := True;
  992.   FClickKey := scAltDown;
  993.   FPopupAlign := epaRight;
  994.   FBtnControl := TWinControl.Create(Self);
  995. {$IFDEF WIN32}
  996.   with FBtnControl do
  997.     ControlStyle := ControlStyle + [csReplicatable];
  998. {$ENDIF}
  999.   FBtnControl.Width := DefEditBtnWidth;
  1000.   FBtnControl.Height := 17;
  1001.   FBtnControl.Visible := True;
  1002.   FBtnControl.Parent := Self;
  1003.   FButton := TEditButton.Create(Self);
  1004.   FButton.SetBounds(0, 0, FBtnControl.Width, FBtnControl.Height);
  1005.   FButton.Visible := True;
  1006.   FButton.Parent := FBtnControl;
  1007.   TEditButton(FButton).OnClick := EditButtonClick;
  1008.   Height := 21;
  1009.   FDefNumGlyphs := 1;
  1010.   FGlyphKind := gkCustom;
  1011. end;
  1012. destructor TCustomComboEdit.Destroy;
  1013. begin
  1014.   FButton.OnClick := nil;
  1015.   inherited Destroy;
  1016. end;
  1017. procedure TCustomComboEdit.CreateParams(var Params: TCreateParams);
  1018. const
  1019.   Alignments: array[TAlignment] of Longword = (ES_LEFT, ES_RIGHT, ES_CENTER);
  1020. begin
  1021.   inherited CreateParams(Params);
  1022.   Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN
  1023.     or Alignments[FAlignment];
  1024. end;
  1025. procedure TCustomComboEdit.CreateWnd;
  1026. begin
  1027.   inherited CreateWnd;
  1028.   SetEditRect;
  1029. end;
  1030. procedure TCustomComboEdit.HidePopup;
  1031. begin
  1032.   TPopupWindow(FPopup).Hide;
  1033. end;
  1034. procedure TCustomComboEdit.ShowPopup(Origin: TPoint);
  1035. begin
  1036.   TPopupWindow(FPopup).Show(Origin);
  1037. end;
  1038. procedure TCustomComboEdit.PopupDropDown(DisableEdit: Boolean);
  1039. var
  1040.   P: TPoint;
  1041.   Y: Integer;
  1042. begin
  1043.   if (FPopup <> nil) and not (ReadOnly or FPopupVisible) then begin
  1044.     P := Parent.ClientToScreen(Point(Left, Top));
  1045.     Y := P.Y + Height;
  1046.     if Y + FPopup.Height > Screen.Height then
  1047.       Y := P.Y - FPopup.Height;
  1048.     case FPopupAlign of
  1049.       epaRight:
  1050.         begin
  1051.           Dec(P.X, FPopup.Width - Width);
  1052.           if P.X < 0 then Inc(P.X, FPopup.Width - Width);
  1053.         end;
  1054.       epaLeft:
  1055.         begin
  1056.           if P.X + FPopup.Width > Screen.Width then
  1057.             Dec(P.X, FPopup.Width - Width);
  1058.         end;
  1059.     end;
  1060.     if P.X < 0 then P.X := 0
  1061.     else if P.X + FPopup.Width > Screen.Width then
  1062.       P.X := Screen.Width - FPopup.Width;
  1063. {$IFDEF WIN32}
  1064.     if Text <> '' then SetPopupValue(Text)
  1065.     else SetPopupValue(Null);
  1066. {$ELSE}
  1067.     SetPopupValue(Text);
  1068. {$ENDIF}
  1069.     if CanFocus then SetFocus;
  1070.     ShowPopup(Point(P.X, Y));
  1071.     FPopupVisible := True;
  1072.     if DisableEdit then begin
  1073.       inherited ReadOnly := True;
  1074.       HideCaret(Handle);
  1075.     end;
  1076.   end;
  1077. end;
  1078. procedure TCustomComboEdit.PopupCloseUp(Sender: TObject; Accept: Boolean);
  1079. var
  1080. {$IFDEF WIN32}
  1081.   AValue: Variant;
  1082. {$ELSE}
  1083.   AValue: string;
  1084. {$ENDIF}
  1085. begin
  1086.   if (FPopup <> nil) and FPopupVisible then begin
  1087.     if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  1088.     AValue := GetPopupValue;
  1089.     HidePopup;
  1090.     try
  1091.       try
  1092.         if CanFocus then begin
  1093.           SetFocus;
  1094.           if GetFocus = Handle then SetShowCaret;
  1095.         end;
  1096.       except
  1097.         { ignore exceptions }
  1098.       end;
  1099.       SetDirectInput(DirectInput);
  1100.       Invalidate;
  1101.       if Accept and AcceptPopup(AValue) and EditCanModify then begin
  1102.         AcceptValue(AValue);
  1103.         if FFocused then inherited SelectAll;
  1104.       end;
  1105.     finally
  1106.       FPopupVisible := False;
  1107.     end;
  1108.   end;
  1109. end;
  1110. procedure TCustomComboEdit.DoChange;
  1111. begin
  1112.   inherited Change;
  1113. end;
  1114. {$IFDEF WIN32}
  1115. function TCustomComboEdit.GetPopupValue: Variant;
  1116. {$ELSE}
  1117. function TCustomComboEdit.GetPopupValue: string;
  1118. {$ENDIF}
  1119. begin
  1120.   if FPopup <> nil then Result := TPopupWindow(FPopup).GetValue
  1121.   else Result := '';
  1122. end;
  1123. {$IFDEF WIN32}
  1124. procedure TCustomComboEdit.SetPopupValue(const Value: Variant);
  1125. {$ELSE}
  1126. procedure TCustomComboEdit.SetPopupValue(const Value: string);
  1127. {$ENDIF}
  1128. begin
  1129.   if FPopup <> nil then TPopupWindow(FPopup).SetValue(Value);
  1130. end;
  1131. {$IFDEF WIN32}
  1132. procedure TCustomComboEdit.AcceptValue(const Value: Variant);
  1133. begin
  1134.   if Text <> VarToStr(Value) then begin
  1135. {$ELSE}
  1136. procedure TCustomComboEdit.AcceptValue(const Value: string);
  1137. begin
  1138.   if Text <> Value then begin
  1139. {$ENDIF}
  1140.     Text := Value;
  1141.     Modified := True;
  1142.     UpdatePopupVisible;
  1143.     DoChange;
  1144.   end;
  1145. end;
  1146. {$IFDEF WIN32}
  1147. function TCustomComboEdit.AcceptPopup(var Value: Variant): Boolean;
  1148. {$ELSE}
  1149. function TCustomComboEdit.AcceptPopup(var Value: string): Boolean;
  1150. {$ENDIF}
  1151. begin
  1152.   Result := True;
  1153. end;
  1154. function TCustomComboEdit.EditCanModify: Boolean;
  1155. begin
  1156.   Result := not FReadOnly;
  1157. end;
  1158. procedure TCustomComboEdit.Change;
  1159. begin
  1160.   if not PopupVisible then DoChange
  1161.   else PopupChange;
  1162. end;
  1163. procedure TCustomComboEdit.PopupChange;
  1164. begin
  1165. end;
  1166. procedure TCustomComboEdit.KeyDown(var Key: Word; Shift: TShiftState);
  1167. begin
  1168.   inherited KeyDown(Key, Shift);
  1169.   if (FClickKey = ShortCut(Key, Shift)) and (ButtonWidth > 0) then begin
  1170.     EditButtonClick(Self);
  1171.     Key := 0;
  1172.   end;
  1173. end;
  1174. procedure TCustomComboEdit.KeyPress(var Key: Char);
  1175. begin
  1176.   if (Key = Char(VK_RETURN)) or (Key = Char(VK_ESCAPE)) then
  1177.   begin
  1178.     if PopupVisible then begin
  1179.       PopupCloseUp(FPopup, Key = Char(VK_RETURN));
  1180.       Key := #0;
  1181.     end
  1182.     else begin
  1183.       { must catch and remove this, since is actually multi-line }
  1184.       GetParentForm(Self).Perform(CM_DIALOGKEY, Byte(Key), 0);
  1185.       if Key = Char(VK_RETURN) then begin
  1186.         inherited KeyPress(Key);
  1187.         Key := #0;
  1188.         Exit;
  1189.       end;
  1190.     end;
  1191.   end;
  1192.   inherited KeyPress(Key);
  1193. end;
  1194. procedure TCustomComboEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1195.   X, Y: Integer);
  1196. begin
  1197.   if (FPopup <> nil) and (Button = mbLeft) then begin
  1198.     if CanFocus then SetFocus;
  1199.     if not FFocused then Exit;
  1200.     if FPopupVisible then PopupCloseUp(FPopup, False);
  1201.     {else if (not ReadOnly or AlwaysEnable) and (not DirectInput) then
  1202.       PopupDropDown(True);}
  1203.   end;
  1204.   inherited MouseDown(Button, Shift, X, Y);
  1205. end;
  1206. function TCustomComboEdit.GetButtonWidth: Integer;
  1207. begin
  1208.   Result := FButton.Width;
  1209. end;
  1210. procedure TCustomComboEdit.SetButtonWidth(Value: Integer);
  1211. begin
  1212.   if ButtonWidth <> Value then begin
  1213.     FBtnControl.Visible := Value > 1;
  1214.     if (csCreating in ControlState) then begin
  1215.       FBtnControl.Width := Value;
  1216.       FButton.Width := Value;
  1217.       with FButton do
  1218.         ControlStyle := ControlStyle - [csFixedWidth];
  1219.       RecreateGlyph;
  1220.     end
  1221.     else if (Value <> ButtonWidth) and (Value < ClientWidth) then begin
  1222.       FButton.Width := Value;
  1223.       with FButton do
  1224.         ControlStyle := ControlStyle - [csFixedWidth];
  1225.       if HandleAllocated then RecreateWnd;
  1226.       RecreateGlyph;
  1227.     end;
  1228.   end;
  1229. end;
  1230. function TCustomComboEdit.GetButtonHint: string;
  1231. begin
  1232.   Result := FButton.Hint;
  1233. end;
  1234. procedure TCustomComboEdit.SetButtonHint(const Value: string);
  1235. begin
  1236.   FButton.Hint := Value;
  1237. end;
  1238. function TCustomComboEdit.GetGlyph: TBitmap;
  1239. begin
  1240.   Result := FButton.Glyph;
  1241. end;
  1242. procedure TCustomComboEdit.SetGlyph(Value: TBitmap);
  1243. begin
  1244.   FButton.Glyph := Value;
  1245.   FGlyphKind := gkCustom;
  1246. end;
  1247. function TCustomComboEdit.GetNumGlyphs: TNumGlyphs;
  1248. begin
  1249.   Result := FButton.NumGlyphs;
  1250. end;
  1251. procedure TCustomComboEdit.SetNumGlyphs(Value: TNumGlyphs);
  1252. begin
  1253.   if FGlyphKind in [gkDropDown, gkEllipsis] then FButton.NumGlyphs := 1
  1254.   else if FGlyphKind = gkDefault then FButton.NumGlyphs := FDefNumGlyphs
  1255.   else FButton.NumGlyphs := Value;
  1256. end;
  1257. procedure TCustomComboEdit.SetEditRect;
  1258. var
  1259.   Loc: TRect;
  1260. begin
  1261.   SetRect(Loc, 0, 0, ClientWidth - FBtnControl.Width - 2, ClientHeight + 1);
  1262.   SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
  1263. end;
  1264. procedure TCustomComboEdit.UpdateBtnBounds;
  1265. var
  1266.   BtnRect: TRect;
  1267. begin
  1268. {$IFDEF WIN32}
  1269.   if NewStyleControls then begin
  1270.     if Ctl3D and (BorderStyle = bsSingle) then
  1271.       BtnRect := Bounds(Width - FButton.Width - 4, 0,
  1272.         FButton.Width, Height - 4)
  1273.     else begin
  1274.       if BorderStyle = bsSingle then
  1275.         BtnRect := Bounds(Width - FButton.Width - 2, 2,
  1276.           FButton.Width, Height - 4)
  1277.       else
  1278.         BtnRect := Bounds(Width - FButton.Width, 0,
  1279.           FButton.Width, Height);
  1280.     end;
  1281.   end
  1282.   else
  1283.     BtnRect := Bounds(Width - FButton.Width, 0, FButton.Width, Height);
  1284. {$ELSE}
  1285.   BtnRect := Bounds(Width - FButton.Width, 0, FButton.Width, Height);
  1286. {$ENDIF}
  1287.   with BtnRect do
  1288.     FBtnControl.SetBounds(Left, Top, Right - Left, Bottom - Top);
  1289.   FButton.Height := FBtnControl.Height;
  1290.   SetEditRect;
  1291. end;
  1292. {$IFDEF WIN32}
  1293. procedure TCustomComboEdit.CMCtl3DChanged(var Message: TMessage);
  1294. begin
  1295.   inherited;
  1296.   UpdateBtnBounds;
  1297. end;
  1298. {$ENDIF}
  1299. procedure TCustomComboEdit.WMSize(var Message: TWMSize);
  1300. var
  1301.   MinHeight: Integer;
  1302. begin
  1303.   inherited;
  1304.   if not (csLoading in ComponentState) then begin
  1305.     MinHeight := GetMinHeight;
  1306.     { text edit bug: if size to less than MinHeight, then edit ctrl does
  1307.       not display the text }
  1308.     if Height < MinHeight then begin
  1309.       Height := MinHeight;
  1310.       Exit;
  1311.     end;
  1312.   end
  1313.   else begin
  1314.     if (FPopup <> nil) and (csDesigning in ComponentState) then
  1315.       FPopup.SetBounds(0, Height + 1, 10, 10);
  1316.   end;
  1317.   UpdateBtnBounds;
  1318. end;
  1319. function TCustomComboEdit.GetTextHeight: Integer;
  1320. var
  1321.   DC: HDC;
  1322.   SaveFont: HFont;
  1323.   SysMetrics, Metrics: TTextMetric;
  1324. begin
  1325.   DC := GetDC(0);
  1326.   try
  1327.     GetTextMetrics(DC, SysMetrics);
  1328.     SaveFont := SelectObject(DC, Font.Handle);
  1329.     GetTextMetrics(DC, Metrics);
  1330.     SelectObject(DC, SaveFont);
  1331.   finally
  1332.     ReleaseDC(0, DC);
  1333.   end;
  1334.   Result := Min(SysMetrics.tmHeight, Metrics.tmHeight);
  1335. end;
  1336. function TCustomComboEdit.GetMinHeight: Integer;
  1337. var
  1338.   I: Integer;
  1339. begin
  1340.   I := GetTextHeight;
  1341.   Result := I + GetSystemMetrics(SM_CYBORDER) * 4 +
  1342.     1 {$IFNDEF WIN32} + (I div 4) {$ENDIF};
  1343. end;
  1344. procedure TCustomComboEdit.UpdatePopupVisible;
  1345. begin
  1346.   FPopupVisible := (FPopup <> nil) and FPopup.Visible;
  1347. end;
  1348. function TCustomComboEdit.GetPopupVisible: Boolean;
  1349. begin
  1350.   Result := (FPopup <> nil) and FPopupVisible;
  1351. end;
  1352. procedure TCustomComboEdit.CMFontChanged(var Message: TMessage);
  1353. begin
  1354.   inherited;
  1355.   if HandleAllocated then SetEditRect;
  1356. end;
  1357. procedure TCustomComboEdit.CMEnabledChanged(var Message: TMessage);
  1358. begin
  1359.   inherited;
  1360.   FButton.Enabled := Enabled;
  1361. end;
  1362. procedure TCustomComboEdit.CMCancelMode(var Message: TCMCancelMode);
  1363. begin
  1364.   if (Message.Sender <> Self) and (Message.Sender <> FPopup) and
  1365.     (Message.Sender <> FButton) and ((FPopup <> nil) and
  1366.     not FPopup.ContainsControl(Message.Sender)) then
  1367.     PopupCloseUp(FPopup, False);
  1368. end;
  1369. procedure TCustomComboEdit.CMEnter(var Message: TMessage);
  1370. begin
  1371.   if AutoSelect and not (csLButtonDown in ControlState) then SelectAll;
  1372.   inherited;
  1373. end;
  1374. procedure TCustomComboEdit.CNCtlColor(var Message: TMessage);
  1375. var
  1376.   TextColor: Longint;
  1377. begin
  1378.   inherited;
  1379.   if NewStyleControls then begin
  1380.     TextColor := ColorToRGB(Font.Color);
  1381.     if not Enabled and (ColorToRGB(Color) <> ColorToRGB(clGrayText)) then
  1382.       TextColor := ColorToRGB(clGrayText);
  1383.     SetTextColor(Message.WParam, TextColor);
  1384.   end;
  1385. end;
  1386. procedure TCustomComboEdit.WMKillFocus(var Message: TWMKillFocus);
  1387. begin
  1388.   inherited;
  1389.   FFocused := False;
  1390.   PopupCloseUp(FPopup, False);
  1391. end;
  1392. procedure TCustomComboEdit.WMSetFocus(var Message: TMessage);
  1393. begin
  1394.   inherited;
  1395.   FFocused := True;
  1396.   SetShowCaret;
  1397. end;
  1398. {$IFDEF RX_D4}
  1399. procedure TCustomComboEdit.CMBiDiModeChanged(var Message: TMessage);
  1400. begin
  1401.   inherited;
  1402.   if FPopup <> nil then FPopup.BiDiMode := BiDiMode;
  1403. end;
  1404. {$ENDIF}
  1405. procedure TCustomComboEdit.SetShowCaret;
  1406. const
  1407.   CaretWidth: array[Boolean] of Byte = (1, 2);
  1408. begin
  1409.   CreateCaret(Handle, 0, CaretWidth[fsBold in Font.Style], GetTextHeight);
  1410.   ShowCaret(Handle);
  1411. end;
  1412. procedure TCustomComboEdit.EditButtonClick(Sender: TObject);
  1413. begin
  1414.   if (not FReadOnly) or AlwaysEnable then ButtonClick;
  1415. end;
  1416. procedure TCustomComboEdit.DoClick;
  1417. begin
  1418.   EditButtonClick(Self);
  1419. end;
  1420. procedure TCustomComboEdit.ButtonClick;
  1421. begin
  1422.   if Assigned(FOnButtonClick) then FOnButtonClick(Self);
  1423.   if FPopup <> nil then begin
  1424.     if FPopupVisible then PopupCloseUp(FPopup, True) else PopupDropDown(True);
  1425.   end;
  1426. end;
  1427. procedure TCustomComboEdit.SelectAll;
  1428. begin
  1429.   if DirectInput then inherited SelectAll;
  1430. end;
  1431. function TCustomComboEdit.GetDirectInput: Boolean;
  1432. begin
  1433.   Result := FDirectInput;
  1434. end;
  1435. procedure TCustomComboEdit.SetDirectInput(Value: Boolean);
  1436. begin
  1437.   inherited ReadOnly := not Value or FReadOnly;
  1438.   FDirectInput := Value;
  1439. end;
  1440. procedure TCustomComboEdit.WMPaste(var Message: TWMPaste);
  1441. begin
  1442.   if not FDirectInput or ReadOnly then Exit;
  1443.   inherited;
  1444. end;
  1445. procedure TCustomComboEdit.WMCut(var Message: TWMCut);
  1446. begin
  1447.   if not FDirectInput or ReadOnly then Exit;
  1448.   inherited;
  1449. end;
  1450. function TCustomComboEdit.GetReadOnly: Boolean;
  1451. begin
  1452.   Result := FReadOnly;
  1453. end;
  1454. procedure TCustomComboEdit.SetReadOnly(Value: Boolean);
  1455. begin
  1456.   if Value <> FReadOnly then begin
  1457.     FReadOnly := Value;
  1458.     inherited ReadOnly := Value or not FDirectInput;
  1459.   end;
  1460. end;
  1461. procedure TCustomComboEdit.SetAlignment(Value: TAlignment);
  1462. begin
  1463.   if FAlignment <> Value then begin
  1464.     FAlignment := Value;
  1465.     RecreateWnd;
  1466.   end;
  1467. end;
  1468. function TCustomComboEdit.BtnWidthStored: Boolean;
  1469. begin
  1470.   if (FGlyphKind = gkDefault) and (Glyph <> nil) then
  1471.     Result := ButtonWidth <> Max(Glyph.Width div FButton.NumGlyphs + 6,
  1472.       DefEditBtnWidth)
  1473.   else if FGlyphKind = gkDropDown then
  1474.     Result := ButtonWidth <> GetSystemMetrics(SM_CXVSCROLL)
  1475.       {$IFNDEF WIN32} + 1{$ENDIF}
  1476.   else Result := ButtonWidth <> DefEditBtnWidth;
  1477. end;
  1478. function TCustomComboEdit.IsCustomGlyph: Boolean;
  1479. begin
  1480.   Result := FGlyphKind = gkCustom;
  1481. end;
  1482. procedure TCustomComboEdit.SetGlyphKind(Value: TGlyphKind);
  1483. begin
  1484.   if FGlyphKind <> Value then begin
  1485.     FGlyphKind := Value;
  1486.     if (FGlyphKind = gkCustom) and (csReading in ComponentState) then begin
  1487.       Glyph := nil;
  1488.     end;
  1489.     RecreateGlyph;
  1490.     if (FGlyphKind = gkDefault) and (Glyph <> nil) then
  1491.       ButtonWidth := Max(Glyph.Width div FButton.NumGlyphs + 6, FButton.Width)
  1492.     else if FGlyphKind = gkDropDown then begin
  1493.       ButtonWidth := GetSystemMetrics(SM_CXVSCROLL){$IFNDEF WIN32} + 1{$ENDIF};
  1494.       with FButton do
  1495.         ControlStyle := ControlStyle + [csFixedWidth];
  1496.     end;
  1497.   end;
  1498. end;
  1499. function TCustomComboEdit.GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap;
  1500. begin
  1501.   Result := nil;
  1502. end;
  1503. procedure TCustomComboEdit.RecreateGlyph;
  1504.   function CreateEllipsisGlyph: TBitmap;
  1505.   var
  1506.     W, G, I: Integer;
  1507.   begin
  1508.     Result := TBitmap.Create;
  1509.     with Result do
  1510.     try
  1511.       Monochrome := True;
  1512.       Width := Max(1, FButton.Width - 6);
  1513.       Height := 4;
  1514.       W := 2;
  1515.       G := (Result.Width - 3 * W) div 2;
  1516.       if G <= 0 then G := 1;
  1517.       if G > 3 then G := 3;
  1518.       I := (Width - 3 * W - 2 * G) div 2;
  1519.       PatBlt(Canvas.Handle, I, 1, W, W, BLACKNESS);
  1520.       PatBlt(Canvas.Handle, I + G + W, 1, W, W, BLACKNESS);
  1521.       PatBlt(Canvas.Handle, I + 2 * G + 2 * W, 1, W, W, BLACKNESS);
  1522.     except
  1523.       Free;
  1524.       raise;
  1525.     end;
  1526.   end;
  1527. var
  1528.   NewGlyph: TBitmap;
  1529.   DestroyNeeded: Boolean;
  1530. begin
  1531.   case FGlyphKind of
  1532.     gkDefault:
  1533.       begin
  1534.         DestroyNeeded := False;
  1535.         NewGlyph := GetDefaultBitmap(DestroyNeeded);
  1536.         try
  1537.           FButton.Glyph.Assign(NewGlyph);
  1538.           NumGlyphs := FDefNumGlyphs;
  1539.         finally
  1540.           if DestroyNeeded then NewGlyph.Destroy;
  1541.         end;
  1542.       end;
  1543.     gkDropDown:
  1544.       begin
  1545.         FButton.Glyph.Handle := LoadBitmap(0, PChar(32738));
  1546.         NumGlyphs := 1;
  1547.       end;
  1548.     gkEllipsis:
  1549.       begin
  1550.         NewGlyph := CreateEllipsisGlyph;
  1551.         try
  1552.           FButton.Glyph := NewGlyph;
  1553.           NumGlyphs := 1;
  1554.         finally
  1555.           NewGlyph.Destroy;
  1556.         end;
  1557.       end;
  1558.   end;
  1559. end;
  1560. const
  1561.   FileBitmap: TBitmap = nil;
  1562.   DateBitmap: TBitmap = nil;
  1563. { TFileDirEdit }
  1564. constructor TFileDirEdit.Create(AOwner: TComponent);
  1565. begin
  1566.   inherited Create(AOwner);
  1567.   OEMConvert := True;
  1568. {$IFNDEF WIN32}
  1569.   MaxLength := MaxFileLength;
  1570. {$ENDIF}
  1571.   ControlState := ControlState + [csCreating];
  1572.   try
  1573.     GlyphKind := gkDefault; { force update }
  1574.   finally
  1575.     ControlState := ControlState - [csCreating];
  1576.   end;
  1577. end;
  1578. function TFileDirEdit.GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap;
  1579. begin
  1580.   DestroyNeeded := False;
  1581.   if FileBitmap = nil then begin
  1582.     FileBitmap := TBitmap.Create;
  1583.     FileBitmap.Handle := LoadBitmap(hInstance, sFileBmp);
  1584.   end;
  1585.   Result := FileBitmap;
  1586. end;
  1587. procedure TFileDirEdit.DoBeforeDialog(var FileName: string;
  1588.   var Action: Boolean);
  1589. begin
  1590.   if Assigned(FOnBeforeDialog) then FOnBeforeDialog(Self, FileName, Action);
  1591. end;
  1592. procedure TFileDirEdit.DoAfterDialog(var FileName: string;
  1593.   var Action: Boolean);
  1594. begin
  1595.   if Assigned(FOnAfterDialog) then FOnAfterDialog(Self, FileName, Action);
  1596. end;
  1597. procedure TFileDirEdit.CreateHandle;
  1598. begin
  1599.   inherited CreateHandle;
  1600.   if FAcceptFiles then SetDragAccept(True);
  1601. end;
  1602. procedure TFileDirEdit.DestroyWindowHandle;
  1603. begin
  1604.   SetDragAccept(False);
  1605.   inherited DestroyWindowHandle;
  1606. end;
  1607. procedure TFileDirEdit.SetDragAccept(Value: Boolean);
  1608. begin
  1609.   if not (csDesigning in ComponentState) and (Handle <> 0) then
  1610.     DragAcceptFiles(Handle, Value);
  1611. end;
  1612. procedure TFileDirEdit.SetAcceptFiles(Value: Boolean);
  1613. begin
  1614.   if FAcceptFiles <> Value then begin
  1615.     SetDragAccept(Value);
  1616.     FAcceptFiles := Value;
  1617.   end;
  1618. end;
  1619. procedure TFileDirEdit.DisableSysErrors;
  1620. begin
  1621.   FErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS);
  1622. end;
  1623. procedure TFileDirEdit.EnableSysErrors;
  1624. begin
  1625.   SetErrorMode(FErrMode);
  1626.   FErrMode := 0;
  1627. end;
  1628. procedure TFileDirEdit.WMDropFiles(var Msg: TWMDropFiles);
  1629. var
  1630.   AFileName: array[0..255] of Char;
  1631.   I, Num: Cardinal;
  1632. begin
  1633.   Msg.Result := 0;
  1634.   try
  1635. {$IFDEF WIN32}
  1636.     Num := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
  1637. {$ELSE}
  1638.     Num := DragQueryFile(Msg.Drop, $FFFF, nil, 0);
  1639. {$ENDIF}
  1640.     if Num > 0 then begin
  1641.       ClearFileList;
  1642.       for I := 0 to Num - 1 do begin
  1643.         DragQueryFile(Msg.Drop, I, PChar(@AFileName), Pred(SizeOf(AFileName)));
  1644.         ReceptFileDir(StrPas(AFileName));
  1645.         if not FMultipleDirs then Break;
  1646.       end;
  1647.       if Assigned(FOnDropFiles) then FOnDropFiles(Self);
  1648.     end;
  1649.   finally
  1650.     DragFinish(Msg.Drop);
  1651.   end;
  1652. end;
  1653. procedure TFileDirEdit.ClearFileList;
  1654. begin
  1655. end;
  1656. { TFilenameEdit }
  1657. function ClipFilename(const FileName: string): string;
  1658. var
  1659.   Params: string;
  1660. begin
  1661.   if FileExists(FileName) then Result := FileName
  1662.   else SplitCommandLine(FileName, Result, Params);
  1663. end;
  1664. function ExtFilename(const FileName: string): string;
  1665. begin
  1666.   if (Pos(' ', FileName) > 0) and (FileName[1] <> '"') then
  1667.     Result := Format('"%s"', [FileName])
  1668.   else Result := FileName;
  1669. end;
  1670. constructor TFilenameEdit.Create(AOwner: TComponent);
  1671. begin
  1672.   inherited Create(AOwner);
  1673.   CreateEditDialog;
  1674. end;
  1675. procedure TFilenameEdit.CreateEditDialog;
  1676. var
  1677.   NewDialog: TOpenDialog;
  1678. begin
  1679.   case FDialogKind of
  1680.     dkOpen: NewDialog := TOpenDialog.Create(Self);
  1681. {$IFDEF RX_D3}
  1682.     dkOpenPicture: NewDialog := TOpenPictureDialog.Create(Self);
  1683.     dkSavePicture: NewDialog := TSavePictureDialog.Create(Self);
  1684. {$ENDIF}
  1685.     else {dkSave} NewDialog := TSaveDialog.Create(Self);
  1686.   end;
  1687.   try
  1688.     if FDialog <> nil then begin
  1689.       with NewDialog do begin
  1690.         DefaultExt := FDialog.DefaultExt;
  1691.         FileEditStyle := FDialog.FileEditStyle;
  1692.         FileName := FDialog.FileName;
  1693.         Filter := FDialog.Filter;
  1694.         FilterIndex := FDialog.FilterIndex;
  1695.         InitialDir := FDialog.InitialDir;
  1696.         HistoryList := FDialog.HistoryList;
  1697.         Files.Assign(FDialog.Files);
  1698.         Options := FDialog.Options;
  1699.         Title := FDialog.Title;
  1700.       end;
  1701.       FDialog.Free;
  1702.     end
  1703.     else begin
  1704.       NewDialog.Title := LoadStr(SBrowse);
  1705.       NewDialog.Filter := LoadStr(SDefaultFilter);
  1706.       NewDialog.Options := [ofHideReadOnly];
  1707.     end;
  1708.   finally
  1709.     FDialog := NewDialog;
  1710.   end;
  1711. end;
  1712. function TFilenameEdit.IsCustomTitle: Boolean;
  1713. begin
  1714.   Result := CompareStr(LoadStr(SBrowse), FDialog.Title) <> 0;
  1715. end;
  1716. function TFilenameEdit.IsCustomFilter: Boolean;
  1717. begin
  1718.   Result := CompareStr(LoadStr(SDefaultFilter), FDialog.Filter) <> 0;
  1719. end;
  1720. procedure TFilenameEdit.ButtonClick;
  1721. var
  1722.   Temp: string;
  1723.   Action: Boolean;
  1724. begin
  1725.   inherited ButtonClick;
  1726.   Temp := inherited Text;
  1727.   Action := True;
  1728.   Temp := ClipFilename(Temp);
  1729.   DoBeforeDialog(Temp, Action);
  1730.   if not Action then Exit;
  1731.   if ValidFileName(Temp) then
  1732.     try
  1733.       if DirExists(ExtractFilePath(Temp)) then
  1734.         SetInitialDir(ExtractFilePath(Temp));
  1735.       if (ExtractFileName(Temp) = '') or
  1736.         not ValidFileName(ExtractFileName(Temp)) then Temp := '';
  1737.       FDialog.FileName := Temp;
  1738.     except
  1739.       { ignore any exceptions }
  1740.     end;
  1741.   FDialog.HelpContext := Self.HelpContext;
  1742.   DisableSysErrors;
  1743.   try
  1744.     Action := FDialog.Execute;
  1745.   finally
  1746.     EnableSysErrors;
  1747.   end;
  1748.   if Action then Temp := FDialog.FileName;
  1749.   if CanFocus then SetFocus;
  1750.   DoAfterDialog(Temp, Action);
  1751.   if Action then begin
  1752.     inherited Text := ExtFilename(Temp);
  1753.     SetInitialDir(ExtractFilePath(FDialog.FileName));
  1754.   end;
  1755. end;
  1756. function TFilenameEdit.GetFileName: string;
  1757. begin
  1758.   Result := ClipFilename(inherited Text);
  1759. end;
  1760. procedure TFilenameEdit.SetFileName(const Value: string);
  1761. begin
  1762.   if (Value = '') or ValidFileName(ClipFilename(Value)) then begin
  1763.     inherited Text := ExtFilename(Value);
  1764.     ClearFileList;
  1765.   end
  1766.   else raise EComboEditError.CreateFmt(ResStr(SInvalidFilename), [Value]);
  1767. end;
  1768. {$IFDEF WIN32}
  1769. function TFilenameEdit.GetLongName: string;
  1770. begin
  1771.   Result := ShortToLongFileName(FileName);
  1772. end;
  1773. function TFilenameEdit.GetShortName: string;
  1774. begin
  1775.   Result := LongToShortFileName(FileName);
  1776. end;
  1777. {$ENDIF WIN32}
  1778. procedure TFilenameEdit.ClearFileList;
  1779. begin
  1780.   FDialog.Files.Clear;
  1781. end;
  1782. procedure TFilenameEdit.ReceptFileDir(const AFileName: string);
  1783. begin
  1784.   if FMultipleDirs then begin
  1785.     if FDialog.Files.Count = 0 then SetFileName(AFileName);
  1786.     FDialog.Files.Add(AFileName);
  1787.   end
  1788.   else SetFileName(AFileName);
  1789. end;
  1790. function TFilenameEdit.GetDialogFiles: TStrings;
  1791. begin
  1792.   Result := FDialog.Files;
  1793. end;
  1794. function TFilenameEdit.GetDefaultExt: TFileExt;
  1795. begin
  1796.   Result := FDialog.DefaultExt;
  1797. end;
  1798. function TFilenameEdit.GetFileEditStyle: TFileEditStyle;
  1799. begin
  1800.   Result := FDialog.FileEditStyle;
  1801. end;
  1802. function TFilenameEdit.GetFilter: string;
  1803. begin
  1804.   Result := FDialog.Filter;
  1805. end;
  1806. function TFilenameEdit.GetFilterIndex: Integer;
  1807. begin
  1808.   Result := FDialog.FilterIndex;
  1809. end;
  1810. function TFilenameEdit.GetInitialDir: string;
  1811. begin
  1812.   Result := FDialog.InitialDir;
  1813. end;
  1814. function TFilenameEdit.GetHistoryList: TStrings;
  1815. begin
  1816.   Result := FDialog.HistoryList;
  1817. end;
  1818. function TFilenameEdit.GetOptions: TOpenOptions;
  1819. begin
  1820.   Result := FDialog.Options;
  1821. end;
  1822. function TFilenameEdit.GetDialogTitle: string;
  1823. begin
  1824.   Result := FDialog.Title;
  1825. end;
  1826. procedure TFilenameEdit.SetDialogKind(Value: TFileDialogKind);
  1827. begin
  1828.   if FDialogKind <> Value then begin
  1829.     FDialogKind := Value;
  1830.     CreateEditDialog;
  1831.   end;
  1832. end;
  1833. procedure TFilenameEdit.SetDefaultExt(Value: TFileExt);
  1834. begin
  1835.   FDialog.DefaultExt := Value;
  1836. end;
  1837. procedure TFilenameEdit.SetFileEditStyle(Value: TFileEditStyle);
  1838. begin
  1839.   FDialog.FileEditStyle := Value;
  1840. end;
  1841. procedure TFilenameEdit.SetFilter(const Value: string);
  1842. begin
  1843.   FDialog.Filter := Value;
  1844. end;
  1845. procedure TFilenameEdit.SetFilterIndex(Value: Integer);
  1846. begin
  1847.   FDialog.FilterIndex := Value;
  1848. end;
  1849. procedure TFilenameEdit.SetInitialDir(const Value: string);
  1850. begin
  1851.   FDialog.InitialDir := Value;
  1852. end;
  1853. procedure TFilenameEdit.SetHistoryList(Value: TStrings);
  1854. begin
  1855.   FDialog.HistoryList := Value;
  1856. end;
  1857. procedure TFilenameEdit.SetOptions(Value: TOpenOptions);
  1858. begin
  1859.   if Value <> FDialog.Options then begin
  1860.     FDialog.Options := Value;
  1861.     FMultipleDirs := ofAllowMultiSelect in FDialog.Options;
  1862.     if not FMultipleDirs then ClearFileList;
  1863.   end;
  1864. end;
  1865. procedure TFilenameEdit.SetDialogTitle(const Value: string);
  1866. begin
  1867.   FDialog.Title := Value;
  1868. end;
  1869. { TDirectoryEdit }
  1870. constructor TDirectoryEdit.Create(AOwner: TComponent);
  1871. begin
  1872.   inherited Create(AOwner);
  1873.   FOptions := [];
  1874. end;
  1875. procedure TDirectoryEdit.ButtonClick;
  1876. var
  1877.   Temp: string;
  1878.   Action: Boolean;
  1879. begin
  1880.   inherited ButtonClick;
  1881.   Temp := Text;
  1882.   Action := True;
  1883.   DoBeforeDialog(Temp, Action);
  1884.   if not Action then Exit;
  1885.   if (Temp = '') then begin
  1886.     if (InitialDir <> '') then Temp := InitialDir
  1887.     else Temp := '';
  1888.   end;
  1889.   if not DirExists(Temp) then Temp := '';
  1890.   DisableSysErrors;
  1891.   try
  1892. {$IFDEF WIN32}
  1893.     if NewStyleControls and (DialogKind = dkWin32) then
  1894.       Action := BrowseDirectory(Temp, FDialogText, Self.HelpContext)
  1895.     else Action := SelectDirectory(Temp, FOptions, Self.HelpContext);
  1896. {$ELSE}
  1897.     Action := SelectDirectory(Temp, FOptions, Self.HelpContext);
  1898. {$ENDIF}
  1899.   finally
  1900.     EnableSysErrors;
  1901.   end;
  1902.   if CanFocus then SetFocus;
  1903.   DoAfterDialog(Temp, Action);
  1904.   if Action then begin
  1905.     SelText := '';
  1906.     if (Text = '') or not MultipleDirs then Text := Temp
  1907.     else Text := Text + ';' + Temp;
  1908.     if (Temp <> '') and DirExists(Temp) then InitialDir := Temp;
  1909.   end;
  1910. end;
  1911. procedure TDirectoryEdit.ReceptFileDir(const AFileName: string);
  1912. var
  1913.   Temp: string;
  1914. begin
  1915.   if FileExists(AFileName) then Temp := ExtractFilePath(AFileName)
  1916.   else Temp := AFileName;
  1917.   if (Text = '') or not MultipleDirs then Text := Temp
  1918.   else Text := Text + ';' + Temp;
  1919. end;
  1920. {$IFDEF WIN32}
  1921. function TDirectoryEdit.GetLongName: string;
  1922. var
  1923.   Temp: string;
  1924.   Pos: Integer;
  1925. begin
  1926.   if not MultipleDirs then Result := ShortToLongPath(Text)
  1927.   else begin
  1928.     Result := '';
  1929.     Pos := 1;
  1930.     while Pos <= Length(Text) do begin
  1931.       Temp := ShortToLongPath(ExtractSubstr(Text, Pos, [';']));
  1932.       if (Result <> '') and (Temp <> '') then Result := Result + ';';
  1933.       Result := Result + Temp;
  1934.     end;
  1935.   end;
  1936. end;
  1937. function TDirectoryEdit.GetShortName: string;
  1938. var
  1939.   Temp: string;
  1940.   Pos: Integer;
  1941. begin
  1942.   if not MultipleDirs then Result := LongToShortPath(Text)
  1943.   else begin
  1944.     Result := '';
  1945.     Pos := 1;
  1946.     while Pos <= Length(Text) do begin
  1947.       Temp := LongToShortPath(ExtractSubstr(Text, Pos, [';']));
  1948.       if (Result <> '') and (Temp <> '') then Result := Result + ';';
  1949.       Result := Result + Temp;
  1950.     end;
  1951.   end;
  1952. end;
  1953. {$ENDIF WIN32}
  1954. { TCustomDateEdit }
  1955. function NvlDate(DateValue, DefaultValue: TDateTime): TDateTime;
  1956. begin
  1957.   if DateValue = NullDate then Result := DefaultValue
  1958.   else Result := DateValue;
  1959. end;
  1960. constructor TCustomDateEdit.Create(AOwner: TComponent);
  1961. begin
  1962.   inherited Create(AOwner);
  1963.   FBlanksChar := ' ';
  1964.   FTitle := NewStr(LoadStr(SDateDlgTitle));
  1965.   FPopupColor := clBtnFace;
  1966.   FDefNumGlyphs := 2;
  1967.   FStartOfWeek := Mon;
  1968.   FWeekends := [Sun];
  1969.   FWeekendColor := clRed;
  1970.   FYearDigits := dyDefault;
  1971.   FCalendarHints := TStringList.Create;
  1972.   TStringList(FCalendarHints).OnChange := CalendarHintsChanged;
  1973.   ControlState := ControlState + [csCreating];
  1974.   try
  1975.     UpdateFormat;
  1976. {$IFDEF DEFAULT_POPUP_CALENDAR}
  1977.     FPopup := TPopupWindow(CreatePopupCalendar(Self
  1978.       {$IFDEF RX_D4}, BiDiMode {$ENDIF}));
  1979.     TPopupWindow(FPopup).OnCloseUp := PopupCloseUp;
  1980.     TPopupWindow(FPopup).Color := FPopupColor;
  1981. {$ENDIF DEFAULT_POPUP_CALENDAR}
  1982.     GlyphKind := gkDefault; { force update }
  1983.   finally
  1984.     ControlState := ControlState - [csCreating];
  1985.   end;
  1986. end;
  1987. destructor TCustomDateEdit.Destroy;
  1988. begin
  1989.   if FHooked then begin
  1990.     Application.UnhookMainWindow(FormatSettingsChange);
  1991.     FHooked := False;
  1992.   end;
  1993.   if FPopup <> nil then TPopupWindow(FPopup).OnCloseUp := nil;
  1994.   FPopup.Free;
  1995.   FPopup := nil;
  1996.   TStringList(FCalendarHints).OnChange := nil;
  1997.   FCalendarHints.Free;
  1998.   FCalendarHints := nil;
  1999.   DisposeStr(FTitle);
  2000.   inherited Destroy;
  2001. end;
  2002. procedure TCustomDateEdit.CreateWindowHandle(const Params: TCreateParams);
  2003. begin
  2004.   inherited CreateWindowHandle(Params);
  2005.   if Handle <> 0 then begin
  2006.     UpdateMask;
  2007.     if not (csDesigning in ComponentState) and not (IsLibrary or FHooked) then
  2008.     begin
  2009.       Application.HookMainWindow(FormatSettingsChange);
  2010.       FHooked := True;
  2011.     end;
  2012.   end;
  2013. end;
  2014. procedure TCustomDateEdit.DestroyWindowHandle;
  2015. begin
  2016.   if FHooked then begin
  2017.     Application.UnhookMainWindow(FormatSettingsChange);
  2018.     FHooked := False;
  2019.   end;
  2020.   inherited DestroyWindowHandle;
  2021. end;
  2022. procedure TCustomDateEdit.UpdateFormat;
  2023. begin
  2024.   FDateFormat := DefDateFormat(FourDigitYear);
  2025. end;
  2026. function TCustomDateEdit.GetDateFormat: string;
  2027. begin
  2028.   Result := FDateFormat;
  2029. end;
  2030. function TCustomDateEdit.TextStored: Boolean;
  2031. begin
  2032.   Result := not IsEmptyStr(Text, [#0, ' ', DateSeparator, FBlanksChar]);
  2033. end;
  2034. procedure TCustomDateEdit.CheckValidDate;
  2035. begin
  2036.   if TextStored then
  2037.     try
  2038.       FFormatting := True;
  2039.       try
  2040.         SetDate(StrToDateFmt(FDateFormat, Text));
  2041.       finally
  2042.         FFormatting := False;
  2043.       end;
  2044.     except
  2045.       if CanFocus then SetFocus;
  2046.       raise;
  2047.     end;
  2048. end;
  2049. procedure TCustomDateEdit.Change;
  2050. begin
  2051.   if not FFormatting then inherited Change;
  2052. end;
  2053. procedure TCustomDateEdit.CMExit(var Message: TCMExit);
  2054. begin
  2055.   if not (csDesigning in ComponentState) and CheckOnExit then
  2056.     CheckValidDate;
  2057.   inherited;
  2058. end;
  2059. function TCustomDateEdit.GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap;
  2060. begin
  2061.   DestroyNeeded := False;
  2062.   if DateBitmap = nil then begin
  2063.     DateBitmap := TBitmap.Create;
  2064.     DateBitmap.Handle := LoadBitmap(hInstance, sDateBmp);
  2065.   end;
  2066.   Result := DateBitmap;
  2067. end;
  2068. procedure TCustomDateEdit.SetBlanksChar(Value: Char);
  2069. begin
  2070.   if Value <> FBlanksChar then begin
  2071.     if (Value < ' ') then Value := ' ';
  2072.     FBlanksChar := Value;
  2073.     UpdateMask;
  2074.   end;
  2075. end;
  2076. procedure TCustomDateEdit.UpdateMask;
  2077. var
  2078.   DateValue: TDateTime;
  2079.   OldFormat: string[10];
  2080. begin
  2081.   DateValue := GetDate;
  2082.   OldFormat := FDateFormat;
  2083.   UpdateFormat;
  2084.   if (GetDateMask <> EditMask) or (OldFormat <> FDateFormat) then begin
  2085.     { force update }
  2086.     EditMask := '';
  2087.     EditMask := GetDateMask;
  2088.   end;
  2089.   UpdatePopup;
  2090.   SetDate(DateValue);
  2091. end;
  2092. function TCustomDateEdit.FormatSettingsChange(var Message: TMessage): Boolean;
  2093. begin
  2094.   Result := False;
  2095.   if (Message.Msg = WM_WININICHANGE)
  2096.     {$IFDEF WIN32} and Application.UpdateFormatSettings {$ENDIF} then
  2097.     UpdateMask;
  2098. end;
  2099. function TCustomDateEdit.FourDigitYear: Boolean;
  2100. begin
  2101.   Result := (FYearDigits = dyFour) or ((FYearDigits = dyDefault) and
  2102.     (DateUtil.FourDigitYear));
  2103. end;
  2104. function TCustomDateEdit.GetDateMask: string;
  2105. begin
  2106.   Result := DefDateMask(FBlanksChar, FourDigitYear);
  2107. end;
  2108. function TCustomDateEdit.GetDate: TDateTime;
  2109. begin
  2110.   if DefaultToday then Result := SysUtils.Date
  2111.   else Result := NullDate;
  2112.   Result := StrToDateFmtDef(FDateFormat, Text, Result);
  2113. end;
  2114. procedure TCustomDateEdit.SetDate(Value: TDateTime);
  2115. var
  2116.   D: TDateTime;
  2117. begin
  2118.   if not ValidDate(Value) or (Value = NullDate) then begin
  2119.     if DefaultToday then Value := SysUtils.Date
  2120.     else Value := NullDate;
  2121.   end;
  2122.   D := Date;
  2123.   if Value = NullDate then Text := ''
  2124.   else Text := FormatDateTime(FDateFormat, Value);
  2125.   Modified := D <> Date;
  2126. end;
  2127. procedure TCustomDateEdit.ApplyDate(Value: TDateTime);
  2128. begin
  2129.   SetDate(Value);
  2130.   SelectAll;
  2131. end;
  2132. function TCustomDateEdit.GetDialogTitle: string;
  2133. begin
  2134.   Result := FTitle^;
  2135. end;
  2136. procedure TCustomDateEdit.SetDialogTitle(const Value: string);
  2137. begin
  2138.   AssignStr(FTitle, Value);
  2139. end;
  2140. function TCustomDateEdit.IsCustomTitle: Boolean;
  2141. begin
  2142.   Result := (CompareStr(LoadStr(SDateDlgTitle), DialogTitle) <> 0) and
  2143.     (FTitle <> NullStr);
  2144. end;
  2145. procedure TCustomDateEdit.UpdatePopup;
  2146. begin
  2147.   if FPopup <> nil then SetupPopupCalendar(FPopup, FStartOfWeek,
  2148.     FWeekends, FWeekendColor, FCalendarHints, FourDigitYear);
  2149. end;
  2150. procedure TCustomDateEdit.SetYearDigits(Value: TYearDigits);
  2151. begin
  2152.   if FYearDigits <> Value then begin
  2153.     FYearDigits := Value;
  2154.     UpdateMask;
  2155.   end;
  2156. end;
  2157. function TCustomDateEdit.GetPopupColor: TColor;
  2158. begin
  2159.   if FPopup <> nil then Result := TPopupWindow(FPopup).Color
  2160.   else Result := FPopupColor;
  2161. end;
  2162. procedure TCustomDateEdit.SetPopupColor(Value: TColor);
  2163. begin
  2164.   if Value <> PopupColor then begin
  2165.     if FPopup <> nil then TPopupWindow(FPopup).Color := Value;
  2166.     FPopupColor := Value;
  2167.   end;
  2168. end;
  2169. function TCustomDateEdit.GetCalendarStyle: TCalendarStyle;
  2170. begin
  2171.   if FPopup <> nil then Result := csPopup
  2172.   else Result := csDialog;
  2173. end;
  2174. procedure TCustomDateEdit.SetCalendarStyle(Value: TCalendarStyle);
  2175. begin
  2176.   if Value <> CalendarStyle then begin
  2177.     case Value of
  2178.       csPopup:
  2179.         begin
  2180.           if FPopup = nil then
  2181.             FPopup := TPopupWindow(CreatePopupCalendar(Self
  2182.               {$IFDEF RX_D4}, BiDiMode {$ENDIF}));
  2183.           TPopupWindow(FPopup).OnCloseUp := PopupCloseUp;
  2184.           TPopupWindow(FPopup).Color := FPopupColor;
  2185.           UpdatePopup;
  2186.         end;
  2187.       csDialog:
  2188.         begin
  2189.           FPopup.Free;
  2190.           FPopup := nil;
  2191.         end;
  2192.     end;
  2193.   end;
  2194. end;
  2195. procedure TCustomDateEdit.SetCalendarHints(Value: TStrings);
  2196. begin
  2197.   FCalendarHints.Assign(Value);
  2198. end;
  2199. procedure TCustomDateEdit.CalendarHintsChanged(Sender: TObject);
  2200. begin
  2201.   TStringList(FCalendarHints).OnChange := nil;
  2202.   try
  2203.     while (FCalendarHints.Count > 4) do
  2204.       FCalendarHints.Delete(FCalendarHints.Count - 1);
  2205.   finally
  2206.     TStringList(FCalendarHints).OnChange := CalendarHintsChanged;
  2207.   end;
  2208.   if not (csDesigning in ComponentState) then UpdatePopup;
  2209. end;
  2210. procedure TCustomDateEdit.SetWeekendColor(Value: TColor);
  2211. begin
  2212.   if Value <> FWeekendColor then begin
  2213.     FWeekendColor := Value;
  2214.     UpdatePopup;
  2215.   end;
  2216. end;
  2217. procedure TCustomDateEdit.SetWeekends(Value: TDaysOfWeek);
  2218. begin
  2219.   if Value <> FWeekends then begin
  2220.     FWeekends := Value;
  2221.     UpdatePopup;
  2222.   end;
  2223. end;
  2224. procedure TCustomDateEdit.SetStartOfWeek(Value: TDayOfWeekName);
  2225. begin
  2226.   if Value <> FStartOfWeek then begin
  2227.     FStartOfWeek := Value;
  2228.     UpdatePopup;
  2229.   end;
  2230. end;
  2231. procedure TCustomDateEdit.KeyDown(var Key: Word; Shift: TShiftState);
  2232. begin
  2233.   if (Key in [VK_PRIOR, VK_NEXT, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN,
  2234.     VK_ADD, VK_SUBTRACT]) and
  2235.     PopupVisible then
  2236.   begin
  2237.     TPopupWindow(FPopup).KeyDown(Key, Shift);
  2238.     Key := 0;
  2239.   end
  2240.   else if (Shift = []) and DirectInput then begin
  2241.     case Key of
  2242.       VK_ADD:
  2243.         begin
  2244.           ApplyDate(NvlDate(Date, Now) + 1);
  2245.           Key := 0;
  2246.         end;
  2247.       VK_SUBTRACT:
  2248.         begin
  2249.           ApplyDate(NvlDate(Date, Now) - 1);
  2250.           Key := 0;
  2251.         end;
  2252.     end;
  2253.   end;
  2254.   inherited KeyDown(Key, Shift);
  2255. end;
  2256. procedure TCustomDateEdit.KeyPress(var Key: Char);
  2257. begin
  2258.   if (Key in ['T', 't', '+', '-']) and PopupVisible then begin
  2259.     TPopupWindow(FPopup).KeyPress(Key);
  2260.     Key := #0;
  2261.   end
  2262.   else if DirectInput then begin
  2263.     case Key of
  2264.       'T', 't':
  2265.         begin
  2266.           ApplyDate(Trunc(Now));
  2267.           Key := #0;
  2268.         end;
  2269.       '+', '-':
  2270.         begin
  2271.           Key := #0;
  2272.         end;
  2273.     end;
  2274.   end;
  2275.   inherited KeyPress(Key);
  2276. end;
  2277. procedure TCustomDateEdit.ButtonClick;
  2278. var
  2279.   D: TDateTime;
  2280.   Action: Boolean;
  2281. begin
  2282.   inherited ButtonClick;
  2283.   if CalendarStyle = csDialog then begin
  2284.     D := Self.Date;
  2285.     Action := SelectDate(D, DialogTitle, FStartOfWeek, FWeekends,
  2286.       FWeekendColor, FCalendarHints);
  2287.     if CanFocus then SetFocus;
  2288.     if Action then begin
  2289.       if Assigned(FOnAcceptDate) then FOnAcceptDate(Self, D, Action);
  2290.       if Action then begin
  2291.         Self.Date := D;
  2292.         if FFocused then inherited SelectAll;
  2293.       end;
  2294.     end;
  2295.   end;
  2296. end;
  2297. {$IFDEF WIN32}
  2298. function TCustomDateEdit.AcceptPopup(var Value: Variant): Boolean;
  2299. {$ELSE}
  2300. function TCustomDateEdit.AcceptPopup(var Value: string): Boolean;
  2301. {$ENDIF}
  2302. var
  2303.   D: TDateTime;
  2304. begin
  2305.   Result := True;
  2306.   if Assigned(FOnAcceptDate) then begin
  2307. {$IFDEF WIN32}
  2308.     if VarIsNull(Value) or VarIsEmpty(Value) then D := NullDate
  2309.     else
  2310.       try
  2311.         D := VarToDateTime(Value);
  2312.       except
  2313.         if DefaultToday then D := SysUtils.Date else D := NullDate;
  2314.       end;
  2315. {$ELSE}
  2316.     if DefaultToday then D := SysUtils.Date else D := NullDate;
  2317.     D := StrToDateDef(Value, D);
  2318. {$ENDIF}
  2319.     FOnAcceptDate(Self, D, Result);
  2320. {$IFDEF WIN32}
  2321.     if Result then Value := VarFromDateTime(D);
  2322. {$ELSE}
  2323.     if Result then Value := FormatDateTime(FDateFormat, D);
  2324. {$ENDIF}
  2325.   end;
  2326. end;
  2327. {$IFDEF WIN32}
  2328. procedure TCustomDateEdit.SetPopupValue(const Value: Variant);
  2329. begin
  2330.   inherited SetPopupValue(StrToDateFmtDef(FDateFormat, VarToStr(Value),
  2331.     SysUtils.Date));
  2332. end;
  2333. procedure TCustomDateEdit.AcceptValue(const Value: Variant);
  2334. begin
  2335.   SetDate(VarToDateTime(Value));
  2336.   UpdatePopupVisible;
  2337.   if Modified then inherited Change;
  2338. end;
  2339. {$ENDIF}
  2340. { TDateEdit }
  2341. constructor TDateEdit.Create(AOwner: TComponent);
  2342. begin
  2343.   inherited Create(AOwner);
  2344.   UpdateMask;
  2345. end;
  2346. { Utility routines }
  2347. procedure DateFormatChanged;
  2348.   procedure IterateControls(AControl: TWinControl);
  2349.   var
  2350.     I: Integer;
  2351.   begin
  2352.     with AControl do
  2353.       for I := 0 to ControlCount - 1 do begin
  2354.         if Controls[I] is TCustomDateEdit then
  2355.           TCustomDateEdit(Controls[I]).UpdateMask
  2356.         else if Controls[I] is TWinControl then
  2357.           IterateControls(TWinControl(Controls[I]));
  2358.       end;
  2359.   end;
  2360. var
  2361.   I: Integer;
  2362. begin
  2363.   if Screen <> nil then
  2364.     for I := 0 to Screen.FormCount - 1 do
  2365.       IterateControls(Screen.Forms[I]);
  2366. end;
  2367. procedure DestroyLocals; far;
  2368. begin
  2369.   FileBitmap.Free;
  2370.   FileBitmap := nil;
  2371.   DateBitmap.Free;
  2372.   DateBitmap := nil;
  2373. end;
  2374. {$IFDEF WIN32}
  2375. initialization
  2376. finalization
  2377.   DestroyLocals;
  2378. {$ELSE}
  2379. initialization
  2380.   AddExitProc(DestroyLocals);
  2381. {$ENDIF}
  2382. end.