经过一番研究,发现可以自定义文字左上角的高度,实现垂直居中。当然,文本可以被截断。
当静态控件的长度小于文本的长度时,文本将被截断。所以我们需要在GetTextExtentPoint32的帮助下计算出文字的高度和长度。然后DrawText 完成其余的工作,应该添加DT_WORDBREAK 和DT_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);
}
...
调试: