The MicroStation Development Library (MDL) provides a set of C-language functions.
Based on C, traditionally text strings have been multibyte char [] arrays.
MicroStation is moving towards Unicode, with some stops and starts along the way.
Q There are many C/C++ data types for strings. They proliferate in the world of Windows programming, and MDL has its own as well …
MSWChar data type?
wchar_t data type?
MSWideChar data type?
Q When I want to extract the string from a MicroStation text element, I don't know how large a buffer to allocate. Is there a way to find the length of the string in a text element?
A
Unicode character type wchar_t and its MDL equivalent MSWChar.
Recent versions of MicroStation provide the MSWChar typedef,
which is a 16-bit character suitable for Unicode text.
In a
Visual Studio
build environment,
MSWChar boils down to a typedef of the compiler's wchar_t.
You can convert between multibyte and Unicode strings with two dedicated MDL functions. These functions are available in all versions of MicroStation V8 …
mdlCnv_convertMultibyteToUnicode
mdlCnv_convertUnicodeToMultibyte
A
MDL character type MSWideChar.
Intermediate versions of MicroStation provide the MSWideChar typedef, which is intended solely to confuse the MDL programmer.
Unfortunately, some common text functions take a MSWideChar* pointer,
and you can't fool
Visual Studio
into thinking that MSWideChar and wchar_t are the same thing
(which they are not). You have to convert between MSWideChar and wchar_t.
Unfortunately, there are no MDL conversion functions in the public API documentation for that purpose.
The following is extracted from this Bentley Community Wiki page authored by Bentley's Jeff Marker.
Functions to convert from (left column) to (top row) in MicroStation V8i …
Note that functions to convert to/from MSWChar and MSWideChar are not published;
you will have to stub your own definitions in order to be able to use them.
The Font-based methods have the advantage of knowing what code page to use
(as any MSWideChar strings you provide should always be in the code page of the font).
To use the C functions, you will have to manually provide a code page, but can simply append the following declarations to your source code.
Additionally, if you're putting these declarations in a C++ header file, you need to wrap them in
extern "C".
Otherwise, the C++ compiler will decorate the names and the linker won't be able to find them …
int MSWideCharStringToMSWCharString (MSWChar* pOutString, UInt32 nOutChars, MSWideChar const * pInString, UInt32 codePage); int MSWCharStringToMSWideCharString (MSWideChar* pOutString, UInt32 nOutChars, MSWChar const * pInString, UInt32 codePage);
Link with the toolsubs MDL library (found in …\MicroStation\mdl\library).
To use the methods on the Font object, you will have to modify your delivered FontManager.h file to include the following declarations in the Font class:
MSCORE_EXPORT int MSWideCharStringToMSWCharString (MSWCharP outString, UInt32 nOutChars, UInt16 const* inString) const; MSCORE_EXPORT int MSWCharStringToMSWideCharString (UInt16* outString, UInt32 nOutChars, MSWCharCP inString) const;
A Bentley spokesperson further commented It looks like these functions return the number of characters (not bytes) put in the destination buffer, not including the NULL terminator.
Note that the above functions are available only with MicroStation V8i.
There are no functions for prior versions of MicroStation that convert between MSWChar and MSWideChar strings.
It's not clear how we ever manage to create a text element successfully using mdlText_createWide with MicroStation XM or earlier
— it requires a MSWideChar* to the string content.
With Visual C++, there are other string types and other conversion functions available. Which types and functions are available depends on the version of Visual Studio you are using.
This Bentley Community WiKi entry about MDL text types may be useful.
Return to MDL articles index.
A How to find the length of the string embedded in a text element.
There's no MDL API function to tell you the length of the string embedded in a MicroStation text element.
Instead you have to do the hard work, delving into the Text_2d and Text_3d
structure defined in <mselems.h>.
Here's a function that does just that …
//////////////////////////////////////////////////////////////////////
// Get string length from a text element descriptor
UInt32 MicroStation::StringLength (MSElementDescr const* pText)
{
UInt32 length (0);
const int elemType (mdlElement_getType (&pText->el));
switch (elemType)
{
case TEXT_ELM:
{
length = mdlModelRef_is3D (pText->h.dgnModelRef)?
pText->el.text_3d.numchars:
pText->el.text_2d.numchars;
break;
}
default:
{
CMdlString inform;
inform.Format (_T("MicroStation::StringLength: element type %d ID %I64d is not text"), elemType, mdlElement_getID (&pText->el));
inform.OutputError (true);
}
break;
}
return length;
}
Here's some code that uses the above function to extract text to a C++ std::wstring …
//////////////////////////////////////////////////////////////////////
// Get a text string from an element descriptor
std::wstring MicroStation::GetText (MSElementDescr const* pText)
{
std::wstring text (L"");
const int elemType (mdlElement_getType (&pText->el));
switch (elemType)
{
case TEXT_ELM:
{
std::vector<MSWideChar> wcText (1 + StringLength (pText));
if (SUCCESS == mdlText_extractStringWide (&wcText [0], &pText->el))
{
text = StringConvert::MSWideChar2Wide (&wcText [0]);
}
break;
}
default:
{
CMdlString inform;
inform.Format (_T("MicroStation::GetText: element type %d ID %I64d is not text"), elemType, mdlElement_getID (&pText->el));
inform.OutputError (true);
}
break;
}
return text;
}
Return to MDL articles index.