cxtimeedit.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,149 行 · 第 1/3 页

PAS
1,149
字号

{********************************************************************}
{                                                                    }
{       Developer Express Visual Component Library                   }
{       ExpressEditors                                               }
{                                                                    }
{       Copyright (c) 1998-2008 Developer Express Inc.               }
{       ALL RIGHTS RESERVED                                          }
{                                                                    }
{   The entire contents of this file is protected by U.S. and        }
{   International Copyright Laws. Unauthorized reproduction,         }
{   reverse-engineering, and distribution of all or any portion of   }
{   the code contained in this file is strictly prohibited and may   }
{   result in severe civil and criminal penalties and will be        }
{   prosecuted to the maximum extent possible under the law.         }
{                                                                    }
{   RESTRICTIONS                                                     }
{                                                                    }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES            }
{   (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE     }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS    }
{   LICENSED TO DISTRIBUTE THE EXPRESSEDITORS AND ALL                }
{   ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{                                                                    }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED       }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE         }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE        }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT   }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                       }
{                                                                    }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON        }
{   ADDITIONAL RESTRICTIONS.                                         }
{                                                                    }
{********************************************************************}

unit cxTimeEdit;

{$I cxVer.inc}

interface

uses
{$IFDEF DELPHI6}
  Variants,
{$ENDIF}
  Windows, 
  Classes, Controls, SysUtils, cxClasses, cxContainer, cxDataUtils, cxDateUtils,
  cxEdit, cxFormats, cxMaskEdit, cxSpinEdit, cxVariants, cxFilterControlUtils;

