开发者

Detect any image on clipboard

Right now I want to prevent the user from pasting into a rich text box any content with开发者_Go百科 an image of any type. Clipboard.ContainsImage won't work as it only detects some types and it won't be detected if the clipboard contains text with the image.

What I need is a way to detect an image inside a text, an image alone, multiple images... inside the clipboard to be able to clear the clipboard if this happens. I need to avoid this heavy content to reach the database...

Thanks


The problem is greater than simply preventing an image, since RTF can embed any object including word documents or arbitrary binary data.

The only 3 options I can think of

  1. Limit the maximum data size you allow saving to the database, at which point images under that size arn't a problem since its with in the allowable size.

  2. Use library that will let you parse and understand the RTF content so you can check it for anything other than standard text and formatting. Then you can strip out any embedded binary objects. Alternatively, you could handle WM_PASTE and check the clipboard for RTF text. If it has RTF text you can parse this and strip embedded objects when pasting rather than when saving. If it doesn't have an RTF version, don't forget to check if it has a plain text version instead.

  3. Intercept and handle the WM_PASTE message and use RichTextBox.Paste(DateFormats) to control which data types can be pasted. You can then limit this to only pasting the plain text version of the data on the clipboard, which cannot contain embedded objects. The disadvantage here is the user can't paste formatted text from a different application, all formatting will be lost.

1 is the simplest, but accepts that users will be able to embed small images and other small objects such as word documents or videos, so long as it is under the maximum size.

2 is more complex but offers the best user experience.

3 is simpler than 2, but offers a poor user experience, as if you didn't care about formatted text you wouldn't be using a rich text box. Unless you only want plain text and are using for its larger text capacity, but if this were the case you'd only be fetching the plain text version to save to the DB, which wouldn't contain images.


What does the following show?

 IDataObject clipData = Clipboard.GetDataObject();
 var formats = clipData.GetFormats();

I would expect it to include something like DeviceIndependentBitmap as one of the available formats, so perhaps you can look for that and clear the disable the paste such cases.

Alternatively, what do you get if you peek at the clipboard and just look for text? eg

 IDataObject clipData = Clipboard.GetDataObject();
... clipData.GetData(System.Windows.Forms.DataFormats.Text); 

I know for ordinary images this will be null and if this is true for your mixed mode case, perhaps you can clear the clipboard in that case.


This simple console application will show you what data types have you in clipboard:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms; // reference is added manually.

namespace ctt // Clipboard Types Tester
{
    class Program
    {
        [STAThread] // it is important! Without this Clipboard.GetDataObject() returns null. 
        static void Main()
        {
            // 'formatsAll' is from http://www.radsoftware.com.au/articles/clipboardmonitor.aspx
            string[] formatsAll = new string[] 
            {
                DataFormats.Bitmap,
                DataFormats.CommaSeparatedValue,
                DataFormats.Dib,
                DataFormats.Dif,
                DataFormats.EnhancedMetafile,
                DataFormats.FileDrop,
                DataFormats.Html,
                DataFormats.Locale,
                DataFormats.MetafilePict,
                DataFormats.OemText,
                DataFormats.Palette,
                DataFormats.PenData,
                DataFormats.Riff,
                DataFormats.Rtf,
                DataFormats.Serializable,
                DataFormats.StringFormat,
                DataFormats.SymbolicLink,
                DataFormats.Text,
                DataFormats.Tiff,
                DataFormats.UnicodeText,
                DataFormats.WaveAudio
            };

            IDataObject data = Clipboard.GetDataObject();

            if (data == null)
                System.Console.WriteLine("Error!");
            else
            {
                bool empty = true;
                foreach (string format in formatsAll)
                    if (data.GetDataPresent(format))
                    {
                        empty = false;
                        break;
                    }

                if (empty) System.Console.WriteLine("Now clipboard is empty.");
                else
                {
                    System.Console.WriteLine("Now clipboard contains the following types:");
                    System.Console.WriteLine();
                    foreach (string format in formatsAll)
                        if (data.GetDataPresent(format))
                            System.Console.WriteLine(format);
                }
            }

            System.Console.ReadKey();
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