In general, UniChar strings must be converted to another format before output (including to STDOUT/STDERR, printer devices, or Presentation Manager controls).

There are two basic approaches to doing so:

If the text is being output to file (or sent over a network) for interchange with others, the output encoding need not match the current codepage if the text is not intended for local display. It should, however, use an appropriate encoding for display by the recipient. UTF-8 (codepage 1208) is often used for this purpose, particularly in HTML documents and electronic messages.

Conversely, text input should be implemented to accept text in a byte-oriented format, which can then be converted to UCS-2 for subsequent processing.

Conversion between UCS-2 and other codepages is performed using the ULS conversion functions.

Direct Output of Unicode Text under GPI

It is possible to output UniChar text without conversion (that is, as UCS-2 data streams) if direct GPI rendering is used. This can be done by using a font which supports Unicode (as noted above), and setting the usCodePage field of the FATTRS structure to 1200.

This is possible because the GPI text-drawing functions use byte arrays with explicitly-specified length variables, and so do not attempt to interpret null bytes as terminators. (When setting the string length parameter, however, remember that one UniChar equals two bytes.)

This technique is not, however, supported for printer devices, which require codepage output. Unicode text should be converted to codepage 1207 before printing.

The following sample of code illustrates the technique. (This code is assumed to be called during WM_PAINT processing in the window procedure.)

    HPS         hps;          // presentation space
    RECTL       rcl,          // window area
                rclClip;      // clipping region for drawn text
    POINTL      ptl;          // current text position
    FATTRS      fontAttrs;    // current font attributes
    FONTMETRICS fm;           // current font metrics
    UniChar   * pUniText;     // UCS-2 text to draw


    hps = WinBeginPaint( hwnd, NULLHANDLE, NULLHANDLE );
    memset( &fontAttrs, 0, sizeof(FATTRS) );

    // set the font attributes and create the logical font
    fontAttrs.usRecordLength = sizeof(FATTRS);
    fontAttrs.usCodePage     = 1200;
    fontAttrs.fsType         = FATTR_TYPE_MBCS;
    fontAttrs.fsFontUse      = FATTR_FONTUSE_NOMIX;
    strcpy( fontAttrs.szFacename, "Times New Roman MT 30");
    GpiCreateLogFont( hps, NULL, 1L, &fontAttrs );
    GpiSetCharSet( hps, 1L );

    // paint the window background
    WinQueryWindowRect( hwnd, &rcl );
    WinFillRect( hps, &rcl, SYSCLR_WINDOW );

    // define a suitable margin to leave around the text
    GpiQueryFontMetrics( hps, sizeof(FONTMETRICS), &fm );
    rclClip.xLeft   = rcl.xLeft + fm.lAveCharWidth;
    rclClip.yBottom = rcl.yBottom + fm.lXHeight;
    rclClip.xRight  = rcl.xRight - fm.lAveCharWidth;
    rclClip.yTop    = rcl.yTop - fm.lXHeight;

    // set the text colour and starting position
    GpiSetColor( hps, SYSCLR_WINDOWTEXT );
    ptl.x = rclClip.xLeft;
    ptl.y = rclClip.yTop - fm.lExternalLeading - fm.lMaxAscender;

    // (set the contents of pUniText)
    // ...

    GpiCharStringPosAt( hps, &ptl, &rclClip, CHS_CLIP,
                        UniStrlen(pUniText) * 2, (PCH) pUniText, NULL );

    // (perform any additional processing required)
    // ...

    WinEndPaint( hps );


[Back] [Next]