Introduction
As part of a series of recent Internet Explorer updates pushed out by Microsoft, ActiveX controls, including the Flash Player and QuickTime player, have started prompting
the user to click the controls to activate them.
This behavior has suddenly created less attractive web pages, broken existing applications, and caused headaches for web developers. The workaround for this problem has been
clearly documented, but is still a hassle to implement. This article describes a .NET 2.0 control
designed not only to fix the problem, but to make the fix easy to implement.
Background
The way to workaround the issue of getting the activation prompt is simple.
- Create a reference in your HTML file to an external JavaScript file. The JavaScript file should contain a function that will
document.write()
the <object>
tag
and all of the associated HTML code that would ordinarily be put directly in the HTML file.
- Call the JavaScript function from your webpage.
The problem with the above approach is that in order to implement it, you have to write custom JavaScript each time, and writing JavaScript to "document.write()
"
can be a very error prone and time consuming process.
The Server Control
Instead of writing Javascript, another approach is to create a server control to simply wrap your existing HTML code on your website. Below is what your existing HTML
code might look like:
<object id="flash1" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/pub/shockwave/
cabs/flash/swflash.cab#version=8,0,0,0"
width="419" height="320" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="/myFlash.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="/myFlash.swf" quality="high" bgcolor="#ffffff"
width="419" height="320" name="map" align="middle"
allowScriptAccess="sameDomain" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
Below is how your HTML will change with the .NET 2.0 server control:
<form runat="server">
<WH:JsWriter runat="server" >
<object id="flash1" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/pub/
shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
width="419" height="320" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="/myFlash.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="/myFlash.swf" quality="high"
bgcolor="#ffffff" width="419" height="320"
name="map" align="middle" allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</WH:JsWriter>
</form>
The .NET server control takes the literal content and puts it into a JavaScript variable. The Render
method of the server control is written to output JavaScript code.
protected override void Render(HtmlTextWriter output)
{
string[] htmlLines = (this.InnerHtml.Trim()).Split('\n');
string outString = "";
for (int i = 0; i < htmlLines.Length; i++)
{
string currentLine = htmlLines[i].Replace("'",
"\\'").Replace("\r", "");
if (i > 0)
outString += "+";
if (i == htmlLines.Length - 1)
outString += "'" + currentLine + "';\n";
else
outString += "'" + currentLine + "'\n";
}
string varName = "objStr_" + this.UniqueID;
output.Write("<script language="\""javascript\">");
output.Write(Environment.NewLine);
output.Write("var " + varName + " = " + outString);
output.Write(Environment.NewLine);
output.Write("InsertObjectToDocument(document," + varName + ");");
output.Write(Environment.NewLine);
output.Write("</script>");
}
The above code when run creates the output:
<script language="Javascript">
var objStr = ''
+'<object id=\"flash1\" classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" '
+ 'codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/'
+ 'swflash.cab#version=8,0,0,0\" width=\"419\" height=\"320\" align=\"middle\">'
+'<param name=\"allowScriptAccess\" value=\"sameDomain\" />'
+'<param name=\"movie\" value=\"/myFlash.swf\" />'
+'<param name=\"quality\" value=\"high\" />'
+'<param name=\"bgcolor\" value=\"#ffffff\" />'
+'<embed src=\"/myFlash.swf\" quality=\"high\" '
+ 'bgcolor=\"#ffffff\" width=\"419\" height=\"320\" '
+ 'name=\"map\" align=\"middle\" allowScriptAccess=\"sameDomain\" '
+ 'type=\"application/x-shockwave-flash\" '
+ 'pluginspage=\"http://www.macromedia.com/go/getflashplayer\" />'
+'</object>';
InsertObjectToDocument(document,objStr);
</script>
This resulting JavaScript code will output the ActiveX control, without the annoying "Click to activate and use this control" message.
The method InsertObjectToDocument
is defined in a JavaScript file that is embedded into the DLL as explained below.
.NET 2.0 Benefits
This code could have worked in .NET 1.1, however we took advantage of a really cool .NET 2.0 feature that rendered this control non-backwards compatible.
Using the web resource functionality, this control is able to self-contain its own JavaScript functions. This means that you can simply drop the control onto
an ASPX page and not worry about copying over JavaScript files, like you had to in .NET 1.1.
This entry has to be put into AssemblyInfo.cs:
[assembly: WebResource("JavascriptWriters.JavascriptWriters.js", "text/Javascript")]
The following code is put in the class file for the server control, JsWriter.cs:
protected override void OnPreRender(EventArgs e)
{
Page.ClientScript.RegisterClientScriptInclude("jsWritersScript",
Page.ClientScript.GetWebResourceUrl(this.GetType(),
"JavascriptWriters.javascriptWriters.js"));
base.OnPreRender(e);
}
Then inside JavaScriptWriters.js, the supporting JavaScript functions are put in.
Save the FORM Tag!
If you don't want to use your precious form
tag just for this workaround, you can simply omit form runat="server"
and instead just include the following JavaScript function in a JavaScript file that is already included on your webpage.
function InsertObjectToDocument(toDocument, insertObject)
{
toDocument.write(insertObject);
}
Design Time Support
One of the benefits of this control is that it helps preserve design time layout functionality for your object
tag in tools like Dreamweaver and Visual Studio.