type
  TcxTimeEditZoneKind = (tzHour, tzMin, tzSec, tzTimeSuffix);

  TcxTimeEditZoneInfo = record
    Kind: TcxTimeEditZoneKind;
    Start, Length: Integer;
    TimeSuffixKind: TcxTimeSuffixKind;
    Use24HourFormat: Boolean;
  end;

  { TcxTimeEditMaskMode }

  TcxTimeEditMaskMode = class(TcxMaskEditStandardMode)
  protected
    function GetBlank(APos: Integer): Char; override;
  end;

  { TcxCustomTimeEditProperties }

  TcxCustomTimeEdit = class;
  TcxTimeEditTimeFormat = (tfHourMinSec, tfHourMin, tfHour);

  TcxCustomTimeEditProperties = class(TcxCustomSpinEditProperties)
  private
    FAutoCorrectHours: Boolean;
    FShowDate: Boolean;
    FTimeFormat: TcxTimeEditTimeFormat;
    FUse24HourFormat: Boolean;
    FUseTimeFormatWhenUnfocused: Boolean;
    procedure SetAutoCorrectHours(Value: Boolean);
    procedure SetUse24HourFormat(Value: Boolean);
    procedure SetShowDate(Value: Boolean);
    procedure SetTimeFormat(Value: TcxTimeEditTimeFormat);
    procedure SetUseTimeFormatWhenUnfocused(Value: Boolean);
  protected
    function DefaultFocusedDisplayValue: TcxEditValue; override;
    function ExtendValueUpToBound: Boolean; override;
    procedure FormatChanged; override;
    function GetDisplayFormatOptions: TcxEditDisplayFormatOptions; override;
    function GetModeClass(AMaskKind: TcxEditMaskKind): TcxMaskEditCustomModeClass; override;
    procedure GetTimeZoneInfo(APos: Integer;
      out AInfo: TcxTimeEditZoneInfo); virtual;
    function IsDisplayValueNumeric: Boolean; override;
    function IsEditValueNumeric: Boolean; override;
    function PrepareValue(const AValue: TcxEditValue): Variant; override;
    function PreserveSelection: Boolean; override;
    function GetEditingPlace(APos: Integer): TcxTimeEditZoneKind;
    function GetTimePartLength(AKind: TcxTimeEditZoneKind): Integer; virtual;
    function GetTimePartPos(AKind: TcxTimeEditZoneKind): Integer; virtual;
    function GetTimeSuffixKind: TcxTimeSuffixKind; virtual;
    procedure UpdateEditMask;
  public
    constructor Create(AOwner: TPersistent); override;
    procedure Assign(Source: TPersistent); override;
    class function GetContainerClass: TcxContainerClass; override;
    function GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource; override;
    function IsDisplayValueValid(var DisplayValue: TcxEditValue; AEditFocused: Boolean): Boolean; override;
    function IsEditValueValid(var EditValue: TcxEditValue; AEditFocused: Boolean): Boolean; override;
    procedure PrepareDisplayValue(const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue;
      AEditFocused: Boolean); override;
    procedure ValidateDisplayValue(var ADisplayValue: TcxEditValue;
      var AErrorText: TCaption; var AError: Boolean;
      AEdit: TcxCustomEdit); override;
    // !!!
    property AutoCorrectHours: Boolean read FAutoCorrectHours
      write SetAutoCorrectHours default True;
    property ShowDate: Boolean read FShowDate write SetShowDate default False;
    property TimeFormat: TcxTimeEditTimeFormat read FTimeFormat write SetTimeFormat default tfHourMinSec;
    property Use24HourFormat: Boolean read FUse24HourFormat write SetUse24HourFormat default True;
    property UseTimeFormatWhenUnfocused: Boolean read FUseTimeFormatWhenUnfocused
      write SetUseTimeFormatWhenUnfocused default True;
  end;

  { TcxTimeEditProperties }

  TcxTimeEditProperties = class(TcxCustomTimeEditProperties)
  published
    property Alignment;
    property AssignedValues;
    property AutoCorrectHours;
    property AutoSelect;
    property BeepOnError;
    property Circular;
    property ClearKey;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property ImmediatePost;
    property ReadOnly;
    property ShowDate;
    property TimeFormat;
    property UseCtrlIncrement;
    property UseLeftAlignmentOnEditing;
    property Use24HourFormat;
    property UseTimeFormatWhenUnfocused;
    property ValidateOnEnter;
    property OnChange;
    property OnEditValueChanged;
    property OnValidate;
  end;

  { TcxCustomTimeEdit }

  TcxCustomTimeEdit = class(TcxCustomSpinEdit)
  private
    FSavedDate: TDate;
    function GetProperties: TcxCustomTimeEditProperties;
    function GetActiveProperties: TcxCustomTimeEditProperties;
    function GetTime: TTime;
    procedure SetProperties(Value: TcxCustomTimeEditProperties);
    procedure SetTime(Value: TTime);
  protected
    function GetIncrement(AButton: TcxSpinEditButton): Double; override;
    function GetValue: Variant; override;
    function IncrementValueToStr(const AValue: TcxEditValue): string; override;
    procedure Initialize; override;
    function InternalGetEditingValue: TcxEditValue; override;
    function InternalGetText: string; override;
    procedure InternalSetDisplayValue(const Value: TcxEditValue); override;
    procedure InternalSetEditValue(const Value: TcxEditValue;
      AValidateEditValue: Boolean); override;
    function InternalSetText(const Value: string): Boolean; override;
    function IsValidChar(AChar: Char): Boolean; override;
    function IsCharValidForPos(var AChar: Char; APos: Integer): Boolean; override;
    procedure PropertiesChanged(Sender: TObject); override;
    procedure SetValue(const Value: Variant); override;
    function EditingPlace: TcxTimeEditZoneKind;
  public
    procedure Clear; override;
    class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
    function Increment(AButton: TcxSpinEditButton): Boolean; override;
    procedure PrepareEditValue(const ADisplayValue: TcxEditValue;
      out EditValue: TcxEditValue; AEditFocused: Boolean); override;
    property ActiveProperties: TcxCustomTimeEditProperties read GetActiveProperties;
    property Properties: TcxCustomTimeEditProperties read GetProperties
      write SetProperties;
    property Time: TTime read GetTime write SetTime stored False;
  end;

  { TcxTimeEdit }

  TcxTimeEdit = class(TcxCustomTimeEdit)
  private
    function GetActiveProperties: TcxTimeEditProperties;
    function GetProperties: TcxTimeEditProperties;
    procedure SetProperties(Value: TcxTimeEditProperties);
  public
    class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
    property ActiveProperties: TcxTimeEditProperties read GetActiveProperties;
  published
    property Anchors;
    property AutoSize;
    property BeepOnEnter;
    property Constraints;
    property DragMode;
    property EditValue;
    property Enabled;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property Properties: TcxTimeEditProperties read GetProperties write SetProperties;
    property ShowHint;
    property Style;
    property StyleDisabled;
    property StyleFocused;
    property StyleHot;
    property TabOrder;
    property TabStop;
    property Time;
    property Visible;
    property DragCursor;
    property DragKind;
    property ImeMode;
    property ImeName;
    property OnClick;
{$IFDEF DELPHI5}
    property OnContextPopup;
{$ENDIF}
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEditing;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
    property OnEndDock;
    property OnStartDock;
  end;

  { TcxFilterTimeEditHelper }

  TcxFilterTimeEditHelper = class(TcxFilterSpinEditHelper)
  protected
    class procedure InitializeEdit(AEdit: TcxCustomEdit;
      AEditProperties: TcxCustomEditProperties); override;
  public
    class function GetFilterEditClass: TcxCustomEditClass; override;
  end;

