G
G
Gepard_vvk2014-04-25 10:21:28
.NET
Gepard_vvk, 2014-04-25 10:21:28

How can I speed up custom rendering in WinForms?

I am working on a WinForms application in which I need to implement spell checking.
To redraw the form, I use the Windows message interception.

/// <summary>
        /// Processes Windows messages.
        /// </summary>
        /// <param name="msg">
        /// A Windows Message object.
        /// </param>
        protected override void WndProc(ref Message msg)
        {
            switch (msg.Msg)
            {
                case WM_PAINT:
                    Invalidate();
                    base.WndProc(ref msg);

                    if (IsSpellingAutoEnabled)
                    {
                        CustomPaint();
                    }

                    break;

            ...

                default:
                    base.WndProc(ref msg);
                    break;
            }
        }

The CustomPaint() method looks like this:
private void CustomPaint()
        {
            Bitmap tempBitmap;
            Graphics bufferGraphics;

            tempBitmap = new Bitmap(Width, Height);
            bufferGraphics = Graphics.FromImage(tempBitmap);
            bufferGraphics.Clip = new Region(ClientRectangle);

            _textBoxGraphics = CreateGraphics();
            bufferGraphics.Clear(Color.Transparent);

            foreach (var wordStartIndex in UnderlinedSections.Keys)
            {
                UnderlineWords(wordStartIndex, bufferGraphics);
            }

            _textBoxGraphics.DrawImageUnscaled(tempBitmap, 0, 0);
        }

In UnderlineWords, lines are added to the clipboard to be drawn with help. this method:
private void DrawWave(Graphics bufferGraphics, Point startOfLine, Point endOfLine)
        {
            startOfLine.Y--;
            endOfLine.Y--;

            // kvv: Определяем цвет линий подчеркивания.
            var pen = Pens.Red;

            if ((endOfLine.X - startOfLine.X) >= 4)
            {
                var points = new ArrayList();
                for (int i = startOfLine.X; i <= (endOfLine.X - 2); i += 4)
                {
                    points.Add(new Point(i, startOfLine.Y));
                    points.Add(new Point(i + 2, startOfLine.Y + 2));
                }

                var p = (Point[])points.ToArray(typeof(Point));
                bufferGraphics.DrawLines(pen, p);
            }
        }

When this code is running on text larger than 500 characters, strong brakes and application freezes begin. How can you get rid of this? In which direction to dig?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
aush, 2014-04-25
@aush

You don't have to do that. You have a lot of logic to draw, of course, it will be wildly slow to work.
Take a standard RichTextBox and do something like this:

richTextBox1.Text = "blah blah meeh";
richTextBox1.SelectionStart = 5;
richTextBox1.SelectionLength = 4;
richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Underline);
// еще варианты:
//richTextBox1.SelectionColor = Color.Red;
//richTextBox1.SelectionBackColor = Color.Yellow;
//повторить для все слов с ошибками

If it is critical that the display be standard (red waveline under black text), then expand the RichTextBox: geekswithblogs.net/pvidler/archive/2003/10/15/188.aspx

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question