2

Hello Windows Programmers!

I am new to windows programming using winapi. I was reading this very nice book and I encountered a problem(displayed as a black box) when I display unicode character U+5167 (內) in the client area using DrawText and TextOut. Mysteriously, this particular unicode character is properly displayed in windows caption area. This unicode character is also displaying correctly when I display it using the MessageBox. Finally, I tried displaying other unicode characters that are relatively near to this unicode like U+5166, U+5168, U+5157 and U+5177;

Here's a link for this unicode character as defined by the standards. http://unicode-table.com/en/#5167

Note : I am compiling this code using Unicode using Visual Studio 2010

Below is my code.


#include<windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("HelloWin");
    HWND hwnd;
    MSG msg;

    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;

    if(!RegisterClass (&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,
                            TEXT("內Sample text 內篇 日本国 渡瀬 內篇全兦兗具 кошка"),
                            WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            NULL,
                            NULL,
                            hInstance,
                            NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
    LPTSTR c = TEXT("內Sample text 內篇 日本国 渡瀬 內篇全兦兗具 кошка");

    switch(message)
    {
        case WM_CREATE:
            PlaySound(TEXT("shutda.wav"), NULL, SND_FILENAME | SND_ASYNC);
MessageBox(hwnd, c, c, 0);
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            GetClientRect(hwnd, &rect);         
            DrawTextEx(hdc, c, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER, NULL);
            TextOut(hdc, 100, 100, TEXT("內篇 日本国 кошка unicode"), 19);
            EndPaint(hwnd, &ps);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

For non windows programmers, you can compile and run this code by copy and pasting this directly to a .cpp file. If you are using VS2010, you just need to create new "Win32 Application" project and select "Empty Project". After that, you need to add a cpp file for example "test.cpp" in the source folder of your project. Then copy and past the code to the "test.cpp" then build and run it. You should now see my problem. :)

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
wembikon
  • 91
  • 2
  • 9
  • 1
    Have you checked your default font contains the necessary glyphs? – Richard May 30 '14 at 09:11
  • Hi Richard. I didn't check my default font but if the font is to be blamed, how is it possible for that character to be displayed correctly using messagebox and the caption area of the window but not when using TextOut or DrawText functions? – wembikon May 30 '14 at 09:17
  • 1
    Message boxes, window titles and default window font can all be different. – Richard May 30 '14 at 09:22
  • I see. How do I check if I am using the correct font for TextOut and DrawText? – wembikon May 30 '14 at 09:24
  • I cannot recall how to see why font is currently set in the DC (this might help: [*Display Device Context Defaults*](http://msdn.microsoft.com/en-us/library/dd183573(v=vs.85).aspx)), but you set the DC's font with [`SelectObject`](http://msdn.microsoft.com/en-us/library/dd162957(v=vs.85).aspx) passing a font handle. – Richard May 30 '14 at 09:32
  • It is pointless using `TEXT()` here. The code cannot work with an ANSI build so you are just making it needlessly complex. – David Heffernan May 30 '14 at 09:55
  • @Richard Hi, thanks for answering. I have solved the problem by creating the font with glyph for this character and using SelectObject to set it to the DC. – wembikon May 30 '14 at 09:56
  • Please don't invalidate correct answers by editing the question. This issue is resolved, close your question by clicking the check mark to the left of the answer that solved your problem. – Hans Passant May 30 '14 at 10:03
  • @DavidHeffernan as I have mentioned, I am building this code using Unicode not ANSI. And also, the TEXT macro IMHO doesn't make anything complex rather it is making your code portable and more easy to scale in the future. – wembikon May 30 '14 at 10:05
  • The default font used by the DC doesn't contain a glyph for the unicode character U+5167. To solve this problem, you must create a font using CreateFont using a font family with a corresponding glyph for the said unicode character. Use this new font object in the device context by using SelectObject. – wembikon May 30 '14 at 10:12
  • `TEXT()` doesn't make the code portable. `TEXT()` is used for programs that can target both ANSI-only Win9x and Unicode WinNT. Those days are long gone and your program is absolutely not portable. It is Unicode only. So use `L"..."`. – David Heffernan May 30 '14 at 10:32
  • L"..." is just the same with TEXT("..."). It's just a matter of preference. I mean "Portable" source code for ansi/unicode versions and my program is absolutely not "Unicode only". Do you know anything about compiler arguments ANSI/UNICODE? – wembikon May 30 '14 at 10:56

1 Answers1

5

When a valid character is displayed as a rectangular box, that indicates that the font does not contain a glyph for the characters. In order to solve the problem you need to use a font which does have a glyph for this character.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490