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

EDIT控件绘制发送时间后原文本隐藏的技术问题咨询

问题分析与解决方案

问题根源在于子类化EDIT控件时,你的WM_PAINT处理直接跳过了控件本身的绘制逻辑,仅绘制了时间,导致原文本未被渲染;而鼠标选中时系统触发局部重绘,才临时显示出文本。

核心修改思路

  1. 先让EDIT控件完成自身文本的默认绘制,再叠加绘制发送时间
  2. 调整时间绘制位置到右下角,并通过设置控件内边距避免文本与时间重叠
  3. 移除引发闪烁的无效重绘调用

修改后的WM_PAINT处理代码

case WM_PAINT:
{
    // 先调用原窗口过程,让EDIT控件完成默认文本绘制
    LRESULT defaultResult = DefSubclassProc(hWnd, uMsg, wParam, lParam);

    // 获取UI管理器实例
    UIManager* manager = (UIManager*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    if (!manager)
    {
        return defaultResult;
    }

    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);
    if (!hdc)
    {
        return defaultResult;
    }

    // 准备时间文本
    const wchar_t* timeText = L"10:45";
    int textLen = lstrlen(timeText);

    // 计算时间文本的尺寸
    SIZE textSize;
    GetTextExtentPoint32(hdc, timeText, textLen, &textSize);

    // 获取客户区矩形
    RECT clientRect;
    GetClientRect(hWnd, &clientRect);

    // 计算右下角绘制位置(留出边距避免贴边)
    int drawX = clientRect.right - textSize.cx - 5;
    int drawY = clientRect.bottom - textSize.cy - 2;

    // 切换到指定字体并绘制时间
    HFONT oldFont = (HFONT)SelectObject(hdc, manager->message_date_sent_font);
    TextOut(hdc, drawX, drawY, timeText, textLen);
    // 恢复原字体
    SelectObject(hdc, oldFont);

    EndPaint(hWnd, &ps);
    return defaultResult;
}

补充:设置EDIT控件内边距(避免文本与时间重叠)

在创建EDIT控件后,添加以下代码,确保控件文本不会绘制到时间区域:

// 临时DC计算时间文本尺寸
HDC tempDC = GetDC(*new_message_window);
HFONT oldTempFont = (HFONT)SelectObject(tempDC, manager->message_date_sent_font);
SIZE timeTextSize;
const wchar_t* tempTimeText = L"10:45";
GetTextExtentPoint32(tempDC, tempTimeText, lstrlen(tempTimeText), &timeTextSize);
SelectObject(tempDC, oldTempFont);
ReleaseDC(*new_message_window, tempDC);

// 设置控件右边距和下边距
SendMessage(*new_message_window, EM_SETMARGINS, 
            EC_RIGHTMARGIN | EC_BOTTOMMARGIN, 
            MAKELPARAM(timeTextSize.cx + 5, timeTextSize.cy + 2));

关键说明

  • 调用DefSubclassProc让控件先完成自身绘制,保证原文本正常显示
  • 计算时间文本尺寸后定位到右下角,避免与控件文本重叠
  • 移除原代码中RedrawWindow和SetWindowPos调用,这类操作会触发无限重绘导致闪烁
  • 若时间文本动态变化,只需调用InvalidateRect(hWnd, NULL, FALSE)触发重绘即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:04:52