Stefan Goßner

Senior Escalation Engineer for SharePoint Products and Technologies

MCMS and the ActiveX activation behavior change in Internet Explorer (last update: December 23rd, 2008)

Microsoft had to modify the behavior of ActiveX controls due to an existing patent from Eolas on this technology. See here for more details on this.

After the change ActiveX controls embedded in the html code of a web page have to be activated manually by a user – e.g. through a click on the ActiveX control. This can be very annoying for users.

At least there is a workaround to prevent the need for an activation when following the coding guidelines outlined in the following document:

The workaround actually requires that the object tag for the ActiveX control has to be placed in an external script file.

This behavior change also affects the ActiveX control included in the MCMS HtmlPlaceholder editor component.

Unlike other ActiveX controls the problem is very small for this ActiveX control as you have to click on this ActiveX control anyway to use it. So clicking on it to activate it should not really be an issue.

Anyway: I have received the question about how to overcome the need to activate the ActiveX control for the HtmlPlaceholder editor component.

The MCMS product team already decided that this behavior will not be changed in a hotfix. So I looked into the details of how MCMS embeds the object tags into the html content and to identify a way to move this code into an external javascript file.

The solution I implemented uses a custom placeholder control derived from the original HtmlPlaceholderControl. This is required to modify the embedding of the object tags.

In addition I had to add an additional ASPX page to my project. This ASPX page is responsible to generate the external javascript code on the fly.

The placeholder control will remove the object tag and replace it with script tags which refer to the additional ASPX page. Using query string parameters to the ASPX the ASPX ensures that the correct javascript code is generated.

Here is the code for the custom placeholder control:

using System;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.WebControls;

namespace StefanG.PlaceholderControls
    // Customer placeholder control to modify the insertion of object tags to comply to 
    // IE behaviour changes
    public class AutoActivateHtmlPlaceholderControl : HtmlPlaceholderControl
        public AutoActivateHtmlPlaceholderControl()
            // empty constructor

        // register a client script blog that modifies the insertion of the object tag for the
        // editor toolbar
        protected override void OnLoad(EventArgs e)
            if (((WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringReedit) 
                ||(WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringNew)))
                string js = “<script language=”javascript” type=”text/javascript” src=””+Page.Request.ApplicationPath+
                string vbs = “<script language=”vbscript” type=”text/vbscript” src=””+Page.Request.ApplicationPath+
                string activeX = “<script language=”Javascript” src=””+Page.Request.ApplicationPath+
                    “<script language=”Javascript”>ActiveX_writeToolbar();</script>”
                Page.RegisterClientScriptBlock(“ActiveXToolbarAndEditorSupportScript”, js+“n”+vbs+“n”+activeX);

        // in the Render method we consume the generated html content from the base class
        // then we remove the object tag using a regular expression and replace it 
        // with a script tag that get’s it content from the external 
        // CreateIEBehaviorChangeJavascript.ASPX page which 
        // generates the javascript code on the fly.
        protected override void Render(System.Web.UI.HtmlTextWriter output)
            if (((WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringReedit) 
                ||(WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringNew)))
                // in authoring mode catch the output of the original HtmlPlaceholderControl
                TextWriter tempWriter = new StringWriter();
                base.Render(new System.Web.UI.HtmlTextWriter(tempWriter));
                string orightml= tempWriter.ToString();

                // modify the html content
                string strRegExp = “<object[^\0]*</object>”;
                Regex r = new Regex( strRegExp, RegexOptions.IgnoreCase | RegexOptions.Compiled );
                string newhtml = r.Replace( orightml, 
                    “<script language=”Javascript” src=””+Page.Request.ApplicationPath+
                    “<script lang=’javascript’>ActiveX_placeholder_”+this.BoundPlaceholder.Name+“();</script>” );

                // return the modified html content
                // not in authoring mode. Call the base render method.


Ok, so far so good. The custom placeholder control will now ensure that no object tag is generated in the html content and that an external javascript file generated by the CreateIEBehaviorChangeJavascript.ASPX javascript file which needs to be located in the root of the web application.

To create this ASP.NET webform please add a regular ASP.NET webform at the root of your template project (same level as the web.config file) and name it CreateIEBehaviorChangeJavascript.aspx.

In your solution you can also move this page to a different folder or give it a different name. But you need to ensure that the path in the placeholder control correctly points to this file.

Now double click somewhere on the new webform to get to the code behind file and add the following method:

protected override void Render( HtmlTextWriter writer)

    if (Request.QueryString[“script”] == “Toolbar”
        // here we emit the object tag for the ActiveX Toolbar
        writer.Write(“n// IE Behavior Change adaption by Stefan Goßnern”+
            “function ActiveX_writeToolbar()n”+
            “document.writeln(‘<OBJECT ID=”ToolbarInterface” “+
               “CLASSID=”CLSID:E99D3E39-5D92-4360-BA86-2C563B3CFFEB” \n’);n”
               “/CMS/WebAuthor/Client/PlaceholderControlSupport/” “+
               “WIDTH=0 HEIGHT=0>\n’);n”
            “document.writeln(‘<PARAM NAME=”BaseUrl” VALUE=””+Page.Request.ApplicationPath+
    else if (Request.QueryString[“script”] == “Placeholder”)
        // we need to retrieve the original placeholder content to fill the placeholder control
        string EncodedHtmlContent = “”;
        Posting p = CmsHttpContext.Current.Posting;
        if (p != null)
            HtmlPlaceholder htmlPh = (p.Placeholders[HttpUtility.UrlDecode(Request.QueryString[“PhName”])] as HtmlPlaceholder);
            if (htmlPh != null)
                EncodedHtmlContent = HttpUtility.HtmlEncode(htmlPh.Html);

        // here we emit the object tag for the ActiveX Editor Component
        writer.Write(“n// IE Behavior Change adaption by Stefan Goßnern”+
            “function ActiveX_placeholder_”+Request.QueryString[“PhName”]+“()n”+
            “document.writeln(‘<OBJECT CODEBASE=””+Page.Request.ApplicationPath+
               “” CLASSID=”CLSID:B33422AC-C567-4F7D-BB28-6583371EC4EE” width=””+
               Request.QueryString[“Width”]+“” height=””+Request.QueryString[“Height”]+“”>’);n”+
            “document.writeln(‘<PARAM NAME=”PostUrl” VALUE=””+Page.Request.ApplicationPath+
            “document.writeln(‘   <PARAM NAME=”HTML” VALUE=””+
                EncodedHtmlContent.Replace(“n”,” “).Replace(“r”,” “).Replace(“‘”,”&#039;”)+“”> ‘);n”+
            “document.writeln(‘   <PARAM NAME=”CodePage” VALUE=””+
                HttpContext.Current.Response.ContentEncoding.CodePage+“”> ‘);n”+
            “document.writeln(‘   <PARAM NAME=”Charset” VALUE=””+
                HttpContext.Current.Response.ContentEncoding.WebName+“”> ‘);n”+

Now you have to replace all HtmlPlaceholderControls in your project with the AutoActivateHtmlPlaceholderControl. Also be aware that if you have custom placeholder controls in place which are also derived from the original HtmlPlaceholderControl now need to be derived from the AutoActivateHtmlPlaceholderControl to ensure that they are automatically activated.

Update: the sample code can now be downloaded from MSDN Code Gallery.