六、C语言创建桌面程序:Static控件(静态文本框控件)

一、创建文本控件

使用 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 控件:

#include <windows.h>

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

HINSTANCE hInst;

int WINAPI WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        PSTR szCmdLine,
        int iCmdShow
){
    static TCHAR szClassName[] = TEXT("Hello World");
    HWND     hwnd;  
    MSG      msg; 
    WNDCLASS wndclass;  

    hInst = hInstance;
    
    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= szClassName; 

    RegisterClass(&wndclass);

 
    hwnd = CreateWindow(
            szClassName,  
            TEXT("Welcome"),  
            WS_OVERLAPPEDWINDOW,  
            CW_USEDEFAULT,  
            CW_USEDEFAULT,  
            500, 
            300,  
            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
){
    PAINTSTRUCT ps;
    HDC hdc;
    HWND hStatic;

    switch (message){
        case  WM_CREATE:
            hStatic = CreateWindow(
                    TEXT("static"), 
                    TEXT("Hello World"),  
                    WS_CHILD | WS_VISIBLE  | WS_BORDER | SS_CENTER | SS_CENTERIMAGE ,
                    20 , 20 , 200 , 100 ,
                    hWnd,  
                    (HMENU)1, 
                    hInst, 
                    NULL
            );
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam) ;
}

二、获取、修改控件文本

GetWindowText 函数用于将指定窗口的标题文本(如果存在)拷贝到一个缓存区内;如果指定的窗口是一个控件,则拷贝控件的文本。它的原型为:

// 函数执行成功,返回拷贝的字符的个数
Int GetWindowText(
    HWND hWnd,  //窗口/控件句柄
    LPTSTR lpString,  //指向接收文本的缓冲区指针
    Int nMaxCount  //要保存在缓冲区内的字符的最大个数,nMaxCount 指定要保存在缓冲区内的字符的最大个数,其中包含NULL字符。如果文本超过界限,它就被截断。
);

SetWindowText 函数可以用来设置窗口标题或控件文本,它的原型为:

BOOL SetWindowText(
    HWND hwnd,
    LPCTSTR lpString
);

下面的例子用来显示鼠标点击的次数:

#include <windows.h>

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

HINSTANCE hInst;

int WINAPI WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        PSTR szCmdLine,
        int iCmdShow
){
    static TCHAR szClassName[] = TEXT("Hello World");
    HWND     hwnd;
    MSG      msg;
    WNDCLASS wndclass;

    hInst = hInstance;

    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= szClassName;

    RegisterClass(&wndclass);


    hwnd = CreateWindow(
            szClassName,
            TEXT("Welcome"),
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            500,
            300,
            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
){
    PAINTSTRUCT ps;
    HDC hdc;
   
    static int iClick = 0; 
    static TCHAR szTextBuf[20];  
    static HWND hStatic;  

    switch (message){
        case  WM_CREATE:
            hStatic = CreateWindow(
                    TEXT("static"), 
                    TEXT("Hello World"),  
                    WS_CHILD  | WS_VISIBLE  | WS_BORDER | SS_CENTER | SS_CENTERIMAGE ,
                    20 , 20 , 200 , 100 ,
                    hWnd, 
                    (HMENU)1, 
                    hInst,  
                    NULL
            );
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
        case WM_LBUTTONDOWN:
            iClick++;
            wsprintf(szTextBuf, TEXT("鼠标点击了%d次"), iClick);
            SetWindowText(hStatic, szTextBuf);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam) ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值