Tuesday, December 8, 2009

Visual Studio: How to Write Unicode Programs

Unicode provides a uniform platform for programming with every language. It was a demand of programmers to create such a platform that will support languages over the world. Now from Windows Vista we have Unicode support built in. In Windows XP we can set it up from the installation CD.

Here we'll describe how to use Unicode in Visual C++ and use of native language string for example Bangla.


Above screenshot shows the Window having texts in Unicode. The code for the program is below.

This program demonstrates the use of Unicode and Bangla as a Unicode language. Some string manipulation functions have been used in the program to demonstrate. You need Unicode support in your system if you are using XP or earlier releases & you need a font named Bangla to run this program. Here are the instructions on how to setup complex-script for Bangla and installing the font.

/***************************************************
      How to program in Unicode
       Use of unicode strings manipulation functions

      -- S A Win32 Tutorial
***************************************************/

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <stdio.h>


// The main window class name.
static TCHAR szWindowClass[] = _T("win32app");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("S A Unicode Program");

HINSTANCE hInst;

// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void showTime(WCHAR *str, HDC tDC);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("S A Win32 Tutorial"),
            NULL);

        return 1;
    }

    hInst = hInstance; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application dows not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT,
        360, 220,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("S A Win32 Tutorial"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;
    HDC hdc;
      // WCHAR & wchar_t is same
    WCHAR greeting[100], strA[50];

    switch (message) {
            case WM_PAINT:
                  HFONT hFont;
                  RECT rect;
                  hdc = BeginPaint(hWnd, &ps);
                  // SetBkMode(hdc, TRANSPARENT);                 // Does not clear the area before drawing
                  // set font
                  hFont = CreateFont(30,0,0,0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Bangla"));
                  // Select font
                  SelectObject(hdc, hFont);

                  SetRect(&rect, 100,20,700,200);
                  SetTextColor(hdc, RGB(0,141,119));
                  swprintf(greeting, L"বাংলা ইউনিকোড প্রোগ্রাম");
                  TextOut(hdc, 40, 20, greeting, wcslen(greeting));
                  swprintf(strA, L" %d", wcslen(greeting));
                  swprintf(greeting, L"String - এর দৈর্ঘ্য:");
                  wcscat_s(greeting, strA);
                  TextOut(hdc, 40, 50, greeting, wcslen(greeting));
                  DeleteObject(hFont);

                  EndPaint(hWnd, &ps);
                  break;

            case WM_DESTROY:
                  PostQuitMessage(0);
                  break;
            default:
                  return DefWindowProc(hWnd, message, wParam, lParam);
                  break;
    }

    return 0;
}


Bangla is written in the program using Avro Keyboard.

Functions to manipulate Unicode(wide-char) strings

wcslen (wide-char version of strlen)
     Calculates string length

swprintf (wide-char version of sprintf)
     Write formatted data to a string.

wcscat (wide-char version of strcat)
     Append a string.

wcschr (wide-char version of strchr)
     Find a character in a string.

wcscpy (wide-char version of strcpy)
     Copy a string.

wcstok (wide-char version of strtok)
     Find the next token in a string.

We’are not gonna cover all functions. You have to find out what you need. The complete function list is in following link:
     http://msdn.microsoft.com/en-us/library/634ca0c2(VS.71).aspx

2 comments:

  1. Eto boro code kivabe pori.

    ReplyDelete
  2. See from "case WM_PAINT:" until "break;" That's the part dealing with the output thing here.

    ReplyDelete