ControlFreak
LANGUAGES:
VB.NET | C#
ASP.NET
VERSIONS: 2.x
Add Flash ... and Flare
Grab Attention with a Custom Flasher Control
By Steve C. Orr
Flash animation is a great way to grab people s attention
among the endless sea of look-alike Web pages on the Internet. It can present
useful information, as well as provide functional interactivity. Embedding
Flash animation within a Web page used to be simple. However, changing
standards such as XHTML and ActiveX Activation have introduced significant
complications. In this article, you ll learn all you need to know to play and
embed Flash animations within ASP.NET Web pages. Indeed, the custom Flasher
control detailed in this article makes Flash animation easy again.
Standards Challenges
Adobe s Web site recommends the HTML syntax shown in
Figure 1 to instantiate their Flash player and display a Flash animation. The
syntax is not pretty, but it works sort of. It certainly used to work well,
but these days it has issues. For one thing, it violates the HTML standard in
several different ways. Browsers tend to be forgiving, so for now it still
mostly works. However, every good Web developer should strive for standards-compliant
code. One of the main reasons it s non-compliant is because the Embed tag is
contained within the Object tag, which is not allowed. However, it works anyway,
but only because Internet Explorer (IE) uses the Object tag and ignores the
internal Embed tag, and Mozilla-based browsers do the opposite.
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/
flash/swflash.cab#version=6,0,40,0"
width="550" height="400"
id="OBJECT1">
<param name="movie"
value="myFlashMovie.swf">
<param name="quality" value="high">
<param name="bgcolor" value="#FFFFFF">
<embed
src="/support/flash/ts/documents/myFlashMovie.swf"
quality="high" bgcolor="#FFFFFF"
width="550" height="400"
name="myMovieName" align=""
type="application/x-shockwave-flash" pluginspage=
"http://www.macromedia.com/go/getflashplayer">
</embed>
</object>
Figure 1: Adobe s Web
site recommends this non-standard HTML to play Flash animations in a Web page.
The sad fact is that there is no single HTML or
XHTML-compliant syntax that will allow a Flash animation to be played across all
browsers. Therefore, Web developers are pretty much forced to output one syntax
for IE users and another syntax for other browser types. That is one messy
detail that s encapsulated by the custom Flasher control included with this
article, so you won t need to worry about it (see end of article for download
details). Essentially, the Flasher control outputs HTML syntax similar to that
shown in Figure 2 for all browsers except IE.
<object
type='application/x-shockwave-flash'
data='anim.swf'
width='550'
height='400'
play='true'
loop='true'
quality='AutoHigh'
/>
Figure 2: This
HTML snippet will play a Flash file in all major browsers except Internet
Explorer.
Conversely, the HTML in Figure 3 shows the syntax that
works for IE. If that HTML is pasted into a Web page and references a valid
Flash animation it will play just fine. However, an annoying message will
appear to the user at run time.
<object
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
width="550"
height="400" id="myMovieName">
<param
name="movie" value="anim.swf">
<param
name="quality" value="high">
<param
name="bgcolor" value="#FFFFFF">
<param
name="loop" value="true">
</object>
Figure 3: This
HTML snippet will play a Flash file in Internet Explorer but ActiveX
Activation will be required by the user upon every page load.
ActiveX Activation
The HTML in Figure 3 worked perfectly in 2005 ah, the
good old days. It turns out that a company named Eolas Technologies apparently
has a patent on it. Microsoft s stunning loss of the related lawsuit has had
major repercussions for Web developers worldwide. Microsoft was forced to
deploy patches for IE that now require the user to click (or press the
spacebar) to activate any embedded software, such as ActiveX controls. Now
users are presented with an annoying activation message for every Web site that
still uses the old syntax (see Figure 4). It should be noted that the same
issue also exists when trying to embed .NET Windows forms controls.
Figure 4: ActiveX Activation is a
burden all Web developers must now deal with so their users don t have to be
annoyed by messages such as this.
To circumvent this problem, the only supported solutions
(at the time of this writing) involve instantiating embedded ActiveX controls from
an external JavaScript file (see http://www.aspnetpro.com/NewsletterArticle/2006/06/asp200606af_l/asp200606af_l.asp
for more information).
In short, if a Web developer wants standards-compliant
code that plays Flash files in all browsers without requiring users to activate
embedded ActiveX controls, there are quite a few hoops to jump through. All
these issues have been addressed and resolved to drag-and-drop simplicity with
the custom Flasher control described here.
Flasher!
To use the cross-browser compatible Flasher control,
download the sample code and add the included Flasher.DLL to your Visual Studio
2005 toolbox. Then drag it onto any WebForm and set its FlashFile property to
any valid SWF file. That s it! Run the project and the Flash animation will
play in all browsers without any of the headaches mentioned previously. Of
course, you can customize it with various properties, such as those shown in
Figure 5.
|
Unique Flasher
Properties
|
Description
|
|
FlashFile
|
(Required) The URL to a Flash (.swf) file.
|
|
Loop
|
(Boolean) True will loop the animation infinitely; False
will stop the animation at its end.
|
|
Menu
|
(Boolean) True to display an extended context (right-click)
menu.
|
|
PlayImmediately
|
(Boolean) True to play the animation instantly upon page
load.
|
|
Quality
|
(Enum) Allows different playback qualities for display
devices of varying capabilities; AutoHigh is the default.
|
Figure 5: The
Flasher control provides several useful properties that allow versatile
configuration.
The ASPX declaration looks like this:
<cc1:Flasher ID="Flasher1" runat="server"
FlashFile="~/anim.swf"
BackColor="red"
Width="550"
Height="400" Loop="false" />
If desired, JavaScript can be added to the page to let the
user or page developer control the animation via client-side code. The
following ASPX page code provides links to let the user start and stop the
playback of the Flash animation:
<div onclick="Flasher1.Play();">Play</div>
<div onclick="Flasher1.Stop();">Stop</div>
So How Does It Work?
Flasher inherits from the System.Web.UI.Control class and
extends it with custom rendering functionality and the properties shown in
Figure 5. The overridden Render method is shown here:
Protected Overrides Sub Render(ByVal w As HtmlTextWriter)
If Me.DesignMode Then
Exit Sub
With
Context.Request.Browser
If
.Browser.ToString.ToUpper = "IE" Then
RenderForIE(w)
Else
RenderForAlt(w)
End If
End With
End Sub
At design time the Render method displays only a
placeholder, as directed by the first line of code. The rest of the code simply
branches to one run-time rendering routine for Internet Explorer users
(RenderForIE) and another rendering routine for all other Web browsers
(RenderForAlt).
The utilitarian RenderForAlt method shown in Figure 6
essentially uses a StringBuilder object to concatenate a string virtually
identical to Figure 2 and renders it to the browser.
Private Sub RenderForAlt(ByVal output As HtmlTextWriter)
Dim sb As StringBuilder
= New StringBuilder
sb.Append("<object
type='application/x-shockwave-flash'")
sb.Append("
data='")
sb.Append(Page.ResolveClientUrl(Me.FlashFile))
sb.Append("'
width='")
sb.Append(Me.Width.ToString)
sb.Append("'
height='")
sb.Append(Me.Height.ToString)
If Not
Me.BackColor.IsEmpty Then
sb.Append("'
bgcolor='")
sb.Append(Color2Hex(Me.BackColor))
End If
sb.Append("'
play='")
sb.Append(Me.PlayImmediately.ToString.ToLower)
sb.Append("'
loop='")
sb.Append(Me.Loop.ToString.ToLower)
sb.Append("'
quality='")
sb.Append(Me.Quality.ToString)
sb.Append("' />")
output.Write(sb.ToString)
End Sub
Figure 6: The
RenderForAlt method takes care of the rendering tasks for all browsers except
Internet Explorer.
This code is simpler than the IE rendering method because
other browsers are not currently subjected to the burden of activation (and the
extra code required to deal with it effectively).
Private Sub RenderForIE(ByVal output As HtmlTextWriter)
Dim sb As StringBuilder
= New StringBuilder
sb.Append("CreateIEFlash('")
sb.Append(Me.ClientID +
"_obj")
sb.Append("','")
sb.Append(Page.ResolveClientUrl(Me.FlashFile))
sb.Append("',")
sb.Append(Me.Width.ToString)
sb.Append(",")
sb.Append(Me.Height.ToString)
sb.Append(",'")
If Not
Me.BackColor.IsEmpty Then
sb.Append(Color2Hex(Me.BackColor))
End If
sb.Append("',")
sb.Append(Me.PlayImmediately.ToString.ToLower)
sb.Append(",")
sb.Append(Me.Loop.ToString.ToLower)
sb.Append(",'")
sb.Append(Me.Quality.ToString)
sb.Append("');")
output.Write("<script
language='JavaScript'>")
output.Write(sb.ToString)
output.Write("</script>")
End Sub
Figure 7: The
Flasher control s Internet Explorer rendering method outputs only a single line
of JavaScript, which calls the CreateIEFlash JavaScript function (shown in
Figure 8).
ASP.NET 2.0 Embedded Web Resources
The RenderForIE method listed in Figure 7 essentially
concatenates together this JavaScript, which is output directly into the page:
CreateIEFlash('Flasher', 'anim.swf',
550,400,'#FFFFFF', true,
true, 'high');
This code calls the custom JavaScript function (named
CreateIEFlash) shown in Figure 8. The CreateIEFlash function essentially uses
the document.write method to dynamically build and output HTML like that shown
in Figure 3. To avoid ActiveX Activation, this function must be located in an
external JavaScript file. Therefore, a reference to the external JavaScript
file must be added to the page, such as this:
<script language="javascript"
src="Flasher.js"></script>
Now, a person could try to remember to add this line to
every page that uses the Flasher control, and a person could try to remember to
deploy that JavaScript file to the proper location in every project that uses
the Flasher control. However, it s far more professional for the control to
take care of these details itself.
// JavaScript File (flasher.js)
function CreateIEFlash(ID, Movie, Width, Height, BGC,
Play, Loop, Qual)
{
var
clsid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
var
codebase="http://download.macromedia.com/pub/";
codebase+="shockwave/cabs/flash/swflash.cab";
codebase+="#version=6,0,40,0";
document.write('<object
classid="' + clsid + '" ');
document.write('codebase="'+ codebase +
'" ');
document.write('width="'+ Width + '"
');
document.write('height="' + Height +
'" ');
document.write('id="'
+ ID + '">');
document.write('<param
name="movie" value="'+ Movie + '"');
document.write('<param
name="quality" value="'+Qual+'">');
if (BGC.length>0)
document.write('<param
name="bgcolor" value="'+ BGC +'>');
document.write('<param
name="loop" value="' + Loop + '">');
document.write('<param
name="play" value="'+ Play +'">');
document.write('</object>');
}
Figure 8: This
external JavaScript function dynamically outputs HTML similar to Figure 3. This
technique avoids ActiveX Activation hassles.
Therefore, the JavaScript file has been compiled into the
control as an embedded resource. To embed a file inside an assembly, simply
drag the file into the project inside Solution Explorer, then set its Build
Action property to Embedded Resource. To access this resource dynamically from
the Web (as is about to be done), the file must also be declared. In this case,
that s done at the top of the class file (before the class declaration) with
this design-time attribute:
<Assembly: _
System.Web.UI.WebResource("ControlFreak.flasher.js",
_
"text/javascript")>
The new WebResource method available in ASP.NET 2.0 makes
it possible for controls to manage their own resources to make deployment and
maintenance easier. Its parameter accepts only the control s namespace
(ControlFreak), followed by a dot and then the filename with extension
(flasher.js). The code in Figure 9 shows how the embedded JavaScript file is
referenced dynamically at run time.
Protected Overrides Sub OnPreRender(ByVal _
e As System.EventArgs)
If Me.DesignMode Then
Exit Sub
With
Context.Request.Browser
If
.Browser.ToString.ToUpper = "IE" Then
' Define the
resource name and type.
Dim rstype As
Type = Me.GetType
Dim rsname As
String = "ControlFreak.flasher.js"
' Register the
client resource with the page.
Dim cs As
ClientScriptManager = Page.ClientScript
cs.RegisterClientScriptResource(rstype, rsname)
End If
End With
End Sub
Figure 9: ASP.NET
2.0 includes the capability for Web controls to manage their own resources,
which can greatly simplify deployment and maintenance.
Using this technique, the control s JavaScript file doesn t
need to be located in the Web application s directory structure at all;
therefore, you can t forget to put it there or accidentally put it in the wrong
place. Instead, it s automatically retrieved from the control at run time. The
RegisterClientScriptResource function makes this happen by building a URL that
references the embedded resource through an automatically managed HTTP Handler.
The resulting HTML script tag looks like this:
<script
src="/FlasherTest/WebResource.axd?d=t0e7oX8lfjsk..."
type="text/javascript"></script>
Fun with Hexadecimals
Adobe s Flash control requires its background color be set
via RGB Hexadecimal values only. Color names are not supported. Therefore, I
patched together a utility function to translate the Flasher control s
BackgroundColor property to just such a Hexadecimal value. This function is
shown in Figure 10. You may have noticed it being called from the RenderForIE
and RenderForAlt methods.
Public Function Color2Hex(ByVal clr As Color) As String
Dim HexR, HexB, HexG As
String
Try
'Get Red Hex
HexR = Hex(clr.R)
If Len(HexR) < 2
Then HexR = "0" & HexR
'Get Green Hex
HexG = Hex(clr.G)
If Len(HexG) < 2
Then HexG = "0" & HexG
'Get Blue Hex
HexB = Hex(clr.B)
If Len(HexB) < 2
Then HexB = "0" & HexB
Catch ex As Exception
Return ""
End Try
Return "#"
& HexR & HexG & HexB 'Output complete hex
End Function
Figure 10: The
Color2Hex function converts a color object into an RGB Hexadecimal value because
that s what Adobe s Flash player requires.
This function extracts the Red, Green, and Blue (RGB) values
from the Color object, then converts them in turn to hexadecimal values. Then
the final line recombines them into a familiar string color value, such as
this:
#FF0099
Wrap Up
Using the ASP.NET 2.0 WebResources techniques (shown here)
and the GetWebResources method (not shown here), you can easily embed scripts,
images, icons, strings, and other items on which a Web control might depend. Web
controls can now control their own dependencies, thereby easing deployment and
maintenance chores (see Figure 11).
Figure 11: The Flasher control plays
Flash animations consistently across all major browsers so you don t have to
worry about development annoyances, such as ActiveX Activation or varying
browser support.
The Flasher control makes playing Flash animations easy
again. Now you can generate standards-compliant output that works in all
browsers, and avoid user annoyances such as ActiveX Activation.
The source code for
the Flasher control is available for download (in both VB and C#).
Steve C. Orr is an
MCSD and a Microsoft MVP in ASP.NET. He s been developing software solutions
for leading companies in the Seattle
area for more than a decade. When he s not busy designing software systems or
writing about them, he can often be found loitering at local user groups and
habitually lurking in the ASP.NET newsgroup. Find out more about him at http://SteveOrr.net
or e-mail him at mailto:Steve@Orr.net.