Intercept event in HtmlEditor WinForms
I am using HtmlEditor control inside Windows Form.
I got the control from this page:
http://windowsclient.net/articles/htmleditor.aspx
I want to extend the controls to allow the user to paste images from the clipboard. Right now you can insert plain and rich text, but when you try to insert an image, it does nothing.
Basically what I thought was to detect when the user presses Ctrl + V on the editor, checks the clipboard for the images, and if there is an image, paste it manually into the editor.
The problem with this approach is that I cannot get the OnKeyDown or OnKeyPress events of the form to be raised.
I have a KeyPreview property set to true on a form, but still no events are raised.
I also tried to subclass the form and editor (as explained here ) to catch the WM_PASTE message, but it didn't get raised either.
Any ideas on how to achieve this?
Thank you so much
source to share
I spent all day on this problem and finally found a solution. Attempting to listen to the WM_PASTE message does not work because Ctrl-V is preprocessed by the underlying mshtml control. You can listen to OnKeyDown / Up etc. to catch Ctrl-V, but that will not stop the underlying control, continuing its default Paste behavior. My solution is to prevent preprocessing of the Ctrl-V message and then implement my own Paste behavior. To stop the control from PreProcessing the CtrlV message, I had to subclass my control, which is 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);
}
}
Here is my custom method for handling Paste commands, yours can do something similar with image data from the clipboard.
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);
}
}
Hope someone finds this useful and doesn't waste a day like today.
source to share