Search code examples
c#.netwinapipinvokesendmessage

what's the proper way to retrieve text from a Rich Text Control using the Windows API?


The GetRTF() method below sort of works, but it retrieves only metadata:

    public string GetRTF(IntPtr handle)
    {
        string result = String.Empty;
        using (System.IO.MemoryStream stream = new MemoryStream())
        {
            EDITSTREAM editStream = new EDITSTREAM();
            editStream.pfnCallback = new EditStreamCallback(EditStreamProc);
            editStream.dwCookie = stream;

            SendMessage(handle, EM_STREAMOUT, SF_RTF, ref editStream);

            stream.Seek(0, SeekOrigin.Begin);
            using (StreamReader reader = new StreamReader(stream))
            {
                result = reader.ReadToEnd();
            }
        }
        return result;
    }

    private int EditStreamProc(MemoryStream dwCookie, IntPtr pbBuff, int cb, out int pcb)
    {
        pcb = cb;
        byte[] buffer = new byte[cb];
        Marshal.Copy(pbBuff, buffer, 0, cb);
        dwCookie.Write(buffer, 0, cb);
        return 0;
    }

    private delegate int EditStreamCallback(MemoryStream dwCookie, IntPtr pbBuff, int cb, out int pcb);

    [StructLayout(LayoutKind.Sequential)]
    private struct EDITSTREAM
    {
        public MemoryStream dwCookie;
        public int dwError;
        public EditStreamCallback pfnCallback;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hwnd, uint msg, uint wParam, ref EDITSTREAM lParam);

    private const int WM_USER = 0x0400;
    private const int SF_RTF = 2;
    private const int EM_STREAMOUT = WM_USER + 74;

So when I call GetRTF() with the handle of the Rich Text Control, the return value is:

     {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fprq2\fcharset0 Tahoma;}}{\colortbl ;\red59\green59\blue59;}{\*\generator Riched20 14.0.6015.1000;}{\*\mmathPr\mwrapIndent1440}\viewkind4\uc1\pard\cf1\f0\fs17{\pict\wmetafile0}}

But that's not the text displayed by the Rich Text Control (it's just an e-mail address).

What's the proper way to retrieve the data I'm looking for?


Solution

  • Your code already retrieves all the data. That is the RTF representation of the contents of the control. There's no text because your control doesn't have any text in it. It appears to contain only a metafile vector image.

    If you sent that control a WM_GETTEXT message to obtain plain text, then you'd get back nothing. Because the control doesn't contain text, only an image.