0

We have an UserControls which herits from the RichTextBox. We would like to forbid the user to enter any image(with copy paste) in this user control.

I found several places where speaking of this:

Currently I've this solution:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == (Keys)Shortcut.CtrlV || keyData == (Keys)Shortcut.ShiftIns)
    {
        if (Clipboard.ContainsImage())
        {
            return false;
        }
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

Which works for copy paste with CTRL+C-CTRL+V, but not with the contextual menu.

EDIT

I tried the given proposition:

public class CustomRichBox : RichTextBox
{
    private const int WM_PASTE = 0x0302;
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_PASTE )
        {
            if (Clipboard.ContainsImage())
            {
                return;
            }
        }
        base.WndProc(ref m);
    }
}

But when I do the CTRL+V, I don't receive this message

Community
  • 1
  • 1
J4N
  • 19,480
  • 39
  • 187
  • 340
  • Not a proper answer, but here are some suggestions on how to do this with unmanaged MFC rich edit controls: https://stackoverflow.com/questions/2250759/how-does-a-cricheditctrl-know-a-paste-operation-has-been-performed and http://stackoverflow.com/questions/2104809/en-protected-and-richedit. Maybe you could try to make use of this somehow? – dbc Apr 02 '15 at 18:47

3 Answers3

0

You could try to override the WndProc method to filter the WM_PASTE message:

protected override void WndProc(ref Message m)
{
    // Trap WM_PASTE with image:
    if (m.Msg == 0x302 && Clipboard.ContainsImage())
    {
        return;
    }
    base.WndProc(ref m);
}

EDIT
Unfortunatly, this approach won't work because the RichTextBox control doesn't send the WM_PAINT message to itself. See also: Detecting if paste event occurred inside a rich text box.

Community
  • 1
  • 1
Dmitry
  • 13,797
  • 6
  • 32
  • 48
  • Well, regarding the link you gave: The first solution doesn't work with the contextual menu. And basing something on the length feels just dirty. I mean we have some model bound on those texts, so if the model change its values and reflects this on the RichTextBox, it will be detected as a paste – J4N Apr 01 '15 at 14:20
0

Sadly there is no global Paste-Event, on which you can subscribe like in WPF. But maybe this is a solution for you:

hook on default "Paste" event of WinForms TextBox control

This worked for me.

Community
  • 1
  • 1
Michi-2142
  • 1,170
  • 3
  • 18
  • 39
  • This should capture Ctrl+V and the Contextual menu -> paste ? Or only the second one? – J4N Apr 01 '15 at 14:21
  • This should work for both. I tried out with success. – Michi-2142 Apr 02 '15 at 08:43
  • It's weird, I copy pasted their code(see my edit) but when I do ctrl+V, it doesn't work. – J4N Apr 02 '15 at 10:51
  • Sorry, you are absolutely right. This only works for TextBox. I tried again and it also doesn't work. Is there any way to choose TextBox instead of RichTextBox? – Michi-2142 Apr 02 '15 at 11:11
0

As a quick workaround, I tried to copy only the Text (using RichTextBox.Text) in another RichTextBox, then copy the Rtf string in the first RichTextBox, all of that in the "TextChanged" event. However there are a lot of downsides for this workaround. First: is not optimized, second and most important: you lose all text formatting, which might be the reason you chose RichTextBox in the first place, and third: you can still see the image for one or two frames in the RTB until it disappears, and if the user is writing a large text it isn't working very smoothly (but fortunately you can fix this if you copy-paste the code in paste events). However, it turned out to be very useful in my app, which is the reason I posted this answer here. So here is all the code (assuming you have a RichTextBox named RTB and an auxiliary RichTextBox named auxRTB):

    private void RTB_TextChanged(object sender, EventArgs e)
    {
        int selStart = RTB.SelectionStart;
        int selLenght = RTB.SelectionLength;
        auxRTB.Text = RTB.Text;
        RTB.TextChanged -= RTB_TextChanged;
        RTB.Rtf = string.Copy(auxRTB.Rtf);
        RTB.TextChanged += RTB_TextChanged;
        try
        {
            RTB.SelectionStart = selStart;
            RTB.SelectionLength = selLenght;
        }
        catch (Exception) { }
    }

Now, if you are interested, here I'm going to explain how is that useful in my app. So I built a command system, and the only reason I chose RichTextBox insted of normal TextBox is because I wanted to give different colors to each type of thing from a command. The commands are not meant to be long so I don't have any optimiziation problems, and I don't care about losing formatting, since I always change the colors automatically.

Edit: by the way, here are some links to the same problem on other sites, which might actually help you:

Link 1: https://social.msdn.microsoft.com/Forums/en-US/0f762cb8-7383-4937-8ee8-f8df5d3a9852/disable-image-paste-in-richtextbox?forum=wpf

Link 2: C# / WPF: Richtextbox: Find all Images

Link 3: https://thomaslevesque.com/2015/09/05/wpf-prevent-the-user-from-pasting-an-image-in-a-richtextbox/

dCake
  • 47
  • 6