Win32窗体添加状态栏

⌚Time: 2023-01-19 13:18:50

👨‍💻Author: Jack Ge

需要的头文件

Commctrl.h

使用CreateStatusWindow创建一个状态窗口,该窗口通常用于显示应用程序的状态。 该窗口通常显示在父窗口底部,其中包含指定的文本。


HWND CreateStatusWindowA(

  LONG   style,

  LPCSTR lpszText,

  HWND   hwndParent,

  UINT   wID

);

参数

style



类型: LONG



状态窗口的窗口样式。 此参数必须包含 WS_CHILD 样式,还应包含 WS_VISIBLE 样式。



lpszText



类型: LPCTSTR



指向以 null 结尾的字符串的指针,该字符串指定第一部分的状态文本。



hwndParent



类型: HWND



父窗口的句柄。



wID



类型: UINT



状态窗口的控制标识符。 窗口过程使用此值标识它发送到父窗口的消息。



返回值

类型: HWND



如果成功,则返回状态窗口的句柄;否则返回 NULL 。 若要检索扩展的错误信息,请调用 GetLastError。

发送SB_SETPARTS消息设置状态窗口中的部件数和每个部件右边缘的坐标。


参数

wParam



要设置 (的部件数不能大于 256) 。



lParam



指向整数数组的指针。 在 wParam 中指定元素数。 每个元素指定相应部分右边缘的位置(以客户端坐标为单位)。 如果元素为 -1,则相应部分的右边缘将扩展到窗口的边框。



返回值

如果成功,则返回 TRUE ;否则返回 FALSE 。

代码


HWND hStatus = CreateStatusWindow(WS_CHILD| WS_VISIBLE, NULL, hwnd, IDC_STATUS_0);

RECT rect;

GetClientRect(hwnd, &rect);//获得窗口的尺寸

int nWith = rect.right/6;//rect.right是0-控件的宽度,6等分

int nWiths[3] = { nWith * 4/*4/6宽度*/, nWith * 5/*5/6宽度*/, -1};

SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)nWiths);//设置状态栏分隔符

发送SB_SETTEXT消息设置状态窗口的指定部分的文本。


参数

wParam



低序单词的 LOBYTE 指定要设置的部件的从零开始的索引。 如果 LOBYTE 设置为SB_SIMPLEID,则状态窗口假定为简单模式状态栏;也就是说,只有一个部分的状态栏。



低序单词的 HIBYTE 指定绘图操作的类型。 此参数的取值可为下列值之一:



将忽略 wParam 的高序单词。



值   含义

0

用边框绘制文本,其显示范围低于窗口平面。

SBT_NOBORDERS

文本在没有边框的情况下绘制。

SBT_OWNERDRAW

文本由父窗口绘制。

[!注意]

简单模式状态栏不支持所有者绘图。



SBT_POPOUT

用边框绘制文本,显示高于窗口平面的边框。

SBT_RTLREADING

文本将以与父窗口中的文本相反的方向显示。

SBT_NOTABPARSING

将忽略制表符。

lParam



指向指定要设置的文本的 null 终止字符串的指针。 如果 wParam SBT_OWNERDRAW,此参数表示 32 位数据。 父窗口必须解释数据并在收到 WM_DRAWITEM 消息时绘制文本。



返回值

如果成功,则返回 TRUE ;否则返回 FALSE 。

SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"1111");

SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)"222");

SendMessage(hStatus, SB_SETTEXT, 2, (LPARAM)"3333");

g++编译参数,需要连接到comctl32库


g++ test.cpp -lcomctl32

对于窗体大小发送改变,状态栏不能跟随改变。可以在父窗体的WM_SIZE消息响应中进行处理。调整状态栏的大小和位置

WM_SIZE


#define WM_SIZE                         0x0005

参数

wParam



请求的大小调整的类型。 此参数的取值可为下列值之一:



值   含义

SIZE_MAXHIDE

4

当其他一些窗口最大化时,消息将发送到所有弹出窗口。

SIZE_MAXIMIZED

2

窗口已最大化。

SIZE_MAXSHOW

3

当其他一些窗口还原到其以前的大小时,消息将发送到所有弹出窗口。

SIZE_MINIMIZED

1

窗口已最小化。

SIZE_RESTORED

0

窗口已调整大小,但 SIZE_MINIMIZED 和 SIZE_MAXIMIZED 值均未应用。

 



lParam



lParam 的低序字指定工作区的新宽度。



lParam 的高序字指定工作区的新高度。

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){

switch (uMsg)

    {

    ...

    case WM_SIZE:

        {

            int nWith = LOWORD(lParam)/6;

            int nWiths[3] = { nWith * 4, nWith * 5, -1};

            SendMessage(GetDlgItem(hwnd,IDC_STATUS_0), SB_SETPARTS, 3, (LPARAM)nWiths);

            //重新调整位置大小

            MoveWindow(GetDlgItem(hwnd,IDC_STATUS_0), 0, 0, 0, 0, TRUE);

        }

        return 0;

    }

}

完整的代码

#include <windows.h>
#include <commctrl.h>
#define IDC_STATUS_0 1000
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
{
    // Register the window class.
    const char CLASS_NAME[]  = "Window0119 Class";

    WNDCLASSA wc = { };

    wc.lpfnWndProc   = WindowProc;
    wc.hInstance     = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClassA(&wc);

    // Create the window.

    HWND hwnd = CreateWindowEx(
        0,
        CLASS_NAME,                     // Window class
        "window",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, 600, 400,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
        );

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    // Run the message loop.

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        {
            HWND hStatus = CreateStatusWindow(WS_CHILD| WS_VISIBLE, NULL, hwnd, IDC_STATUS_0);
            RECT rect;
            GetClientRect(hwnd, &rect);//获得窗口的尺寸
                int nWith = rect.right/6;
            int nWiths[3] = { nWith * 4, nWith * 5, -1};
            SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)nWiths);
            SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"1111");
            SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)"222");
            SendMessage(hStatus, SB_SETTEXT, 2, (LPARAM)"3333");
        }
        return 0;
    case WM_SIZE:
        {
                int nWith = LOWORD(lParam)/6;
            int nWiths[3] = { nWith * 4, nWith * 5, -1};
            SendMessage(GetDlgItem(hwnd,IDC_STATUS_0), SB_SETPARTS, 3, (LPARAM)nWiths);
            //重新调整位置
            MoveWindow(GetDlgItem(hwnd,IDC_STATUS_0), 0, 0, 0, 0, TRUE);
        }
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);


            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        return 0;

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