Windows API学习-static静态文本框控件(1)


使用 TextOut 和 DrawText 函数有时候会不方便,例如:
文本不能自动换行,超出窗口范围会被隐藏;
每次更改文本都要先擦除背景再重新输出,比较麻烦。

实际开发中一般使用静态文本框控件来输出文本。静态文本框是Windows 的一种标准控件,可以用来在窗口上显示一段文本,并且文本容易受到控制。除了静态文本框,Windows的标准控件还有很多种,例如按钮、下拉菜单、单选按钮、复选框等。

其实,控件也是一种窗口,也使用 CreateWindow 函数来创建。但是它们使用的窗口类的名字比较特殊,是由Windows预定义的;静态文本框控件的窗口类名是static。

与前面创建的独立窗口不同,控件是子窗口,创建时必须指定父窗口,这样控件才能有“归属”。

我们先来回顾一下 CreateWindow 函数的原型:

HWND CreateWindow(
    LPCWSTR lpClassName,  //窗口类名
    LPCWSTR lpWindowName,  //窗体标题(或控件文本)
    DWORD dwStyle,  //窗口/控件样式
    int x,  //窗口相对桌面(或子窗口相对父窗口)的 X 坐标
    int y,  //窗口相对桌面(或子窗口相对父窗口)的 Y 坐标
    int nWidth,  //窗体宽度
    int nHeight,  //窗体高度
    HWND hWndParent,  //父窗口句柄
    HMENU hMenu,  //菜单句柄
    HINSTANCE hInstance,  //当前程序实例句柄
    LPVOID lpParam  //一个指向某数值的指针
);

几点说明:
1) 对于参数 lpClassName 和 lpWindowName,一般使用宽字符,请加前缀L或使用TEXT()。

lpClassName 为窗口类的名字,可以是 RegisterClass 注册的类名,也可以是 Windows 预定义的控件类名。

如果你创建的是独立窗口,则 lpWindowName 应传入窗口的标题,若你希望创建控件,则应传入控件的文本。

2) dwStyle 表示窗口样式或控件样式。窗口样式以 WS 开头,详情请查看《CreateWindow窗口风格取值》。这些样式既可以用于独立窗口,也可以用于控件(子窗口)。

除了窗口样式,不同的控件也有自己特有的样式。对于 static 控件,它的样式以 SS 开头,常用的有:

样样式	        说明
SS_LEFT	        文本居左。
SS_RIGHT	文本居右。
SS_CENTER	文本居中。
SS_CENTERIMAGE	文本垂直居中。设置该样式后只能显示一行文本,即使有 '\n' 也不会换行。
SS_LEFTNOWORDWRAP	文本居左,不自动换行(有 '\n' 才会换行),超出控件范围的文本将被隐藏。
SS_SIMPLE	只显示一行文本(有 '\n' 也不换行),且不自动换行,超出控件范围的文本将被隐藏。

3) 对于参数 hWndParent,如果是独立窗口,那么为 NULL,如果是控件,那么就需要父窗口的句柄。

4) 参数 hMenu 十分重要,在后续介绍的需要处理控件消息的控件中,这是他们的唯一标识符。每个控件的 hMenu 参数值都应不同,并且需要强制转换到 HMENU 类型,如 (HMENU)1 ,再次强调,每个控件的(HMENU)后的值都应不同,可以从1往下递推。

下面的代码,会在 WM_CREATE 事件中创建 static 控件:

//窗口过程
LRESULT CALLBACK WndProc(
    HWND hWnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam
){
    PAINTSTRUCT ps;
    HDC hdc;
    HWND hStatic;
    switch (message){
        case  WM_CREATE:
            hStatic = CreateWindow(
                L"static", //静态文本框的类名
                L"C语言中文网",  //控件的文本
                WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/| SS_CENTER /*水平居中*/ | SS_CENTERIMAGE /*垂直居中*/,
                20 /*X坐标*/, 20 /*Y坐标*/, 200 /*宽度*/, 100 /*高度*/,
                hWnd,  //父窗口句柄
                (HMENU)1,  //为控件指定一个唯一标识符
                hInst,  //当前程序实例句柄
                NULL
            );
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO:  在此添加任意绘图代码...
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam) ;
}

运行效果:
2.png