《Windows32 SDK教程》04章 字符串的显示


文本字符在窗口中显示一般有2种方法,一是在指定位置显示文字使用TextOut()函数,在指定区域显示文字使用上一章讲的DrawText()函数功能比较强大,能自动回行、显示快捷键上下左右对齐等。另外本章还要介绍如何设置文本的前景背景。

一、DrawText()函数的格式

DrawText()函数的原型上一章已经说明,这儿仅解释其中的最后一个参数:格式输出。下面列举部分值,详细内容得看HELP。

说明
DT_LEFT
DT_CENTER
DT_RIGHT
这是横向对齐的三种方式。
DT_TOP
DT_VCENTER
DT_BOTTOM
这是纵向对齐的三种方式,但必须和DT_SINGLELINE一起使用。
DT_END_ELLIPSIS
DT_WORD_ELLIPSIS
DT_PATH_ELLIPSIS
一行写不下时用省略号代替。
DT_WORDBREAK一行写不下时自动回行。
............

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    TCHAR szHello[64]="Wecome you to Http://www.quanxue.cn/, 欢迎你来到小雅的劝学网!";
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);

            //定义四个区域,初始值为窗口有效区
            RECT rt1, rt2, rt3, rt4;
            GetClientRect(hWnd, &rt1);
            rt2 = rt3 = rt4 = rt1;

            //设置rt1为窗口有效区的上面四分之一
            rt1.bottom /= 4;
            rt2.top = rt1.bottom;
            //设置rt2为窗口有效区的中上四分之一
            rt2.bottom /= 2;
            rt3.top = rt2.bottom;
            //设置rt3为窗口有效区的中下四分之一
            rt3.bottom -= rt1.bottom;
            //设置rt4为窗口有效区的下面四分之一
            rt4.top = rt3.bottom;

            //当文字在窗口中显示不下时的四种情况的比较
            DrawText(hdc, szHello, (int)strlen(szHello), &rt1, DT_END_ELLIPSIS);
            DrawText(hdc, szHello, (int)strlen(szHello), &rt2, DT_WORD_ELLIPSIS);
            DrawText(hdc, szHello, (int)strlen(szHello), &rt3, DT_PATH_ELLIPSIS);
            DrawText(hdc, szHello, (int)strlen(szHello), &rt4, DT_WORDBREAK);

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

二、改变文字前景色SetTextColor()函数

Windows中颜色类型是COLORREF,实际上就是DWORD类型(即32位无符号整型),共4字节,高位的一个字节保留为00,其它三个字节表示红绿兰三元色,用16进制即是0x000000FF表示“红色”,不用的1字节一般不写,所以一般写成0x0000FF,而0x00FF00表示“绿色”,0xFF0000表示“兰色”,0xFFFFFF表示“白色”,0x000000表示“黑色”。

颜色除了可以用16进制很直观地表示之外,还可以用10进制表示,例如16711935用计算器换算一下就知道这是16进制的0xFF00FF表示“粉红色”。另外,还可以用RGB()宏函数将红绿兰三个整数合成一个颜色值,例如上面的粉红色可以写成RGB(256,0,256)或RGB(0xFF,0,256)。

如果已经知道了某颜色的值,可以通过GetRValue(),GetGValue(),GetBValue()来取得红绿兰的三元色。例如GetRValue(16711935),结果为255。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    TCHAR szHello[64]="Wecome you to Http://www.quanxue.cn/, 欢迎你来到小雅的劝学网!";
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);

            //定义四个区域,初始值为窗口有效区
            RECT rt1, rt2, rt3, rt4;
            GetClientRect(hWnd, &rt1);
            rt2 = rt3 = rt4 = rt1;

            //设置rt1为窗口有效区的上面四分之一
            rt1.bottom /= 4;
            rt2.top = rt1.bottom;
            //设置rt2为窗口有效区的中上四分之一
            rt2.bottom /= 2;
            rt3.top = rt2.bottom;
            //设置rt3为窗口有效区的中下四分之一
            rt3.bottom -= rt1.bottom;
            //设置rt4为窗口有效区的下面四分之一
            rt4.top = rt3.bottom;

            //当文字在窗口中显示不下时的四种情况的比较
            SetTextColor(hdc, 0x0000FF);
            DrawText(hdc, szHello, (int)strlen(szHello), &rt1, DT_END_ELLIPSIS);
            SetTextColor(hdc, RGB(0, 256, 0));    //0x00FF00
            DrawText(hdc, szHello, (int)strlen(szHello), &rt2, DT_WORD_ELLIPSIS);
            SetTextColor(hdc, RGB(0xFF, 0, 0));   //0xFF0000
            DrawText(hdc, szHello, (int)strlen(szHello), &rt3, DT_PATH_ELLIPSIS);
            SetTextColor(hdc,16711935);            //0xFF00FF
            DrawText(hdc, szHello, (int)strlen(szHello), &rt4, DT_WORDBREAK);

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

三、改变文字背景色SetBkColor()函数

上面的程序看上去好象没有背景,但实际上是有的,因为系统默认背景色是白色。只要将InitApp()函数中的WHITE_BRUSH改成GRAY_BRUSH,你就会看到右图的效果。

设置文字背景用SetBkColor()函数,该函数如果成功,则返回前一背景色,否则返回CLR_INVALID。如果不需要文字有背景,可以通过SetBkMode()函数来实现背景透明或不透明。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    TCHAR szHello[64]="Wecome you to Http://www.quanxue.cn/, 欢迎你来到小雅的劝学网!";
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);

            //定义四个区域,初始值为窗口有效区
            RECT rt1, rt2, rt3, rt4;
            GetClientRect(hWnd, &rt1);
            rt2 = rt3 = rt4 = rt1;

            //设置rt1为窗口有效区的上面四分之一
            rt1.bottom /= 4;
            rt2.top = rt1.bottom;
            //设置rt2为窗口有效区的中上四分之一
            rt2.bottom /= 2;
            rt3.top = rt2.bottom;
            //设置rt3为窗口有效区的中下四分之一
            rt3.bottom -= rt1.bottom;
            //设置rt4为窗口有效区的下面四分之一
            rt4.top = rt3.bottom;

            //当文字在窗口中显示不下时的四种情况的比较
            SetTextColor(hdc, 0x0000FF);
            SetBkColor(hdc, 0xCDFAFF);    //设置文字背景
            DrawText(hdc, szHello, (int)strlen(szHello), &rt1, DT_END_ELLIPSIS);
            SetTextColor(hdc, RGB(0, 256, 0));
            SetBkColor(hdc, 0xFFFFE0);    //设置文字背景
            DrawText(hdc, szHello, (int)strlen(szHello), &rt2, DT_WORD_ELLIPSIS);
            SetTextColor(hdc, 0x00FFFF);
            SetBkMode(hdc, TRANSPARENT);  //设置背景为透明
            DrawText(hdc, szHello, (int)strlen(szHello), &rt3, DT_PATH_ELLIPSIS);
            SetTextColor(hdc,16711935);
            SetBkMode(hdc, OPAQUE);       //设置背景为不透明
            SetBkColor(hdc, 0xF0FFF0);    //设置文字背景
            DrawText(hdc, szHello, (int)strlen(szHello), &rt4, DT_WORDBREAK);

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