function IsCharValidForTimeEdit(ATimeEdit: TcxCustomMaskEdit;
  var AChar: Char; APos: Integer;
  const ATimeZoneInfo: TcxTimeEditZoneInfo): Boolean;

implementation

uses
  StdCtrls, cxControls, cxEditConsts, cxTextEdit{$IFDEF DELPHI6}, DateUtils{$ENDIF},
  Forms, Dialogs, Math;

type

  { TcxTimeEditFormatListener }

  TcxTimeEditFormatListener = class(TcxInterfacedPersistent, IcxFormatControllerListener)
  protected
    procedure FormatChanged;
  public
    constructor Create(AOwner: TPersistent); override;
    destructor Destroy; override;
  end;

var
  cxTimeEditHalfDayIncrement,
  cxTimeEditOneHourIncrement,
  cxTimeEditOneMinIncrement,
  cxTimeEditOneSecIncrement: Double;
  FTimeEditFormatListener: TcxTimeEditFormatListener;

  cxTimeEditFormats: array [TcxTimeEditTimeFormat, Boolean, 0 .. 1] of string = (
    (('hh:nn:ss ampm', '00:00:00 LL;1;0'), ('hh:nn:ss', '00:00:00;1;0')),
    (('hh:nn ampm', '00:00 LL;1;0'), ('hh:nn', '00:00;1;0')),
    (('hh ampm', '00 LL;1;0'), ('hh', '00;1;0'))
  );

function EqualChars(C1, C2: Char): Boolean;
begin
  Result := UpperCase(C1) = UpperCase(C2);
end;

function GetFirstDifferenceIndex(const S1, S2: string): Integer;
var
  ACount, I: Integer;
begin
  Result := -1;
  ACount := Min(Length(S1), Length(S2));
  for I := 1 to ACount do
    if not EqualChars(S1[I], S2[I]) then
    begin
      Result := I;
      Break;
    end;
  if (Result = -1) and (Length(S1) <> Length(S2)) then
    Result := ACount + 1;
end;

procedure GetTimeSuffixes(ATimeSuffixKind: TcxTimeSuffixKind;
  out ATimeSuffix1, ATimeSuffix2: string);
begin
  case ATimeSuffixKind of
    tskAP:
      begin
        ATimeSuffix1 := 'A';
        ATimeSuffix2 := 'P';
      end;
    tskAMPM:
      begin
        ATimeSuffix1 := 'AM';
        ATimeSuffix2 := 'PM';
      end;
    tskAMPMString:
      begin
        ATimeSuffix1 := TimeAMString;
        ATimeSuffix2 := TimePMString;
      end;
  end;
end;

function IsCharValidForTimeEdit(ATimeEdit: TcxCustomMaskEdit;
  var AChar: Char; APos: Integer;
  const ATimeZoneInfo: TcxTimeEditZoneInfo): Boolean;

  procedure GetTimeValueItemValueRange(out AMinValue, AMaxValue: Integer);
  begin
    AMinValue := 0;
    if ATimeZoneInfo.Kind = tzHour then
      if not ATimeZoneInfo.Use24HourFormat then
      begin
        AMinValue := 1;
        AMaxValue := 12;
      end
      else
        AMaxValue := 23
    else
      AMaxValue := 59;
  end;

  procedure SetEditText(const AText: string; APos: Integer);
  var
    ASelStart: Integer;
    S: string;
  begin
    S := ATimeEdit.Text;
    Delete(S, APos, Length(AText));
    Insert(AText, S, APos);
    ASelStart := ATimeEdit.SelStart;
    TCustomEdit(ATimeEdit.InnerControl).Text := S;
    ATimeEdit.SelStart := ASelStart;
  end;

  function CheckTimeSuffix: Boolean;
  var
    AFirstDifferenceIndex: Integer;
    ATimeSuffix, ATimeSuffix1, ATimeSuffix2: string;
  begin
    GetTimeSuffixes(ATimeZoneInfo.TimeSuffixKind, ATimeSuffix1, ATimeSuffix2);
    AFirstDifferenceIndex := ATimeZoneInfo.Start +
      GetFirstDifferenceIndex(ATimeSuffix1, ATimeSuffix2) - 1;
    if APos < AFirstDifferenceIndex then
    begin
      Result := EqualChars(AChar, ATimeSuffix1[APos - ATimeZoneInfo.Start + 1]);
      if Result then
        AChar := ATimeSuffix1[APos - ATimeZoneInfo.Start + 1];
    end
    else

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?