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 {*****************************************************************************}
12 unit TntWideStringProperty_Design
;
14 {$INCLUDE ..\Source\TntCompilers.inc}
18 {*****************************************************}
19 { TWideCharProperty-editor implemented by Maël Hörz }
20 {*****************************************************}
22 {$IFDEF COMPILER_9_UP}
23 {$MESSAGE FATAL 'The Object Inspector in Delphi 9 is already Unicode enabled.'}
27 Classes
, Messages
, Windows
, Graphics
, TypInfo
, TntDesignEditors_Design
,
28 DesignIntf
, DesignEditors
, VCLEditors
;
31 TWideStringProperty
= class(TPropertyEditor
, ICustomPropertyDrawing
)
33 FActivateWithoutGetValue
: Boolean;
34 FPropList
: PInstPropList
;
36 procedure SetPropEntry(Index
: Integer; AInstance
: TPersistent
; APropInfo
: PPropInfo
); override;
37 function GetWideStrValueAt(Index
: Integer): WideString
; dynamic;
38 function GetWideStrValue
: WideString
;
39 procedure SetWideStrValue(const Value
: WideString
); dynamic;
40 function GetWideVisualValue
: WideString
;
42 constructor Create(const ADesigner
: ITntDesigner
; APropCount
: Integer); override;
43 destructor Destroy
; override;
44 procedure Activate
; override;
45 procedure PropDrawName(ACanvas
: TCanvas
; const ARect
: TRect
; ASelected
: Boolean);
46 procedure PropDrawValue(ACanvas
: TCanvas
; const ARect
: TRect
; ASelected
: Boolean);
47 function AllEqual
: Boolean; override;
48 function GetEditLimit
: Integer; override;
49 function GetValue
: AnsiString
; override;
50 procedure SetValue(const Value
: AnsiString
); override;
51 {$IFDEF MULTI_LINE_STRING_EDITOR}
52 function GetAttributes
: TPropertyAttributes
; override;
53 procedure Edit
; override;
57 TWideCaptionProperty
= class(TWideStringProperty
)
59 function GetAttributes
: TPropertyAttributes
; override;
62 TWideCharProperty
= class(TWideStringProperty
)
64 {$IFDEF COMPILER_7_UP}
65 function GetIsDefault
: Boolean; override;
67 function GetWideStrValueAt(Index
: Integer): WideString
; override;
68 procedure SetWideStrValue(const Value
: WideString
); override;
70 function GetAttributes
: TPropertyAttributes
; override;
71 function GetEditLimit
: Integer; override;
79 Controls
, Forms
, SysUtils
, StdCtrls
, TntGraphics
, TntControls
,
80 TntSysUtils
, TntSystem
, Consts
,
85 RegisterPropertyEditor(TypeInfo(WideString
), nil, '', TWideStringProperty
);
86 RegisterPropertyEditor(TypeInfo(TWideCaption
), nil, '', TWideCaptionProperty
);
87 RegisterPropertyEditor(TypeInfo(WideChar
), nil, '', TWideCharProperty
);
90 function GetOIInspListBox
: TWinControl
;
92 ObjectInspectorForm
: TCustomForm
;
96 ObjectInspectorForm
:= GetObjectInspectorForm
;
97 if ObjectInspectorForm
<> nil then begin
98 Comp
:= ObjectInspectorForm
.FindComponent('PropList');
99 if Comp
is TWinControl
then
100 Result
:= TWinControl(Comp
);
104 function GetOIPropInspEdit
: TCustomEdit
{TNT-ALLOW TCustomEdit};
106 OIInspListBox
: TWinControl
;
110 OIInspListBox
:= GetOIInspListBox
;
111 if OIInspListBox
<> nil then begin
112 Comp
:= OIInspListBox
.FindComponent('EditControl');
113 if Comp
is TCustomEdit
{TNT-ALLOW TCustomEdit} then
114 Result
:= TCustomEdit
{TNT-ALLOW TCustomEdit}(Comp
);
117 //------------------------------
119 type TAccessWinControl
= class(TWinControl
);
121 { TWideStringProperty }
124 WideStringPropertyCount
: Integer = 0;
126 constructor TWideStringProperty
.Create(const ADesigner
: ITntDesigner
; APropCount
: Integer);
129 Inc(WideStringPropertyCount
);
130 GetMem(FPropList
, APropCount
* SizeOf(TInstProp
));
133 procedure ConvertObjectInspectorBackToANSI
;
135 Edit
: TCustomEdit
{TNT-ALLOW TCustomEdit};
137 if (Win32PlatformIsUnicode
) then begin
138 Edit
:= GetOIPropInspEdit
;
140 and IsWindowUnicode(Edit
.Handle
) then
141 TAccessWinControl(Edit
).RecreateWnd
;
145 destructor TWideStringProperty
.Destroy
;
147 Dec(WideStringPropertyCount
);
148 if (WideStringPropertyCount
= 0) then
149 ConvertObjectInspectorBackToANSI
;
150 if FPropList
<> nil then
151 FreeMem(FPropList
, PropCount
* SizeOf(TInstProp
));
155 {$IFDEF DELPHI_7} // verified against VCL source in Delphi 7
157 THackPropertyEditor
= class
158 FDesigner
: IDesigner
;
159 FPropList
: PInstPropList
;
163 procedure TWideStringProperty
.Activate
;
165 Edit
: TCustomEdit
{TNT-ALLOW TCustomEdit};
167 FActivateWithoutGetValue
:= True;
168 if (Win32PlatformIsUnicode
) then begin
169 Edit
:= GetOIPropInspEdit
;
171 and (not IsWindowUnicode(Edit
.Handle
)) then
172 ReCreateUnicodeWnd(Edit
, 'EDIT', True);
176 procedure TWideStringProperty
.SetPropEntry(Index
: Integer;
177 AInstance
: TPersistent
; APropInfo
: PPropInfo
);
180 with FPropList
^[Index
] do
182 Instance
:= AInstance
;
183 PropInfo
:= APropInfo
;
187 function TWideStringProperty
.GetWideStrValueAt(Index
: Integer): WideString
;
189 with FPropList
^[Index
] do Result
:= GetWideStrProp(Instance
, PropInfo
);
192 function TWideStringProperty
.GetWideStrValue
: WideString
;
194 Result
:= GetWideStrValueAt(0);
197 procedure TWideStringProperty
.SetWideStrValue(const Value
: WideString
);
201 for I
:= 0 to PropCount
- 1 do
202 with FPropList
^[I
] do SetWideStrProp(Instance
, PropInfo
, Value
);
206 function TWideStringProperty
.GetWideVisualValue
: WideString
;
209 Result
:= GetWideStrValue
214 procedure TWideStringProperty
.PropDrawName(ACanvas
: TCanvas
; const ARect
: TRect
; ASelected
: Boolean);
216 DefaultPropertyDrawName(Self
, ACanvas
, ARect
);
219 procedure TWideStringProperty
.PropDrawValue(ACanvas
: TCanvas
; const ARect
: TRect
; ASelected
: Boolean);
221 WideCanvasTextRect(ACanvas
, ARect
, ARect
.Left
+ 1, ARect
.Top
+ 1, GetWideVisualValue
);
224 function TWideStringProperty
.AllEqual
: Boolean;
230 if PropCount
> 1 then
232 V
:= GetWideStrValue
;
233 for I
:= 1 to PropCount
- 1 do
234 if GetWideStrValueAt(I
) <> V
then Exit
;
239 function TWideStringProperty
.GetEditLimit
: Integer;
241 Edit
: TCustomEdit
{TNT-ALLOW TCustomEdit};
244 // GetEditLimit is called right before the inplace editor text has been set
245 if Win32PlatformIsUnicode
then begin
246 Edit
:= GetOIPropInspEdit
;
247 if Assigned(Edit
) then begin
248 TntControl_SetText(Edit
, GetWideStrValue
);
249 TntControl_SetHint(Edit
, GetWideStrValue
);
254 function TWideStringProperty
.GetValue
: AnsiString
;
256 FActivateWithoutGetValue
:= False;
257 Result
:= WideStringToStringEx(GetWideStrValue
, CP_ACP
{TNT-ALLOW CP_ACP}); // use the same code page as the inplace editor
260 procedure TWideStringProperty
.SetValue(const Value
: AnsiString
);
262 Edit
: TCustomEdit
{TNT-ALLOW TCustomEdit};
264 if (not FActivateWithoutGetValue
) then begin
265 Edit
:= GetOIPropInspEdit
;
266 if Assigned(Edit
) and Win32PlatformIsUnicode
then
267 SetWideStrValue(TntControl_GetText(Edit
))
269 SetWideStrValue(StringToWideStringEx(Value
, CP_ACP
{TNT-ALLOW CP_ACP})); // use the same code page as the inplace editor
273 {$IFDEF MULTI_LINE_STRING_EDITOR}
274 function TWideStringProperty
.GetAttributes
: TPropertyAttributes
;
276 Result
:= inherited GetAttributes
+ [paDialog
];
279 procedure TWideStringProperty
.Edit
;
283 with TTntStrEditDlg
.Create(Application
) do
285 PrepareForWideStringEdit
;
286 Memo
.Text := GetWideStrValue
;
288 if ShowModal
= mrOk
then begin
290 while (Length(Temp
) > 0) and (Temp
[Length(Temp
)] < ' ') do
291 System
.Delete(Temp
, Length(Temp
), 1); { trim control characters from end }
292 SetWideStrValue(Temp
);
300 { TWideCaptionProperty }
302 function TWideCaptionProperty
.GetAttributes
: TPropertyAttributes
;
304 Result
:= inherited GetAttributes
+ [paAutoUpdate
];
307 { TWideCharProperty }
309 function TWideCharProperty
.GetAttributes
: TPropertyAttributes
;
311 Result
:= [paMultiSelect
, paRevertable
];
314 function TWideCharProperty
.GetEditLimit
: Integer;
316 inherited GetEditLimit
;
320 {$IFDEF COMPILER_7_UP}
321 function TWideCharProperty
.GetIsDefault
: Boolean;
324 OldPropList
: PInstPropList
;
327 if PropCount
> 0 then
329 OldPropList
:= THackPropertyEditor(Self
).FPropList
;
330 // The memory FPropList points to is write-protected.
331 // In the constructor we dynamically allocated our own PropList,
332 // which can be written, so point there instead.
333 THackPropertyEditor(Self
).FPropList
:= FPropList
;
335 // Delphi can't handle WideChar-type, but does well with Word-type,
336 // which has exactly the same size as WideChar (i.e. 2 Bytes)
337 for i
:= 0 to PropCount
- 1 do
338 FPropList
^[i
].PropInfo
^.PropType
^ := TypeInfo(Word);
340 Result
:= inherited GetIsDefault
;
342 for i
:= 0 to PropCount
- 1 do
343 FPropList
^[i
].PropInfo
^.PropType
^ := TypeInfo(WideChar
);
345 THackPropertyEditor(Self
).FPropList
:= OldPropList
;
350 function IsCharGraphic(C
: WideChar
): Boolean;
352 if Win32PlatformIsUnicode
then
353 Result
:= not IsWideCharCntrl(C
) and not IsWideCharSpace(C
)
354 else // representation as charcode avoids corruption on ANSI-systems
355 Result
:= (C
>= #33) and (C
<= #127);
358 function TWideCharProperty
.GetWideStrValueAt(Index
: Integer): WideString
;
362 with FPropList
^[Index
] do
363 C
:= WideChar(GetOrdProp(Instance
, PropInfo
));
365 if IsCharGraphic(C
) then
368 Result
:= WideFormat('#%d', [Ord(C
)]);
371 procedure TWideCharProperty
.SetWideStrValue(const Value
: WideString
);
376 if Length(Value
) = 0 then
378 else if Length(Value
) = 1 then
380 else if Value
[1] = '#' then
381 C
:= StrToInt(Copy(Value
, 2, Maxint
))
383 raise EPropertyError
.Create(SInvalidPropertyValue
);
385 with GetTypeData(GetPropType
)^ do
386 if (C
< MinValue
) or (C
> MaxValue
) then
387 raise EPropertyError
.CreateFmt(SOutOfRange
, [MinValue
, MaxValue
]);
389 for I
:= 0 to PropCount
- 1 do
390 with FPropList
^[I
] do SetOrdProp(Instance
, PropInfo
, C
);
398 ConvertObjectInspectorBackToANSI
;