winapivisual-c++mfcricheditcomctl32

MFC: rect provided to EM_REQUESTRESIZE cuts off text?


As I understood it, setting up ENM_REQUESTRESIZE would issue EN_REQUESTRESIZE to change the height (but not the width) per this article.

However, I found the call was changing the height and width. I only want the height to change. In my example the width was shorter than I want the rich text box so I just use the existing width, but the issue is the height was not high enough and cuts off the text.

Sample Pic

Here's what I did:

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;
}

The debug output was:

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

What am I doing wrong?

More Details:

If it's multi-line text, the last line is cutoff the same as the picture. If I calculate the border via GetWindowRect() vs GetClientRect() it's zero, if I calculate the internal border via GetRect() (EM_GETRECT) and GetClientRect() it's 1.


Solution

  • I can reproduce this problem with a plain (non-MFC) Win32 RichEdit.

    image

    The text is getting cut off because you are not resizing the RichEdit large enough. Near as I can tell, the requested rectangle is for the client area of the RichEdit, but you are interpreting the rectangle as being for the window as a whole.

    Try taking into account the spacing between the RichEdit's text and borders. You can use both CWnd::GetWindowRect() and CWnd::GetClientRect() and then add the difference to the requested height, eg:

    CRect rect;
    m_ctlRichEdit.GetWindowRect(rect);
    
    CRect crect;
    m_ctlRichEdit.GetClientRect(crect);
    
    REQRESIZE* prr = (REQRESIZE*)pNMHDR;
    m_ctlRichEdit.SetWindowPos(NULL, 0, 0, rect.Width(), (prr->rc.bottom - prr->rc.top) + (rect.Height() - crect.Height()), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);
    

    When I do this, the text is not cut off anymore.

    image