2 {*****************************************************************************}
4 { Tnt Delphi Unicode Controls }
5 { http://www.tntware.com/delphicontrols/unicode/ }
8 { Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) }
10 {*****************************************************************************}
14 {$INCLUDE TntCompilers.inc}
19 Classes
, TntClasses
, Grids
, Windows
, Controls
, Messages
;
22 {TNT-WARN TInplaceEdit}
23 TTntInplaceEdit
= class(TInplaceEdit
{TNT-ALLOW TInplaceEdit})
25 function GetText
: WideString
;
26 procedure SetText(const Value
: WideString
);
28 procedure UpdateContents
; override;
29 procedure CreateWindowHandle(const Params
: TCreateParams
); override;
31 property Text: WideString read GetText write SetText
;
34 TTntGetEditEvent
= procedure (Sender
: TObject
; ACol
, ARow
: Longint; var Value
: WideString
) of object;
35 TTntSetEditEvent
= procedure (Sender
: TObject
; ACol
, ARow
: Longint; const Value
: WideString
) of object;
37 {TNT-WARN TCustomDrawGrid}
38 _TTntInternalCustomDrawGrid
= class(TCustomDrawGrid
{TNT-ALLOW TCustomDrawGrid})
40 FSettingEditText
: Boolean;
41 procedure InternalSetEditText(ACol
, ARow
: Longint; const Value
: string{TNT-ALLOW string}); dynamic; abstract;
43 procedure SetEditText(ACol
, ARow
: Longint; const Value
: string{TNT-ALLOW string}); override;
46 TTntCustomDrawGrid
= class(_TTntInternalCustomDrawGrid
)
48 FOnGetEditText
: TTntGetEditEvent
;
49 FOnSetEditText
: TTntSetEditEvent
;
50 function GetHint
: WideString
;
51 procedure SetHint(const Value
: WideString
);
52 function IsHintStored
: Boolean;
53 procedure WMChar(var Msg
: TWMChar
); message WM_CHAR
;
55 function CreateEditor
: TInplaceEdit
{TNT-ALLOW TInplaceEdit}; override;
56 procedure InternalSetEditText(ACol
, ARow
: Longint; const Value
: string{TNT-ALLOW string}); override;
57 function GetEditText(ACol
, ARow
: Longint): WideString
; reintroduce
; virtual;
58 procedure SetEditText(ACol
, ARow
: Longint; const Value
: WideString
); reintroduce
; virtual;
60 procedure CreateWindowHandle(const Params
: TCreateParams
); override;
61 procedure ShowEditorChar(Ch
: WideChar
); dynamic;
62 procedure DefineProperties(Filer
: TFiler
); override;
63 function GetActionLinkClass
: TControlActionLinkClass
; override;
64 procedure ActionChange(Sender
: TObject
; CheckDefaults
: Boolean); override;
65 property OnGetEditText
: TTntGetEditEvent read FOnGetEditText write FOnGetEditText
;
66 property OnSetEditText
: TTntSetEditEvent read FOnSetEditText write FOnSetEditText
;
68 property Hint
: WideString read GetHint write SetHint stored IsHintStored
;
72 TTntDrawGrid
= class(TTntCustomDrawGrid
)
87 property DefaultColWidth
;
88 property DefaultRowHeight
;
89 property DefaultDrawing
;
99 property GridLineWidth
;
101 property ParentBiDiMode
;
102 property ParentColor
;
103 property ParentCtl3D
;
105 property ParentShowHint
;
111 property VisibleColCount
;
112 property VisibleRowCount
;
114 property OnColumnMoved
;
115 property OnContextPopup
;
124 property OnGetEditMask
;
125 property OnGetEditText
;
129 {$IFDEF COMPILER_9_UP}
130 property OnMouseActivate
;
132 property OnMouseDown
;
133 {$IFDEF COMPILER_10_UP}
134 property OnMouseEnter
;
135 property OnMouseLeave
;
137 property OnMouseMove
;
139 property OnMouseWheelDown
;
140 property OnMouseWheelUp
;
142 property OnSelectCell
;
143 property OnSetEditText
;
144 property OnStartDock
;
145 property OnStartDrag
;
146 property OnTopLeftChanged
;
149 TTntStringGrid
= class;
151 {TNT-WARN TStringGridStrings}
152 TTntStringGridStrings
= class(TTntStrings
)
155 FColRowIndex
: Integer;
156 FGrid
: TTntStringGrid
;
157 function GridAnsiStrings
: TStrings
{TNT-ALLOW TStrings};
159 function Get(Index
: Integer): WideString
; override;
160 procedure Put(Index
: Integer; const S
: WideString
); override;
161 function GetCount
: Integer; override;
162 function GetObject(Index
: Integer): TObject
; override;
163 procedure PutObject(Index
: Integer; AObject
: TObject
); override;
164 procedure SetUpdateState(Updating
: Boolean); override;
166 constructor Create(AGrid
: TTntStringGrid
; AIndex
: Longint);
167 function Add(const S
: WideString
): Integer; override;
168 procedure Assign(Source
: TPersistent
); override;
169 procedure Clear
; override;
170 procedure Delete(Index
: Integer); override;
171 procedure Insert(Index
: Integer; const S
: WideString
); override;
174 {TNT-WARN TStringGrid}
175 _TTntInternalStringGrid
= class(TStringGrid
{TNT-ALLOW TStringGrid})
177 FSettingEditText
: Boolean;
178 procedure InternalSetEditText(ACol
, ARow
: Longint; const Value
: string{TNT-ALLOW string}); dynamic; abstract;
180 procedure SetEditText(ACol
, ARow
: Longint; const Value
: string{TNT-ALLOW string}); override;
183 TTntStringGrid
= class(_TTntInternalStringGrid
)
185 FCreatedRowStrings
: TStringList
{TNT-ALLOW TStringList};
186 FCreatedColStrings
: TStringList
{TNT-ALLOW TStringList};
187 FOnGetEditText
: TTntGetEditEvent
;
188 FOnSetEditText
: TTntSetEditEvent
;
189 function GetHint
: WideString
;
190 procedure SetHint(const Value
: WideString
);
191 function IsHintStored
: Boolean;
192 procedure WMChar(var Msg
: TWMChar
); message WM_CHAR
;
193 function GetCells(ACol
, ARow
: Integer): WideString
;
194 procedure SetCells(ACol
, ARow
: Integer; const Value
: WideString
);
195 function FindGridStrings(const IsCol
: Boolean; const ListIndex
: Integer): TTntStrings
;
196 function GetCols(Index
: Integer): TTntStrings
;
197 function GetRows(Index
: Integer): TTntStrings
;
198 procedure SetCols(Index
: Integer; const Value
: TTntStrings
);
199 procedure SetRows(Index
: Integer; const Value
: TTntStrings
);
201 function CreateEditor
: TInplaceEdit
{TNT-ALLOW TInplaceEdit}; override;
202 procedure DrawCell(ACol
, ARow
: Longint; ARect
: TRect
; AState
: TGridDrawState
); override;
203 procedure InternalSetEditText(ACol
, ARow
: Longint; const Value
: string{TNT-ALLOW string}); override;
204 function GetEditText(ACol
, ARow
: Longint): WideString
; reintroduce
; virtual;
205 procedure SetEditText(ACol
, ARow
: Longint; const Value
: WideString
); reintroduce
; virtual;
207 procedure CreateWindowHandle(const Params
: TCreateParams
); override;
208 procedure ShowEditorChar(Ch
: WideChar
); dynamic;
209 procedure DefineProperties(Filer
: TFiler
); override;
210 function GetActionLinkClass
: TControlActionLinkClass
; override;
211 procedure ActionChange(Sender
: TObject
; CheckDefaults
: Boolean); override;
213 constructor Create(AOwner
: TComponent
); override;
214 destructor Destroy
; override;
215 property Cells
[ACol
, ARow
: Integer]: WideString read GetCells write SetCells
;
216 property Cols
[Index
: Integer]: TTntStrings read GetCols write SetCols
;
217 property Rows
[Index
: Integer]: TTntStrings read GetRows write SetRows
;
219 property Hint
: WideString read GetHint write SetHint stored IsHintStored
;
220 property OnGetEditText
: TTntGetEditEvent read FOnGetEditText write FOnGetEditText
;
221 property OnSetEditText
: TTntSetEditEvent read FOnSetEditText write FOnSetEditText
;
227 SysUtils
, TntSystem
, TntGraphics
, TntControls
, TntStdCtrls
, TntActnList
, TntSysUtils
;
229 { TBinaryCompareAnsiStringList }
231 TBinaryCompareAnsiStringList
= class(TStringList
{TNT-ALLOW TStringList})
233 function CompareStrings(const S1
, S2
: string{TNT-ALLOW string}): Integer; override;
236 function TBinaryCompareAnsiStringList
.CompareStrings(const S1
, S2
: string{TNT-ALLOW string}): Integer;
238 // must compare strings via binary for speed
249 procedure TTntInplaceEdit
.CreateWindowHandle(const Params
: TCreateParams
);
251 TntCustomEdit_CreateWindowHandle(Self
, Params
);
254 function TTntInplaceEdit
.GetText
: WideString
;
257 Result
:= inherited Text
259 Result
:= TntControl_GetText(Self
);
262 procedure TTntInplaceEdit
.SetText(const Value
: WideString
);
265 inherited Text := Value
267 TntControl_SetText(Self
, Value
);
270 type TAccessCustomGrid
= class(TCustomGrid
);
272 procedure TTntInplaceEdit
.UpdateContents
;
275 with TAccessCustomGrid(Grid
) do
276 Self
.EditMask
:= GetEditMask(Col
, Row
);
277 if (Grid
is TTntStringGrid
) then
278 with (Grid
as TTntStringGrid
) do
279 Self
.Text := GetEditText(Col
, Row
)
280 else if (Grid
is TTntCustomDrawGrid
) then
281 with (Grid
as TTntCustomDrawGrid
) do
282 Self
.Text := GetEditText(Col
, Row
)
284 with TAccessCustomGrid(Grid
) do
285 Self
.Text := GetEditText(Col
, Row
);
286 with TAccessCustomGrid(Grid
) do
287 Self
.MaxLength
:= GetEditLimit
;
290 { _TTntInternalCustomDrawGrid }
292 procedure _TTntInternalCustomDrawGrid
.SetEditText(ACol
, ARow
: Integer; const Value
: string{TNT-ALLOW string});
294 if FSettingEditText
then
297 InternalSetEditText(ACol
, ARow
, Value
);
301 { TTntCustomDrawGrid }
303 function TTntCustomDrawGrid
.CreateEditor
: TInplaceEdit
{TNT-ALLOW TInplaceEdit};
305 Result
:= TTntInplaceEdit
.Create(Self
);
308 procedure TTntCustomDrawGrid
.CreateWindowHandle(const Params
: TCreateParams
);
310 CreateUnicodeHandle(Self
, Params
, '');
313 procedure TTntCustomDrawGrid
.DefineProperties(Filer
: TFiler
);
316 TntPersistent_AfterInherited_DefineProperties(Filer
, Self
);
319 function TTntCustomDrawGrid
.IsHintStored
: Boolean;
321 Result
:= TntControl_IsHintStored(Self
);
324 function TTntCustomDrawGrid
.GetHint
: WideString
;
326 Result
:= TntControl_GetHint(Self
);
329 procedure TTntCustomDrawGrid
.SetHint(const Value
: WideString
);
331 TntControl_SetHint(Self
, Value
);
334 function TTntCustomDrawGrid
.GetEditText(ACol
, ARow
: Integer): WideString
;
337 if Assigned(FOnGetEditText
) then FOnGetEditText(Self
, ACol
, ARow
, Result
);
340 procedure TTntCustomDrawGrid
.InternalSetEditText(ACol
, ARow
: Integer; const Value
: string{TNT-ALLOW string});
342 if not FSettingEditText
then
343 SetEditText(ACol
, ARow
, TntControl_GetText(InplaceEditor
));
346 procedure TTntCustomDrawGrid
.SetEditText(ACol
, ARow
: Integer; const Value
: WideString
);
348 if Assigned(FOnSetEditText
) then FOnSetEditText(Self
, ACol
, ARow
, Value
);
351 procedure TTntCustomDrawGrid
.WMChar(var Msg
: TWMChar
);
353 if (goEditing
in Options
)
354 and (AnsiChar(Msg
.CharCode
) in [^H
, #32..#255]) then begin
355 RestoreWMCharMsg(TMessage(Msg
));
356 ShowEditorChar(WideChar(Msg
.CharCode
));
361 procedure TTntCustomDrawGrid
.ShowEditorChar(Ch
: WideChar
);
364 if InplaceEditor
<> nil then begin
365 if Win32PlatformIsUnicode
then
366 PostMessageW(InplaceEditor
.Handle
, WM_CHAR
, Word(Ch
), 0)
368 PostMessageA(InplaceEditor
.Handle
, WM_CHAR
, Word(Ch
), 0);
372 procedure TTntCustomDrawGrid
.ActionChange(Sender
: TObject
; CheckDefaults
: Boolean);
374 TntControl_BeforeInherited_ActionChange(Self
, Sender
, CheckDefaults
);
378 function TTntCustomDrawGrid
.GetActionLinkClass
: TControlActionLinkClass
;
380 Result
:= TntControl_GetActionLinkClass(Self
, inherited GetActionLinkClass
);
383 { TTntStringGridStrings }
385 procedure TTntStringGridStrings
.Assign(Source
: TPersistent
);
387 UTF8Strings
: TStringList
{TNT-ALLOW TStringList};
390 UTF8Strings
:= TStringList
{TNT-ALLOW TStringList}.Create
;
392 if Source
is TStrings
{TNT-ALLOW TStrings} then begin
393 for i
:= 0 to TStrings
{TNT-ALLOW TStrings}(Source
).Count
- 1 do
394 UTF8Strings
.AddObject(WideStringToUTF8(WideString(TStrings
{TNT-ALLOW TStrings}(Source
).Strings
[i
])),
395 TStrings
{TNT-ALLOW TStrings}(Source
).Objects
[i
]);
396 GridAnsiStrings
.Assign(UTF8Strings
);
397 end else if Source
is TTntStrings
then begin
398 for i
:= 0 to TTntStrings(Source
).Count
- 1 do
399 UTF8Strings
.AddObject(WideStringToUTF8(TTntStrings(Source
).Strings
[i
]),
400 TTntStrings(Source
).Objects
[i
]);
401 GridAnsiStrings
.Assign(UTF8Strings
);
403 GridAnsiStrings
.Assign(Source
);
409 function TTntStringGridStrings
.GridAnsiStrings
: TStrings
{TNT-ALLOW TStrings};
411 Assert(Assigned(FGrid
));
413 Result
:= TStringGrid
{TNT-ALLOW TStringGrid}(FGrid
).Cols
[FColRowIndex
]
415 Result
:= TStringGrid
{TNT-ALLOW TStringGrid}(FGrid
).Rows
[FColRowIndex
];
418 procedure TTntStringGridStrings
.Clear
;
420 GridAnsiStrings
.Clear
;
423 procedure TTntStringGridStrings
.Delete(Index
: Integer);
425 GridAnsiStrings
.Delete(Index
);
428 function TTntStringGridStrings
.GetCount
: Integer;
430 Result
:= GridAnsiStrings
.Count
;
433 function TTntStringGridStrings
.Get(Index
: Integer): WideString
;
435 Result
:= UTF8ToWideString(GridAnsiStrings
[Index
]);
438 procedure TTntStringGridStrings
.Put(Index
: Integer; const S
: WideString
);
440 GridAnsiStrings
[Index
] := WideStringToUTF8(S
);
443 procedure TTntStringGridStrings
.Insert(Index
: Integer; const S
: WideString
);
445 GridAnsiStrings
.Insert(Index
, WideStringToUTF8(S
));
448 function TTntStringGridStrings
.Add(const S
: WideString
): Integer;
450 Result
:= GridAnsiStrings
.Add(WideStringToUTF8(S
));
453 function TTntStringGridStrings
.GetObject(Index
: Integer): TObject
;
455 Result
:= GridAnsiStrings
.Objects
[Index
];
458 procedure TTntStringGridStrings
.PutObject(Index
: Integer; AObject
: TObject
);
460 GridAnsiStrings
.Objects
[Index
] := AObject
;
463 type TAccessStrings
= class(TStrings
{TNT-ALLOW TStrings});
465 procedure TTntStringGridStrings
.SetUpdateState(Updating
: Boolean);
467 TAccessStrings(GridAnsiStrings
).SetUpdateState(Updating
);
470 constructor TTntStringGridStrings
.Create(AGrid
: TTntStringGrid
; AIndex
: Integer);
474 if AIndex
> 0 then begin
476 FColRowIndex
:= AIndex
- 1;
479 FColRowIndex
:= -AIndex
- 1;
483 { _TTntInternalStringGrid }
485 procedure _TTntInternalStringGrid
.SetEditText(ACol
, ARow
: Integer; const Value
: string{TNT-ALLOW string});
487 if FSettingEditText
then
490 InternalSetEditText(ACol
, ARow
, Value
);
495 constructor TTntStringGrid
.Create(AOwner
: TComponent
);
498 FCreatedRowStrings
:= TBinaryCompareAnsiStringList
.Create
;
499 FCreatedRowStrings
.Sorted
:= True;
500 FCreatedRowStrings
.Duplicates
:= dupError
;
501 FCreatedColStrings
:= TBinaryCompareAnsiStringList
.Create
;
502 FCreatedColStrings
.Sorted
:= True;
503 FCreatedColStrings
.Duplicates
:= dupError
;
506 destructor TTntStringGrid
.Destroy
;
510 for i
:= FCreatedColStrings
.Count
- 1 downto 0 do
511 FCreatedColStrings
.Objects
[i
].Free
;
512 for i
:= FCreatedRowStrings
.Count
- 1 downto 0 do
513 FCreatedRowStrings
.Objects
[i
].Free
;
514 FreeAndNil(FCreatedColStrings
);
515 FreeAndNil(FCreatedRowStrings
);
519 function TTntStringGrid
.CreateEditor
: TInplaceEdit
{TNT-ALLOW TInplaceEdit};
521 Result
:= TTntInplaceEdit
.Create(Self
);
524 procedure TTntStringGrid
.CreateWindowHandle(const Params
: TCreateParams
);
526 CreateUnicodeHandle(Self
, Params
, '');
529 procedure TTntStringGrid
.DefineProperties(Filer
: TFiler
);
532 TntPersistent_AfterInherited_DefineProperties(Filer
, Self
);
535 function TTntStringGrid
.IsHintStored
: Boolean;
537 Result
:= TntControl_IsHintStored(Self
);
540 function TTntStringGrid
.GetHint
: WideString
;
542 Result
:= TntControl_GetHint(Self
)
545 procedure TTntStringGrid
.SetHint(const Value
: WideString
);
547 TntControl_SetHint(Self
, Value
);
550 function TTntStringGrid
.GetCells(ACol
, ARow
: Integer): WideString
;
552 Result
:= UTF8ToWideString(inherited Cells
[ACol
, ARow
])
555 procedure TTntStringGrid
.SetCells(ACol
, ARow
: Integer; const Value
: WideString
);
559 UTF8Str
:= WideStringToUTF8(Value
);
560 if inherited Cells
[ACol
, ARow
] <> UTF8Str
then
561 inherited Cells
[ACol
, ARow
] := UTF8Str
;
564 function TTntStringGrid
.FindGridStrings(const IsCol
: Boolean; const ListIndex
: Integer): TTntStrings
;
567 SrcStrings
: TStrings
{TNT-ALLOW TStrings};
571 SrcStrings
:= FCreatedColStrings
573 SrcStrings
:= FCreatedRowStrings
;
574 Assert(Assigned(SrcStrings
));
575 idx
:= SrcStrings
.IndexOf(IntToStr(ListIndex
));
577 Result
:= SrcStrings
.Objects
[idx
] as TTntStrings
579 if IsCol
then RCIndex
:= -ListIndex
- 1 else RCIndex
:= ListIndex
+ 1;
580 Result
:= TTntStringGridStrings
.Create(Self
, RCIndex
);
581 SrcStrings
.AddObject(IntToStr(ListIndex
), Result
);
585 function TTntStringGrid
.GetCols(Index
: Integer): TTntStrings
;
587 Result
:= FindGridStrings(True, Index
);
590 function TTntStringGrid
.GetRows(Index
: Integer): TTntStrings
;
592 Result
:= FindGridStrings(False, Index
);
595 procedure TTntStringGrid
.SetCols(Index
: Integer; const Value
: TTntStrings
);
597 FindGridStrings(True, Index
).Assign(Value
);
600 procedure TTntStringGrid
.SetRows(Index
: Integer; const Value
: TTntStrings
);
602 FindGridStrings(False, Index
).Assign(Value
);
605 procedure TTntStringGrid
.DrawCell(ACol
, ARow
: Integer; ARect
: TRect
; AState
: TGridDrawState
);
607 SaveDefaultDrawing
: Boolean;
609 if DefaultDrawing
then
610 WideCanvasTextRect(Canvas
, ARect
, ARect
.Left
+2, ARect
.Top
+2, Cells
[ACol
, ARow
]);
611 SaveDefaultDrawing
:= DefaultDrawing
;
613 DefaultDrawing
:= False;
614 inherited DrawCell(ACol
, ARow
, ARect
, AState
);
616 DefaultDrawing
:= SaveDefaultDrawing
;
620 function TTntStringGrid
.GetEditText(ACol
, ARow
: Integer): WideString
;
622 Result
:= Cells
[ACol
, ARow
];
623 if Assigned(FOnGetEditText
) then FOnGetEditText(Self
, ACol
, ARow
, Result
);
626 procedure TTntStringGrid
.InternalSetEditText(ACol
, ARow
: Integer; const Value
: string{TNT-ALLOW string});
628 if not FSettingEditText
then
629 SetEditText(ACol
, ARow
, TntControl_GetText(InplaceEditor
));
632 procedure TTntStringGrid
.SetEditText(ACol
, ARow
: Integer; const Value
: WideString
);
634 FSettingEditText
:= True;
636 inherited SetEditText(ACol
, ARow
, WideStringToUTF8(Value
));
638 FSettingEditText
:= False;
640 if Assigned(FOnSetEditText
) then FOnSetEditText(Self
, ACol
, ARow
, Value
);
643 procedure TTntStringGrid
.WMChar(var Msg
: TWMChar
);
645 if (goEditing
in Options
)
646 and (AnsiChar(Msg
.CharCode
) in [^H
, #32..#255]) then begin
647 RestoreWMCharMsg(TMessage(Msg
));
648 ShowEditorChar(WideChar(Msg
.CharCode
));
653 procedure TTntStringGrid
.ShowEditorChar(Ch
: WideChar
);
656 if InplaceEditor
<> nil then begin
657 if Win32PlatformIsUnicode
then
658 PostMessageW(InplaceEditor
.Handle
, WM_CHAR
, Word(Ch
), 0)
660 PostMessageA(InplaceEditor
.Handle
, WM_CHAR
, Word(Ch
), 0);
664 procedure TTntStringGrid
.ActionChange(Sender
: TObject
; CheckDefaults
: Boolean);
666 TntControl_BeforeInherited_ActionChange(Self
, Sender
, CheckDefaults
);
670 function TTntStringGrid
.GetActionLinkClass
: TControlActionLinkClass
;
672 Result
:= TntControl_GetActionLinkClass(Self
, inherited GetActionLinkClass
);