EDIT控件绘制发送时间后原文本隐藏的技术问题咨询
问题分析与解决方案
问题根源在于子类化EDIT控件时,你的WM_PAINT处理直接跳过了控件本身的绘制逻辑,仅绘制了时间,导致原文本未被渲染;而鼠标选中时系统触发局部重绘,才临时显示出文本。
核心修改思路
- 先让EDIT控件完成自身文本的默认绘制,再叠加绘制发送时间
- 调整时间绘制位置到右下角,并通过设置控件内边距避免文本与时间重叠
- 移除引发闪烁的无效重绘调用
修改后的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
相关产品推荐
相关产品推荐

