c# - 在 HtmlEditor WinForms 上拦截粘贴事件

标签 c# winforms events subclass

我在 Windows 窗体中使用 HtmlEditor 控件。

我从这个页面获得了控件:

http://windowsclient.net/articles/htmleditor.aspx

我想通过允许用户从剪贴板粘贴图像来扩展控件功能。现在,您可以粘贴纯文本和格式化文本,但是当尝试粘贴图像时,它不会执行任何操作。

基本上我的想法是检测用户何时在编辑器上按 Ctrl+V,检查剪贴板中是否有图像,如果有图像,则将其手动插入到编辑器中。

这种方法的问题是我无法引发表单的 OnKeyDown 或 OnKeyPress 事件。

我已将表单上的 KeyPreview 属性设置为 true,但仍然没有引发事件。

我还尝试对表单和编辑器进行子类化(如 here 所述)以拦截 WM_PASTE 消息,但它也没有引发。

关于如何实现这一目标有什么想法吗?

非常感谢

最佳答案

我花了一整天的时间来解决这个问题,终于找到了解决方案。尝试监听 WM_PASTE 消息不起作用,因为 Ctrl-V 正在由底层 mshtml 控件进行预处理。您可以监听 OnKeyDown/Up 等来捕获 Ctrl-V,但这不会阻止底层 Control 继续其默认的粘贴行为。我的解决方案是阻止 Ctrl-V 消息的预处理,然后实现我自己的粘贴行为。为了阻止控件预处理 CtrlV 消息,我必须对 AxWebBrowser 控件进行子类化,

public class DisabledPasteWebBrowser : AxWebBrowser
{
    const int WM_KEYDOWN = 0x100;
    const int CTRL_WPARAM = 0x11;
    const int VKEY_WPARAM = 0x56;

    Message prevMsg;
    public override bool PreProcessMessage(ref Message msg)
    {
        if (prevMsg.Msg == WM_KEYDOWN && prevMsg.WParam == new IntPtr(CTRL_WPARAM) && msg.Msg == WM_KEYDOWN && msg.WParam == new IntPtr(VKEY_WPARAM))
        {
            // Do not let this Control process Ctrl-V, we'll do it manually.
            HtmlEditorControl parentControl = this.Parent as HtmlEditorControl;
            if (parentControl != null)
            {
                parentControl.ExecuteCommandDocument("Paste");
            }
            return true;
        }
        prevMsg = msg;
        return base.PreProcessMessage(ref msg);
    }
}

这是我处理粘贴命令的自定义方法,您的方法可能会对剪贴板中的图像数据执行类似的操作。

    internal void ExecuteCommandDocument(string command, bool prompt)
    {
        try
        {
            // ensure command is a valid command and then enabled for the selection
            if (document.queryCommandSupported(command))
            {
                if (command == HTML_COMMAND_TEXT_PASTE && Clipboard.ContainsImage())
                {
                    // Save image to user temp dir
                    String imagePath = Path.GetTempPath() + "\\" + Path.GetRandomFileName() + ".jpg";
                    Clipboard.GetImage().Save(imagePath, System.Drawing.Imaging.ImageFormat.Jpeg);
                    // Insert image href in to html with temp path
                    Uri uri = null;
                    Uri.TryCreate(imagePath, UriKind.Absolute, out uri);
                    document.execCommand(HTML_COMMAND_INSERT_IMAGE, false, uri.ToString());
                    // Update pasted id
                    Guid elementId = Guid.NewGuid();
                    GetFirstControl().id = elementId.ToString();
                    // Fire event that image saved to any interested listeners who might want to save it elsewhere as well
                    if (OnImageInserted != null)
                    {
                        OnImageInserted(this, new ImageInsertEventArgs { HrefUrl = uri.ToString(), TempPath = imagePath, HtmlElementId = elementId.ToString() });
                    }
                }
                else
                {
                    // execute the given command
                    document.execCommand(command, prompt, null);
                }
            }
        }
        catch (Exception ex)
        {
            // Unknown error so inform user
            throw new HtmlEditorException("Unknown MSHTML Error.", command, ex);
        }

    }

希望有人觉得这很有帮助,并且不会像我今天一样在上面浪费一天的时间。

关于c# - 在 HtmlEditor WinForms 上拦截粘贴事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2611350/

相关文章:

c# - 为什么这个差距会出现在我的 ListView 中?

c# - 如何在系统托盘中找到图标的位置

javascript - jQuery:覆盖单个元素的标记事件

c# - 如何实现可以取消的事件?

javascript - 在 JS 中使用 "transform: translate"只能使用一次

c# - 小 cucumber 功能无法将任何方法与步骤匹配

c# - 删除按钮的文本轮廓

c# - 如何读取共享驱动器上的文件夹文件?

c# - 使用 Ninject 进行类型激活

c# - 在使用 NUnit 对 Controller Action 方法进行单元测试时遇到困难