Question

I am trying to disable the automatic URL detection feature of the rich text editor control of Internet Explorer in an embedded Windows Forms WebBrowser control. This is doable in JavaScript since IE9, but my ebedded control has to use IE7 at the moment.

I found that there is a native command in the MSHTML control that does this: http://msdn.microsoft.com/en-us/library/aa769893%28VS.85%29.aspx

Is it possible to somehow call this command from C# on a Forms WebBrowser control? I've found a couple of code samples doing something similar using the IOleCommandTarget interface, but I couldn't get any of them to work.

It would be greate if someone with experience in this could provide a sample code showing how to do this (if the above method is possible at all, of course :))

Was it helpful?

Solution

You need to execute CGID_MSHTML/IDM_AUTOURLDETECT_MODE. Refer to "HOW TO: Invoke the Find, View Source, and Options Dialog Boxes for the WebBrowser Control from Visual C# .NET" for a definition and sample use IOleCommandTarget. In your case (untested):

var CGID_MSHTML = new Guid("de4ba900-59ca-11cf-9592-444553540000");
var IDM_AUTOURLDETECT_MODE = (uint)2400;
var commandTarget = (IOleCommandTarget)webBrowser.Document.DomDocument;
var arg1 = (object)false;
var arg2 = new Object();
commandTarget.Exec(
    ref CGID_MSHTML, IDM_AUTOURLDETECT_MODE, 0, ref arg1, ref arg2);

OTHER TIPS

I managed to achieve this using the code in Noseratio's answer. Here I provide a bit more detail.

I am using a CKEditor rich text editor inside a WPF app inside a Windows Forms WebBrowser control. First I tried to execute the IDM_AUTOURLDETECT_MODE command in the handler for the DocumentCompleted event, and it did not work.

The CKEditor has an instanceReady event in JavaScript, so I tried to call back from JS in that event handler to C# and execute the IDM_AUTOURLDETECT_MODE command then, and this way it worked properly.

So it seems that th IDM_AUTOURLDETECT_MODE command has to be executed after the rich editor control in the page has already been instantiated and ready.

Here are the relevant pieces of code.
Creating the WebBrowser control:

webBrowser = new WebBrowser
{
    ObjectForScripting = com = new MyScriptCommunicationObject()
};

The ScriptCommunicationObject is passed in order to be able to call back from JS to C#.

Calling back in the instanceReady event handler of CKEditor:

CKEDITOR.on('instanceReady', function (e) {
    // Call back to C#, that the editor is ready.
    window.external.CKEditorReady();
});

I guess a similar event can be used with other rich text editors as well.

The event handler in C#, that runs the command (© Noseratio :)):

public void CKEditorReady()
{
    var CGID_MSHTML = new Guid("de4ba900-59ca-11cf-9592-444553540000");
    var IDM_AUTOURLDETECT_MODE = (uint)2400;
    var commandTarget = (IOleCommandTarget)webBrowser.Document.DomDocument;
    var arg1 = (object)false;
    var arg2 = new Object();
    commandTarget.Exec(ref CGID_MSHTML, IDM_AUTOURLDETECT_MODE, 0, ref arg1, ref arg2);
}

And the above code needs the COM IOleCommandTarget interface definition (taken from here: http://support.microsoft.com/kb/329014):

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct OLECMDTEXT
{
    public uint cmdtextf;
    public uint cwActual;
    public uint cwBuf;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
    public char rgwz;
}

[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
    public uint cmdID;
    public uint cmdf;
}

// Interop definition for IOleCommandTarget. 
[ComImport,
Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
    void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] OLECMD[] prgCmds, ref OLECMDTEXT CmdText);
    void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top