2


0

HtmlEditor WinFormsで貼り付けイベントをインターセプトする

Windowsフォーム内でHtmlEditorコントロールを使用しています。

私はこのページからコントロールを得ました:

ユーザーがクリップボードから画像を貼り付けられるようにすることで、コントロール機能を拡張したいと思います。 現在、プレーンテキストとフォーマット済みテキストを貼り付けることができますが、画像を貼り付けようとしても何も実行されません。

基本的に、ユーザーがエディターでCtrl + Vを押したときに検出し、クリップボードの画像を確認し、画像がある場合はエディターに手動で挿入することでした。

このアプローチの問題は、フォームのOnKeyDownまたはOnKeyPressイベントを発生させることができないことです。

フォームでKeyPreviewプロパティをtrueに設定していますが、それでもイベントは発生しません。

また、WM_PASTEメッセージをインターセプトするために、フォームとエディター(http://support.microsoft.com/kb/815775 [こちら]で説明)をサブクラス化しようとしましたが、どちらも発生しません。

これを達成する方法についての任意のアイデア?

どうもありがとう

1 Answer


5


私はこの問題に一日中費やし、最終的に解決策を見つけました。 基になるmshtmlコントロールによってCtrl-Vが前処理されているため、WM_PASTEメッセージをリッスンしようとしても機能しません。 OnKeyDown / UpなどをリッスンしてCtrl-Vをキャッチできますが、これにより、基になるコントロールがデフォルトの貼り付け動作を続行するのを停止することはできません。 私の解決策は、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);
        }

    }

誰かがこれを役立ててくれて、今日のように一日を無駄にしないことを願っています。