views:

132

answers:

1

MFC File: winctrl4.cpp

(C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc)

CString CRichEditCtrl::GetSelText() const
{
    ASSERT(::IsWindow(m_hWnd));
    CHARRANGE cr;
    cr.cpMin = cr.cpMax = 0;
    ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
    CStringA strText;
    LPSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1)*2); 
    lpsz[0] = NULL;
    ::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
    strText.ReleaseBuffer();
    return CString(strText);
}

I am having a weird problem, when I call this it only returns the first character of the selected string. cr is correctly being set but after ::SendMessage(m_hWnd, EM_GETSELTEXT,... the whole string is not present.

I saw similar behavior in my custom code due to WCHAR issues (two-byte character containing a zero in one byte) when CHAR was expected. But this is part of MFC/Win32! Is it possible my .rc file sets something wrong? Is there a Create style relating to this? Or since we create a CFont for the control in question, could that screw it up?

+1  A: 

This is not the correct MFC source code, have you edited it? Using CStringA and LPSTR is quite inappropriate, the real code uses CString and LPTSTR so that Unicode is correctly handled. Yes, as posted the code would only return one character.


Seeing the version helped. The bug is described in this feedback article. If you can't reasonably upgrade to VS2008 SP1, you could derive your own class from CRichEditCtrl and replace the function. For example:

CString CRichEditCtrlFix::GetSelText() const
{
    ASSERT(::IsWindow(m_hWnd));
    CHARRANGE cr;
    cr.cpMin = cr.cpMax = 0;
    ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
    CString strText;
    LPTSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1) * 2);
    lpsz[0] = NULL;
    ::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
    strText.ReleaseBuffer();
    return CString(strText);
}
Hans Passant
This is the code we have in our SDK directory, it has not been edited. However, this project has been going since the 90s and it's entirely plausible we're on a very old version of MFC.
John
You don't know what MFC version you use but you do know that it wasn't edited in the past 15 years?
Hans Passant
Well since it was installed on my PC a few months ago, I assume so. I updated my post to show the full path of the file, and have confirmed that I can debug into that particular version. Plus, I definitely never _built_ MFC myself, so whatever DLL is being sued is one that was installed on my PC. How do _you_ know what the source looked like in every version of MFC to be sure it's wrong?
John
@John: that helped, I updated my answer.
Hans Passant
Oh, thanks a lot. Is it also possible I can separately download a newer version of MFC/platform SDK for use within VS2005?
John
That's best avoided. You'll have major deployment and manifest headaches.
Hans Passant