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

MFC中使用EN_REQUESTRESIZE调整RichEdit高度时文本被截断?

问题描述

设置ENM_REQUESTRESIZE后,本应触发EN_REQUESTRESIZE仅修改RichEdit控件的高度(而非宽度),但实际调用时宽高均被修改。保留控件原有宽度后,调整后的高度仍不足,导致文本被截断。

实现代码

void CDialogX::OnEnRequestResize( NMHDR* pNMHDR, LRESULT* pResult )
{
   _ASSERT( pNMHDR->code == EN_REQUESTRESIZE );

   CRect rect;
   m_ctlRichEdit.GetWindowRect(rect);
   ScreenToClient(rect);

   CDebugPrint::DebugPrint(_T("existing size %i %i %i %i\n"), rect.left, rect.top, rect.right, rect.bottom);
   
   REQRESIZE* prr = (REQRESIZE*)pNMHDR;
   m_ctlRichEdit.SetWindowPos(NULL, 0, 0, rect.Width(), prr->rc.bottom - prr->rc.top, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);

   CDebugPrint::DebugPrint(_T("requested size %i %i %i %i\n"), prr->rc.left, prr->rc.top, prr->rc.right, prr->rc.bottom);

  // get new size
  m_ctlRichEdit.GetWindowRect(rect);
  ScreenToClient(rect);

  CDebugPrint::DebugPrint(_T("new size %i %i %i %i\n"), rect.left, rect.top, rect.right, rect.bottom);
  
  // ...
  
  *pResult=0;
}

调试输出

existing size 60 57 329 58
requested size 60 57 241 70
new size 60 57 329 70

补充细节

  • 多行文本时最后一行会被截断
  • 通过GetWindowRect与GetClientRect计算边框为0
  • 通过GetRect(EM_GETRECT)与GetClientRect计算内部边框为1

解决方案

问题核心是未考虑RichEdit内部的文本区域边距,且误用了REQRESIZE结构体的尺寸含义。

错误点分析

  1. REQRESIZE中的rc是控件需要的内部文本显示区域尺寸,不是整个窗口的尺寸。你直接用这个高度设置窗口高度,会导致实际文本显示区域因内部边距被压缩,空间不足。
  2. 即便窗口边框为0,EM_GETRECT得到的内部文本区域和客户区仍有1像素边距,这部分差值被你忽略,导致最终文本显示高度不够。

修正步骤

  1. 先计算控件内部的垂直边距总和:
    CRect clientRect;
    m_ctlRichEdit.GetClientRect(clientRect);
    CRect textRect;
    m_ctlRichEdit.SendMessage(EM_GETRECT, 0, (LPARAM)&textRect);
    int verticalMargin = clientRect.Height() - textRect.Height();
    
  2. 将REQRESIZE请求的文本区域高度,加上垂直边距,作为窗口的目标高度,同时保留原有宽度:
    int targetHeight = (prr->rc.bottom - prr->rc.top) + verticalMargin;
    m_ctlRichEdit.SetWindowPos(NULL, 0, 0, rect.Width(), targetHeight, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);
    
  3. 额外检查:确保RichEdit控件禁用ES_AUTOHSCROLL样式,这样控件才会自动换行,仅触发高度调整的请求,避免宽度被修改。

修正后的示例代码

void CDialogX::OnEnRequestResize( NMHDR* pNMHDR, LRESULT* pResult )
{
   _ASSERT( pNMHDR->code == EN_REQUESTRESIZE );

   CRect rect;
   m_ctlRichEdit.GetWindowRect(rect);
   ScreenToClient(rect);

   CDebugPrint::DebugPrint(_T("existing size %i %i %i %i\n"), rect.left, rect.top, rect.right, rect.bottom);
   
   REQRESIZE* prr = (REQRESIZE*)pNMHDR;
   CDebugPrint::DebugPrint(_T("requested text area size %i %i %i %i\n"), prr->rc.left, prr->rc.top, prr->rc.right, prr->rc.bottom);

   // 计算内部垂直边距
   CRect clientRect;
   m_ctlRichEdit.GetClientRect(clientRect);
   CRect textRect;
   m_ctlRichEdit.SendMessage(EM_GETRECT, 0, (LPARAM)&textRect);
   int verticalMargin = clientRect.Height() - textRect.Height();

   // 目标高度 = 请求的文本区域高度 + 垂直边距
   int targetHeight = (prr->rc.bottom - prr->rc.top) + verticalMargin;
   m_ctlRichEdit.SetWindowPos(NULL, 0, 0, rect.Width(), targetHeight, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);

   // 获取新尺寸
   m_ctlRichEdit.GetWindowRect(rect);
   ScreenToClient(rect);
   CDebugPrint::DebugPrint(_T("new size %i %i %i %i\n"), rect.left, rect.top, rect.right, rect.bottom);
  
   *pResult=0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:48:28