cxformats.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,256 行 · 第 1/3 页
PAS
1,256 行
{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ Express Cross Platform Library classes }
{ }
{ Copyright (c) 2000-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 EXPRESSCROSSPLATFORMLIBRARY 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 cxFormats;
{$I cxVer.inc}
interface
uses
Windows, Messages,
Classes, cxDateUtils;
type
IcxFormatControllerListener = interface
['{A7F2F6D3-1A7D-4295-A6E6-9297BD83D0DE}']
procedure FormatChanged;
end;
IcxFormatControllerListener2 = interface
['{5E33A2A7-0C77-415F-A359-112103E54937}']
procedure TimeChanged;
end;
TcxDateTimeEditMaskKind = (dtmkDate, dtmkTime, dtmkDateTime);
TcxDateTimeFormatItemKind = (
dtikString,
dtikYear, // YY YYYY
dtikMonth, // M MM MMM MMMM
dtikDay, // D DD DDD DDDD
dtikHour, // 12H 12HH 24H 24HH
dtikMin, // N NN
dtikSec, // S SS
dtikMSec, // Z ZZ ZZZ
dtikTimeSuffix, // A/P AM/PM AMPM (lower, upper, or mixed case)
dtikDateSeparator,
dtikTimeSeparator
);
TcxTimeSuffixKind = (tskAP, tskAMPM, tskAMPMString);
TcxDateTimeFormatItem = record
Kind: TcxDateTimeFormatItemKind;
Data: string;
end;
TcxDateTimeFormatInfo = record
DefinedItems: array[TcxDateTimeFormatItemKind] of Boolean;
Items: array of TcxDateTimeFormatItem;
end;
TcxDateTimeFormatItemInfo = record
Kind: TcxDateTimeFormatItemKind;
ItemZoneStart, ItemZoneLength: Integer;
TimeSuffixKind: TcxTimeSuffixKind;
end;
{ TcxFormatController }
TcxFormatController = class
private
FAssignedCurrencyFormat: Boolean;
FAssignedRegExprDateEditMask: Boolean;
FAssignedRegExprDateTimeEditMask: Boolean;
FAssignedStandardDateEditMask: Boolean;
FAssignedStandardDateTimeEditMask: Boolean;
FAssignedStartOfWeek: Boolean;
FCurrencyFormat: string;
FDateEditFormat: string;
FDateEditMask: string;
FDateFormatInfo: TcxDateTimeFormatInfo;
FDateTimeFormatInfo: TcxDateTimeFormatInfo;
FFirstWeekOfYear: TcxFirstWeekOfYear;
FList: TList;
FLockCount: Integer;
FMaskedDateEditFormat: string;
FMaskedDateTimeEditFormat: string;
FRegExprDateEditMask: string;
FRegExprDateTimeEditMask: string;
FStandardDateEditMask: string;
FStandardDateTimeEditMask: string;
FStartOfWeek: TDayOfWeek;
FTimeFormatInfo: TcxDateTimeFormatInfo;
FUseDelphiDateTimeFormats: Boolean;
procedure CalculateDateEditMasks(AUseSmartInputWhenRegExpr: Boolean);
function GetCurrencyFormat: string;
function GetDateEditFormat(AIsMasked: Boolean): string;
function GetDateTimeDisplayFormat(AMaskKind: TcxDateTimeEditMaskKind): string;
class function GetDateTimeFormatItemStandardMaskZoneLength(
const AItem: TcxDateTimeFormatItem): Integer;
function GetStartOfWeek: TDayOfWeek;
function InternalGetDateTimeEditRegExprMask(
AFormatInfo: TcxDateTimeFormatInfo;
AMaskKind: TcxDateTimeEditMaskKind): string;
function InternalGetDateTimeEditStandardMask(
AFormatInfo: TcxDateTimeFormatInfo;
AMaskKind: TcxDateTimeEditMaskKind): string;
function InternalGetMaskedDateEditFormat(
AFormatInfo: TcxDateTimeFormatInfo): string;
procedure SetAssignedCurrencyFormat(Value: Boolean);
procedure SetAssignedRegExprDateEditMask(Value: Boolean);
procedure SetAssignedRegExprDateTimeEditMask(Value: Boolean);
procedure SetAssignedStandardDateEditMask(Value: Boolean);
procedure SetAssignedStandardDateTimeEditMask(Value: Boolean);
procedure SetAssignedStartOfWeek(Value: Boolean);
procedure SetCurrencyFormat(const Value: string);
procedure SetFirstWeekOfYear(Value: TcxFirstWeekOfYear);
procedure SetRegExprDateEditMask(const Value: string);
procedure SetRegExprDateTimeEditMask(const Value: string);
procedure SetStandardDateEditMask(const Value: string);
procedure SetStandardDateTimeEditMask(const Value: string);
procedure SetStartOfWeek(Value: TDayOfWeek);
procedure SetUseDelphiDateTimeFormats(Value: Boolean);
protected
FWindow: HWND;
procedure MainWndProc(var Message: TMessage);
procedure WndProc(var Message: TMessage); virtual;
procedure FormatChanged;
procedure TimeChanged;
public
constructor Create;
destructor Destroy; override;
procedure AddListener(AListener: IcxFormatControllerListener); virtual;
procedure BeginUpdate;
procedure EndUpdate;
procedure GetFormats;
class function GetDateTimeFormatItemStandardMaskInfo(
const AFormatInfo: TcxDateTimeFormatInfo; APos: Integer;
out AItemInfo: TcxDateTimeFormatItemInfo): Boolean;
function GetDateTimeStandardMaskStringLength(
const AFormatInfo: TcxDateTimeFormatInfo): Integer;
procedure NotifyListeners;
procedure RemoveListener(AListener: IcxFormatControllerListener); virtual;
property AssignedCurrencyFormat: Boolean read FAssignedCurrencyFormat write SetAssignedCurrencyFormat;
property AssignedRegExprDateEditMask: Boolean read FAssignedRegExprDateEditMask write SetAssignedRegExprDateEditMask;
property AssignedRegExprDateTimeEditMask: Boolean read FAssignedRegExprDateTimeEditMask write SetAssignedRegExprDateTimeEditMask;
property AssignedStandardDateEditMask: Boolean read FAssignedStandardDateEditMask write SetAssignedStandardDateEditMask;
property AssignedStandardDateTimeEditMask: Boolean read FAssignedStandardDateTimeEditMask write SetAssignedStandardDateTimeEditMask;
property AssignedStartOfWeek: Boolean read FAssignedStartOfWeek write SetAssignedStartOfWeek;
property CurrencyFormat: string read FCurrencyFormat write SetCurrencyFormat;
property DateEditFormat: string read FDateEditFormat;
property DateEditMask: string read FDateEditMask;
property DateFormatInfo: TcxDateTimeFormatInfo read FDateFormatInfo;
property DateTimeFormatInfo: TcxDateTimeFormatInfo read FDateTimeFormatInfo;
property FirstWeekOfYear: TcxFirstWeekOfYear read FFirstWeekOfYear write SetFirstWeekOfYear;
property MaskedDateEditFormat: string read FMaskedDateEditFormat;
property MaskedDateTimeEditFormat: string read FMaskedDateTimeEditFormat;
property RegExprDateEditMask: string read FRegExprDateEditMask write SetRegExprDateEditMask;
property RegExprDateTimeEditMask: string read FRegExprDateTimeEditMask write SetRegExprDateTimeEditMask;
property StandardDateEditMask: string read FStandardDateEditMask write SetStandardDateEditMask;
property StandardDateTimeEditMask: string read FStandardDateTimeEditMask write SetStandardDateTimeEditMask;
property StartOfWeek: TDayOfWeek read FStartOfWeek write SetStartOfWeek;
property TimeFormatInfo: TcxDateTimeFormatInfo read FTimeFormatInfo;
property UseDelphiDateTimeFormats: Boolean read FUseDelphiDateTimeFormats write SetUseDelphiDateTimeFormats;
end;
function cxFormatController: TcxFormatController;
function GetCharString(C: Char; ACount: Integer): string;
implementation
uses
SysUtils, Forms, cxClasses;
var
FcxFormatController: TcxFormatController;
function GetCharString(C: Char; ACount: Integer): string;
var
I: Integer;
begin
Result := '';
for I := 1 to ACount do
Result := Result + C;
end;
function CharLength(const S: string; Index: Integer): Integer;
begin
Result := 1;
assert((Index > 0) and (Index <= Length(S)));
if SysLocale.FarEast and (S[Index] in LeadBytes) then
Result := cxStrCharLength(S, Index);
end;
procedure GetDateTimeFormatInfo(const AFormat: string;
var AFormatInfo: TcxDateTimeFormatInfo);
var
A12HourFormat: Boolean;
procedure AddFormatItem(AItemKind: TcxDateTimeFormatItemKind;
const AItemData: string);
begin
if not(AItemKind in [dtikString, dtikDateSeparator, dtikTimeSeparator]) and
AFormatInfo.DefinedItems[AItemKind] then
Exit;
AFormatInfo.DefinedItems[AItemKind] := True;
SetLength(AFormatInfo.Items, Length(AFormatInfo.Items) + 1);
with AFormatInfo.Items[Length(AFormatInfo.Items) - 1] do
begin
Kind := AItemKind;
Data := AItemData;
end;
end;
procedure AppendChars(const S: string; AStartIndex, ACount: Integer);
begin
if (Length(AFormatInfo.Items) = 0) or
(AFormatInfo.Items[Length(AFormatInfo.Items) - 1].Kind <> dtikString) then
AddFormatItem(dtikString, '');
with AFormatInfo.Items[Length(AFormatInfo.Items) - 1] do
Data := Data + Copy(S, AStartIndex, ACount);
end;
function GetCount(const AFormat: string; var AStartIndex: Integer;
AStartSymbol: Char): Integer;
begin
Result := 1;
while (AStartIndex <= Length(AFormat)) and (AFormat[AStartIndex] = AStartSymbol) do
begin
Inc(AStartIndex);
Inc(Result);
end;
end;
function ParseFormat(const AFormat: string; ARecursionDepth: Integer): Boolean;
var
ACount, APrevI, I: Integer;
AFormatItemData: string;
ALastToken, AStartSymbol, AToken: Char;
AThereIsHourItem, AThereIsTimeSuffixItem: Boolean;
begin
Result := True;
if (AFormat = '') or (ARecursionDepth = 2) then
Exit;
Inc(ARecursionDepth);
ALastToken := ' ';
AThereIsHourItem := False;
AThereIsTimeSuffixItem := False;
I := 1;
while I <= Length(AFormat) do
begin
AStartSymbol := AFormat[I];
if AStartSymbol in LeadBytes then
begin
AppendChars(AFormat, I, CharLength(AFormat, I));
Inc(I, CharLength(AFormat, I));
ALastToken := ' ';
Continue;
end;
Inc(I, CharLength(AFormat, I));
AToken := AStartSymbol;
if AToken in ['a'..'z'] then
Dec(AToken, 32);
if AToken in ['A'..'Z'] then
begin
if (AToken = 'M') and (ALastToken = 'H') then
AToken := 'N';
ALastToken := AToken;
end;
case AToken of
'E', 'Y':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount <= 2 then
AFormatItemData := 'YY'
else
AFormatItemData := 'YYYY';
AddFormatItem(dtikYear, AFormatItemData);
end;
'G':
begin
Result := False;
Break;
end;
'M':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount > 4 then
ACount := 4;
AddFormatItem(dtikMonth, GetCharString('M', ACount));
end;
'D':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
case ACount of
1..4:
AddFormatItem(dtikDay, GetCharString('D', ACount));
5:
Result := ParseFormat(ShortDateFormat, ARecursionDepth);
else
Result := ParseFormat(LongDateFormat, ARecursionDepth);
end;
if not Result then
Break;
end;
'H':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount > 2 then
ACount := 2;
AddFormatItem(dtikHour, GetCharString('H', ACount));
AThereIsHourItem := True;
end;
'N':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount > 2 then
ACount := 2;
AddFormatItem(dtikMin, GetCharString('N', ACount));
end;
'S':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount > 2 then
ACount := 2;
AddFormatItem(dtikSec, GetCharString('S', ACount));
end;
'T':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount = 1 then
Result := ParseFormat(ShortTimeFormat, ARecursionDepth)
else
Result := ParseFormat(LongTimeFormat, ARecursionDepth);
if not Result then
Break;
end;
'Z':
begin
ACount := GetCount(AFormat, I, AStartSymbol);
if ACount > 3 then
ACount := 3;
AddFormatItem(dtikMSec, GetCharString('Z', ACount));
end;
'A':
begin
if SameText(Copy(AFormat, I - 1, 5), 'AM/PM') then
begin
AddFormatItem(dtikTimeSuffix, Copy(AFormat, I - 1, 5));
Inc(I, 4);
AThereIsTimeSuffixItem := True;
end
else if SameText(Copy(AFormat, I - 1, 3), 'A/P') then
begin
AddFormatItem(dtikTimeSuffix, Copy(AFormat, I - 1, 3));
Inc(I, 2);
AThereIsTimeSuffixItem := True;
end
else if SameText(Copy(AFormat, I - 1, 4), 'AMPM') then
begin
AddFormatItem(dtikTimeSuffix, 'AMPM');
Inc(I, 3);
AThereIsTimeSuffixItem := True;
end
else if SameText(Copy(AFormat, I - 1, 3), 'AAA') then
begin
if SameText(Copy(AFormat, I - 1, 4), 'AAAA') then
ACount := 4
else
ACount := 3;
AddFormatItem(dtikDay, GetCharString('D', ACount));
Inc(I, ACount - 1);
end
else
AppendChars(AStartSymbol, 1, 1);
end;
'C':
begin
GetCount(AFormat, I, AStartSymbol);
Result := ParseFormat(ShortDateFormat, ARecursionDepth);
if not Result then
Break;
AppendChars(' ', 1, 1);
Result := ParseFormat(LongTimeFormat, ARecursionDepth);
if not Result then
Break;
end;
'/':
AddFormatItem(dtikDateSeparator, '');
':':
AddFormatItem(dtikTimeSeparator, '');
'''', '"':
begin
APrevI := I;
while (I <= Length(AFormat)) and (AFormat[I] <> AStartSymbol) do
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?