locked
Parameter Invalid when inserting images into RTB RRS feed

  • Question

  • Hello~

    I have a relatively simple (Windows Forms) chat application that I use to monitor incoming messages and I have been wanting to insert images preceding the lines based on what kind of message it is. However, I did not want to use the copy/paste method. So I did some searching online and came across the code below which seems to work except that overtime I end up getting an Invalid Parameter Exception. I searched around and found that my gdi objects building up until the application crashes. The function has calls to dispose of the objects. The images I am using are stored in an imagelist which is also used by listview. Other than that, there are no other code related to images or GDI in the project. Any help is greatly appreciated, thanks!

            private string GetRtfImage(Image _image)
            {
                // Used to store the enhanced metafile
                MemoryStream _stream = null;
                // Used to create the metafile and draw the image
                Graphics _graphics = null;
                // The enhanced metafile
                Metafile _metaFile = null;
                // Handle to the device context used to create the metafile
                IntPtr _hdc;
                try
                {
                    StringBuilder _rtf = new StringBuilder();
                    _stream = new MemoryStream();
                    // Get a graphics context from the RichTextBox
                    using (_graphics = this.CreateGraphics())
                    {
                        // Get the device context from the graphics context
    
                        _hdc = _graphics.GetHdc();
                        // Create a new Enhanced Metafile from the device context
                        _metaFile = new Metafile(_stream, _hdc);
                        // Release the device context
                        _graphics.ReleaseHdc(_hdc);
                    }
                    // Get a graphics context from the Enhanced Metafile
                    using (_graphics = Graphics.FromImage(_metaFile))
                    {
                        // Draw the image on the Enhanced Metafile
                        _graphics.DrawImage(_image, new Rectangle(0, 0, _image.Width,
                            _image.Height));
                    }
                    // Get the handle of the Enhanced Metafile
                    IntPtr _hEmf = _metaFile.GetHenhmetafile();
                    // A call to EmfToWmfBits with a null buffer return the size of the
                    // buffer need to store the WMF bits.  Use this to get the buffer
                    // size.
                    uint _bufferSize = GdipEmfToWmfBits(_hEmf, 0, null, MM_ANISOTROPIC,
                        EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
                    // Create an array to hold the bits
                    byte[] _buffer = new byte[_bufferSize];
    
                    // A call to EmfToWmfBits with a valid buffer copies the bits into the
                    // buffer an returns the number of bits in the WMF.  
                    uint _convertedSize = GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer,
                        MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
                    // Append the bits to the RTF string
                    for (int i = 0; i < _buffer.Length; ++i)
                    {
                        _rtf.Append(String.Format("{0:X2}", _buffer[i]));
                    }
                    return _rtf.ToString();
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message, "GetRTFImage");
                    return "";
                }
                finally
                {
                    if (_graphics != null)
                        _graphics.Dispose();
                    if (_metaFile != null)
                        _metaFile.Dispose();
                    if (_stream != null)
                        _stream.Close();
                }
            }
      this.SelectedRtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033" +
           @"{\pict\wmetafile8\picw" + picw +
           @"\pich" + pich +
           @"\picwgoal" + picwgoal +
           @"\pichgoal" + pichgoal + " " + 
           GetRtfImage(img) + @"}";
    ^ This is how the image is insert in my append

    Saturday, December 12, 2020 12:27 PM

All replies

  • I did a quick test by inserting 1000 times the same image in a loop and could not reproduce your problem.

    (otherwise, the usual way to insert images is with IRichEditOle.InsertObject)

    Saturday, December 12, 2020 6:22 PM