【问题标题】:Check for amount of line breaks — winapi c++检查换行符的数量——winapi c++
【发布时间】:2020-06-17 19:37:02
【问题描述】:

我有一个静态文本控件,它应该与窗口一起调整大小,它的文本宽度一开始小于整行文本,所以默认情况下它会像我需要的那样剪辑。

我想将文本垂直居中。当它被剪裁时,整个高度都被占用了,但是当静态的宽度足够大并且整个文本适合一行时,它就很高了。如何将其居中?

【问题讨论】:

  • 我以为可以在静态控件中设置一种样式来进行垂直对齐,但我找不到。您可以使用 SS_CENTER 等样式进行水平对齐。
  • @MarkRansom 我已经拥有SS_CENTER。如果您的意思是SS_CENTERIMAGE,它对我不起作用,因为它不会剪辑文本。
  • A STATIC 控件不支持垂直对齐。您必须使用SS_OWNERDRAW 样式并使用DrawText/Ex() 手动绘制文本,它具有DT_CENTERDT_VCENTER 标志。不过,DT_VCENTER 仅在同时使用 DT_SINGLELINE 标志时才有效。
  • 由于您没有在问题中包含任何代码,因此无法查看您包含或未包含哪些样式。
  • @RemyLebeau 你可能误解了我的意思。当你添加DT_VCENTERDT_SINGLELINE样式时,你会发现单行文本不会被剪裁。这与 OP 的预期不同。

标签: c++ winapi text static


【解决方案1】:

经过一番研究,发现可以自定义文字左上角的高度,实现垂直居中。当然,文本可以被截断。

当静态控件的长度小于文本的长度时,文本将被截断。所以我们需要在GetTextExtentPoint32的帮助下计算出文字的高度和长度。然后DrawText 完成其余的工作,应该添加DT_WORDBREAKDT_CENTER

具体细节见我的代码:

// Parent Hwnd
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        0, 0, 800, 600, nullptr, nullptr, hInstance, nullptr);

// Window Process
float nScale_x = 1.0, nScale_y = 1.0;
HWND static_hwnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT rc;   // the size of text
    RECT rect; // the size of Rectangle       
    switch (message)
    {
    case WM_CREATE:
    {
        static_hwnd = CreateWindow(L"STATIC",
            L"Some clipping text example",
            WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_OWNERDRAW,
            100, 100, 200, 50, 
            hWnd,
            NULL,
            NULL,
            NULL);
 
        return 1;
    }
    case WM_DRAWITEM:
    {
        LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)lParam;
        if (pDIS->hwndItem == static_hwnd)
        {          
            const wchar_t* text = L"Some clipping text example";
            HDC hDC = pDIS->hDC;
            RECT rect = pDIS->rcItem;
            RECT rc;

            int w = rect.right - rect.left;
            int h;
            if (w >= 180) // the length of "Some clipping text example"
            {
                h = 16;
            }
            else if (w < 92) //the length of "Some clipping"
            {
                h = 16 * 3;
            }
            else if (w < 180) 
            {
                h = 16 * 2;
            }
            rc.left = rect.left;
            rc.right = rect.right;
            rc.top = ((rect.bottom - rect.top) - h) / 2;
            rc.bottom = rect.bottom;

            HBRUSH bg = (HBRUSH)(::GetStockObject(LTGRAY_BRUSH));
            HPEN pn = (HPEN)(::GetStockObject(BLACK_PEN));
            ::SelectObject(hDC, bg);

            //SIZE sz;
            //GetTextExtentPoint32(hDC, text, 13, &sz); 
            ::SelectObject(hDC, pn);
            ::SetTextColor(hDC, RGB(0, 0, 0));           
            ::Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
            ::DrawText(hDC, text, wcslen(text), &rc, DT_WORDBREAK | DT_CENTER); 
        }
        return TRUE;
    }        
    case WM_SIZE:
    {
        GetWindowRect(hWnd, &rc);
        nScale_x = (rc.right - rc.left) / 800.0;
        nScale_y = (rc.bottom - rc.top) / 600.0;
        SetWindowPos(static_hwnd, NULL, 100, 100, 200 * nScale_x, 50 * nScale_y, SWP_SHOWWINDOW);
    }        
    ...

调试:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多