WString

See Also: Declaring Variables, Variable Declaration Commands, Struct, AddressOf Function

Purpose

Declares one or more WString variables.

Syntax

To declare WString variables

WString {identifier} [… {identifier}]

Where

To declare array variables of type WString

WString{dimension-list} {identifier} […{identifier}]

Where

What It Does

A lot of external APIs, such as the Windows APIs, work with UTF-16 encoding. When calling these APIs, the strings that need to be converted as DataFlex String variables are UTF-8 encoded. To make this easier, use the WString type. When moving strings to / from this type, the data is automatically converted to UTF-16. WStrings can be passed to external functions as parameters or as pointers (in case of a return buffer).

It is recommended to only use the WString type when actually calling an external API, and not instead of the regular String type. Even though string manipulations and string functions do work, internally the data is converted between UTF-16 and UTF-8 for each operation, which will slow down your application.

When working with COM, there is no need to use the WString, as variants are already UTF-16 encoded (they always have been).

Example: WString Parameters

When an external function has a string as a parameter (this is usually a pointer to a string) like this:

External_Function WritePrivateProfileString "WritePrivateProfileStringA" Kernel32.dll ;

    String sSection String sKeyName String sValue String sFileName Returns Integer

Converting it to its wide version is as easy as changing it into:

External_Function WritePrivateProfileString "WritePrivateProfileStringW" Kernel32.dll ;

    WString sSection WString sKeyName WString sValue WString sFileName Returns Integer

When calling this function, you can simply use regular strings as parameters. These can come from a parameter, an expression or a constant. The runtime will automatically convert them to a WString before actually calling the external function. As with string, the runtime is smart enough to pass a pointer to the wide string when executing the external function. So, the line below will work properly:

Move (WritePrivateProfileString(sSection, "", "", psFilename(Self))) to iRes

 

Example: WString with Pointer Parameters

It is common practice to define external APIs with Pointer (formerly also called Address) parameters. This is done when needed to allow passing 0 (NULL) as parameter or when a string is returned. This can be done the same way as we used to do with String parameters.

External_Function GetModuleFileNameW "GetModuleFileNameW" Kernel32.dll ;

    Handle   hModule ;

    Pointer  lpFilename ;

    UInteger nSize ;

    Returns  UInteger

This function returns a string in the passed buffer. The size of the buffer is passed as separate parameter. Calling this function can be done like this:

Integer iNumChars

WString wApplicationFileName

String sApplicationFileName

 

Move (Repeat(Character(0), 1024)) to wApplicationFileName

Move (GetModuleFileNameW(0, AddressOf(wApplicationFileName), 1024)) to iNumChars

Move (CString(wApplicationFileName)) to sApplicationFileName

So, we define a WString and fill it with 1024 null characters. Do note that Repeat generates a UTF-8 string, which is then converted to UTF-16 when it is put into the WString buffer. Then we call the external function, passing a pointer to the WString. The external function changes the WString buffer. On the last line, we convert the UTF-16 result string to a regular UTF-8 string.

The CString function is used to adjust the length of the string. DataFlex strings (both WString and String) can contain 0 characters, while in other environments the 0 usually terminates the string. To support this, DataFlex strings actually store a length with them. The external function will adjust the content of the string, and write a 0 terminator, but it will not change the length of the string (which remains 1024 characters). Calling the CString function fixes that.