Hal
Hal

Reputation: 43

Cursor flickers when trying to resize image in RichTextBox

I hope this is a simple question. I do the following:

  1. In VS2010, I create a Windows Form Application
  2. From the Toolbox, drag RichTextBox control to the form
  3. Size the form and RichTextBox control large enough to display a small picture.
  4. Run (start debugging).
  5. Copy a small image from a web browser and paste to richtextbox (using ctrl-v).
  6. Select the image in the richtextbox. A resize frame is displayed with small boxes.

Now when I position the cursor over one of the small resizer boxes, the cursor flickers. I see glimpses of the resize arrow cursor but most the time it displays the I-beam cursor. It does not steadily show the arrow cursors as it does when the a picture is pasted into WordPad and the cursor placed over the one of the small resize boxes. Should resizing a picture in the RichTextBox behave the same as in WordPad? How can I stop the cursor flicker?

Upvotes: 4

Views: 787

Answers (3)

D.Kastier
D.Kastier

Reputation: 3025

With this hack you will be able to resize the image without flickering, and with the correct Arrows Cursors.

How

First you will need to subclass the RichTextBox and override the method WndProc, so when the RichTextBox receives the message to change its Cursor, we will check if the image is select --- well, I don't really known if is an Image, but it is an Object and not Text.

If the Image is selected, we redirect the message to DefWndProc --- which is the Default Window Procedure.

The code:

public class RichTextBoxEx : RichTextBox
{
    private const int WM_SETCURSOR = 0x20;

    protected override void WndProc(ref Message m) 
    {
        if (m.Msg == WM_SETCURSOR) 
        {
            if (SelectionType == RichTextBoxSelectionTypes.Object) 
            {
                DefWndProc(ref m);
                return;
            }
        }

        base.WndProc(ref m);
    }
}

Upvotes: 2

D.Kastier
D.Kastier

Reputation: 3025

It's 2018 and this problem is still happening...

It is not the best, but I create a workaround. I believe that we can improve this code --- maybe in the future I do it myself.


You need to subclass RichTextBox and then add the following to force the Cursor to be what it should be.

Notice that the Cursor is either Cross for Objects like pictures OR I-Beam for texts.


How it works:

  1. Every time that the RichTextBox requests a Cursor change (SetCursor), we intercept it and check if an Object is Selected.

  2. If true, then change the cursor for Cross. If false, then change it to I-Beam.


class RichTextBoxEx : RichTextBox
{
    private const int WM_SETCURSOR = 0x20;

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr SetCursor(IntPtr hCursor);

    protected override void WndProc(ref Message m) {
        if (m.Msg == WM_SETCURSOR) 
        {
            if (SelectionType == RichTextBoxSelectionTypes.Object) 
            {
                // Necessary to avoid recursive calls
                if (Cursor != Cursors.Cross) 
                {
                    Cursor = Cursors.Cross;
                }
            }
            else 
            {
                // Necessary to avoid recursive calls
                if (Cursor != Cursors.IBeam) 
                {
                    Cursor = Cursors.IBeam;
                }
            }

            SetCursor(Cursor.Handle);
            return;
        }

        base.WndProc(ref m);
    }
}

Upvotes: 1

M. Nasir Javaid
M. Nasir Javaid

Reputation: 5990

Use the following property

/// <summary>
/// The Lower property CreateParams is being used to reduce flicker
/// </summary>
protected override CreateParams CreateParams
{
    get
    {
        const int WS_EX_COMPOSITED = 0x02000000;
        var cp = base.CreateParams;
        cp.ExStyle |= WS_EX_COMPOSITED;
        return cp;
    }
}

I have already answered here.

Upvotes: 0

Related Questions