You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SetTextColor设置后文本填充透明,修改颜色仅轮廓变化的解决求助

DC绘图:文本仅显轮廓、背景区域过大的解决方案

1. 修复文本仅显示轮廓的问题

你看到文本只有轮廓、填充透明,核心原因是当前DC里选的是空心字体,不是实心样式。GDI默认字体可能不符合预期,得手动创建并选入实心字体:

// 创建实心字体(可按需调整字号、字体名称)
HFONT hFont = CreateFont(
    24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
    DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"微软雅黑"
);
// 把字体选进DC,保存旧字体方便后续还原
HFONT hOldFont = (HFONT)SelectObject(hdcDest, hFont);

// 你的原有绘制代码
RECT textRect;
textRect.left = 200;
textRect.top = 405;
textRect.right = combinedSize.cx;
textRect.bottom = combinedSize.cy;
SetTextColor(hdcDest, RGB(0, 0, 0));
SetBkMode(hdcDest, TRANSPARENT);
DrawText(hdcDest, text.c_str(), -1, &textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

// 还原旧字体,释放新字体资源(必须做,避免内存泄漏)
SelectObject(hdcDest, hOldFont);
DeleteObject(hFont);

要是不需要透明背景,把SetBkMode(hdcDest, TRANSPARENT)改成SetBkMode(hdcDest, OPAQUE),再用SetBkColor设置背景色就行。

2. 解决背景区域大于文本的问题

要让背景完全贴合文本,得先拿到文本的精确像素尺寸,再基于这个尺寸画背景和文本:

// 获取文本的实际宽高
SIZE textSize;
GetTextExtentPoint32(hdcDest, text.c_str(), (int)text.length(), &textSize);

// 生成刚好包裹文本的矩形(以原坐标(200,405)为左上角)
RECT textRect;
textRect.left = 200;
textRect.top = 405;
textRect.right = 200 + textSize.cx;
textRect.bottom = 405 + textSize.cy;

// 绘制背景(示例用白色,可换其他颜色)
SetBkColor(hdcDest, RGB(255,255,255));
FillRect(hdcDest, &textRect, (HBRUSH)GetStockObject(WHITE_BRUSH));

// 绘制文本,这里设TRANSPARENT避免和手动画的背景冲突
SetTextColor(hdcDest, RGB(0,0,0));
SetBkMode(hdcDest, TRANSPARENT);
DrawText(hdcDest, text.c_str(), -1, &textRect, DT_LEFT | DT_TOP | DT_SINGLELINE);

如果要让文本在原区域居中,同时背景只包裹文本,可以先算居中后的左上角坐标:

// 原区域(你用combinedSize定义的范围)
RECT originalArea = {0, 0, combinedSize.cx, combinedSize.cy};
// 计算居中后的文本左上角
int centerX = originalArea.left + (originalArea.right - originalArea.left - textSize.cx) / 2;
int centerY = originalArea.top + (originalArea.bottom - originalArea.top - textSize.cy) / 2;
// 用这个坐标生成文本矩形
textRect.left = centerX;
textRect.top = centerY;
textRect.right = centerX + textSize.cx;
textRect.bottom = centerY + textSize.cy;

额外注意事项

  • 绘制文本前,确保DC里没有残留的画刷、画笔等GDI对象,避免干扰绘制效果。
  • 所有选入DC的GDI对象(比如字体、画刷),用完一定要还原并释放,防止内存泄漏。

内容的提问来源于stack exchange,提问作者marus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:15:37