Delphi's Format function is used by everyone, and the second parameter is really handy. Recently in the database development application need to create a function with the const parameter of array, for the common type String,integer,pointer processing is not a problem, but when the use of widestring type error, groping for a morning, feeling a lot of benefit. Now will the problem, problem-solving ideas, analysis methods, such as one by one, hope to gentlemen some inspiration to achieve the purpose of my writing this article!
Environment: WINXP + D7 Enter D7 to add a process test (M:array of const) to the default new project; Procedure Tform1.test (M:array of Const); Var I, Zero:integer; S, t:string; C:char; Const Sboolean:array [Boolean] of String = (' False ', ' True '); Begin s: = '; For I: = 0 to High (m) does with M[i] do Case VType of//write to this, hold down CTRL click VType, open the system unit, paste the VType enumeration value Vtinteger: (Vinteger:integer; Vtype:byte); Vtboolean: (Vboolean:boolean); Vtchar: (Vchar:char); vtextended: (vextended:pextended); Vtstring: (vstring:pshortstring); Vtpointer: (Vpointer:pointer); Vtpchar: (Vpchar:pchar); Vtobject: (Vobject:tobject); Vtclass: (Vclass:tclass); Vtwidechar: (Vwidechar:widechar); Vtpwidechar: (Vpwidechar:pwidechar); Vtansistring: (Vansistring:pointer); Vtcurrency: (vcurrency:pcurrency); Vtvariant: (vvariant:pvariant); Vtinterface: (Vinterface:pointer); Vtwidestring: (Vwidestring:pointer); VtInt64: (Vint64:pint64); End Delete (S, 1, 1); Self.caption: = s; End Continue writing, processing the enumeration values! Here's an explanation, Array of Const is made up of TVARREC types! See the code in the case of statement: Vtinteger:s: = s + '; ' + inttostr (Vinteger); Vtboolean:s: = s + '; ' + Sboolean[vboolean]; Vtchar:s: = s + '; ' + Vchar; Vtextended:s: = s + '; ' + floattostr (vextended^); Vtstring: If Assigned (vstring) THEN BEGIN T: = vstring^; S: = s + '; ' + t; End Vtpointer: If Assigned (Vpointer) Then S: = Format ('%s; Pointer: $%x ', [S, Integer (Vpointer)]); Vtpchar: If Assigned (Vpchar) THEN BEGIN T: = vpchar^; S: = s + '; ' + t; End Vtobject: If Assigned (Vobject) Then S: = Format ('%s; $%x ClassName:%s ', [S, Integer (@VObject), Vobject.classname]); Vtclass: If Assigned (Vclass) Then S: = Format ('%s; Class Reference $%x-classname:%s ', [S, Integer (Vclass), Vclass.classname]); Vtwidechar: Begin T: = Vwidechar; S: = s + '; ' + t; End Vtpwidechar: If Assigned (Vpwidechar) THEN BEGIN T: = vpwidechar^; S: = s + '; ' + t; End Vtansistring: If Assigned (vansistring) THEN BEGIN T: = PChar (vansistring); S: = s + '; ' + t; End Vtcurrency: If Assigned (vcurrency) Then S: = s + '; ' + floattostr (vcurrency^); Vtvariant: If Assigned (vvariant) Then S: = s + '; This is variant '; Vtinterface: If Assigned (vinterface) Then S: = Format ('%s; Interface: $%x ', [S, Integer (Vinterface)]); Vtwidestring: If Assigned (vwidestring) THEN BEGIN T: = pwidestring (vwidestring) ^; S: = s + '; ' + t; End VtInt64: If Assigned (VInt64) Then S: = s + '; ' + inttostr (vint64^);
Add a button to test the function Procedure Tform1.button1click (Sender:tobject); Var ws:widestring; Begin WS: = ' dda This is a test DFA '; Test ([Self, ' SDF ', 2.3324, WS, Tform]); End
Can see the test results, the value of the variable WS is not displayed, what to do?
We can see that the value of the widestring type is a pointer, and we start here and add a sentence to the event: Button1.caption: = Format (' $%x ', [Integer (@ws)]); The function of this sentence is to show the address of WS Add a similar statement to the test function and comment out the useless statement: T: = pwidestring (vwidestring) ^; S: = s + '; ' + t; S: = s + '; ' + Format (' $%x ', [Integer (vwidestring)]); Run can see two addresses are different, indicating that Delphi has copied the incoming parameter data So casting it into Pwidechar should be possible, add a variable declaration w:widestring;
W: = pwidestring (vwidestring) ^; S: = s + '; ' + W; But the results show only a single character, don't be depressed, already touched the doorway!
We know that format can handle the widestring type, where only one character is given, indicating that the character is truncated. The string in Delphi is ended with #0, widestring ends with two #0, you can be sure w: = pwidestring (vwidestring) ^ This Delphi is converted with the default as Ansistring. Analysis here has been able to write down .....
P:pbyte;
If Assigned (vwidestring) THEN BEGIN T: = '; Zero: = 0; P: = vwidestring; Repeat c: = char (p^); Inc (P); If C = #0 Then Inc (zero) else Begin Zero: = 0; T: = t + C; End Until zero = 2; S: = s + '; ' + t; End
But the display of Chinese characters has become garbled, and processing also appears bloated. Here we understand that the string indicated by Vwidestring is a two-byte wide string, and Intel's byte order is low before the high. So it can be processed with Pword!
To delete the c,zero,w variable, p changes to: P:pword;
If Assigned (vwidestring) THEN BEGIN T: = '; P: = vwidestring; Repeat T: = t + widechar (p^); Inc (P); Until p^ = 0; S: = s + '; ' + t; End Can see the core code has been very concise, the operation has been shown normal, Chinese characters are not garbled! At this point we seem to be done, but still think about it, Delphi supports widestring to string conversion, it should also have such a processing code. And in the loop t: = t + widechar (p^), the statement at the next breakpoint, run to the breakpoint, and then open the CPU window, see the seemingly concise code, a single sentence, the compiler will add a lot of processing code to it. It is necessary to find the string handler function of the system, after searching for widestring in the System.pas cell, find the function: procedure Widechartostrvar (Source:pwidechar; var dest:string); Oh, this is what we want!!! Now the Loop statement and the P variable can be deleted, the code I omitted. |