The EnterPage 12-03
September 22, 2009

In this issue:

Learning & Mastering ToolBook 10 Now Available

Plug-In Pro 8 Adds Image Tools and Supports ToolBook 10

ToolBook 10 Review

ToolBook 10 Pricing Information

TBCON 2009 Report

"Programming for e-Learning Developers" Book Shipping

Plug-In Pro Spotlight - Import/Export Resources

Expert Information from the Learning & Mastering ToolBook Series

OpenScript Tip from the Learning & Mastering ToolBook Series

Web Hint from the Learning & Mastering ToolBook Series

Flash ActionScript Tip

VBTrain.Net Nugget



Introduction

Things are hopping here as usual. We got the Programming for e-Learning Developers book back from the printers, had a successful TBCON, and then have been hunkering down updating products in preparation for the release of ToolBook 10. We give you all the info on these events and products as usual along with ToolBook, Flash, and Silverlight tips. Enjoy!



Learning & Mastering ToolBook 10 Now Available

We have completely updated this popular training application for ToolBook 10. We have added new content on the Quiz Summary, the new Image object, controlling Voice Recordings, importing PowerPoint audio and speaker notes, and much more. Learning & Mastering ToolBook Instructor contains over 30 hours of training with:
  • 80 Show Me Demonstrations
  • 61 Let Me Try simulations
  • 415 Expert Information topics
  • 161 Web Hints
  • 173 OpenScript Tips
Learning & Mastering ToolBook 10 also includes extensive content on SmartPages/SmartStyles, Actions Editor, OpenScript, Certificates, XML, Flash, HTTP Post, ADO, Automation, Simulations, and more. Pricing remains at $595. You can upgrade from version 9.5 for $195 or from 9.0 or older for $385. It is available now from Platte Canyon and will be available from SumTotal Systems in the near future.

Information

Purchase

Plug-In Pro 8 Adds Image Tools and Supports ToolBook 10

We are excited to announce that Plug-In Pro 8 is available. Rather than targeting multiple versions of ToolBook as we have done in past Plug-In Pro releases, Plug-In Pro 8 supports only ToolBook 10 and adds great new tools that add to the already formidable capabilities of TB 10.

Plug-In Pro 8 adds the ability to import and export PNG, GIF, JPG, BMP, WMF, and EMF files. You can choose to import or export only particular image types. For example, you might want to replace all your BMP resources with .PNG equivalents. You can use the Plug-In Pro to export only the BMP format bitmap resources to external files. Then overwrite them with .PNG equivalents and the use the Plug-In Pro to replace all those resources with the PNG ones. You can also find which objects are using particular resources, again by image type. Version 8 also has great new tools to create image objects (new to ToolBook 10) and populate them with external graphic files (which are in turn imported as resources). You can put all the images on one page or put each one on its own page. If you still want to use the Web Graphic Placeholder, you can do the same thing with it. The Plug-In Pro also has the ability to copy actions between objects (even from different books!), merge pages to different backgrounds, a tool to save and restore your Command Window scripts, a tool for listing all the web graphics and adjusting their external files if desired, a tool to find all your media players and list/adjust their media, the ability to import clips and see all your clip information, the ability to write your sticky notes to a file, the addition of simulation information such as Instructions and Feedback to the generated spell-check file, and much more!

The Plug-In Pro is $495 per developer. Owners of version 7 can upgrade for $165. Owners of version 6 or older can upgrade for $330.

Information

Purchase


ToolBook 10 Review

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

I have been using ToolBook 10 since the first preview release. It has been quite stable from the beginning and has a number of highly-worthwhile features. These include:
  • Quiz Summary
  • Speaker Notes/Audio/Bullets Imported from PowerPoint
  • JPG, GIF, WMF, EMF (as well as PNG and BMP) Graphic Support
  • Image Object
  • Commonly Used Objects" Catalog Category
  • Google Android Support
  • Nice Curved Lines for DHTML Matching Question
  • Control Voice Recordings
  • "Scrolling Borderless" Field
  • Change Bullet Graphics for Graphic List Object

The Quiz Summary object allows you to show a list (or a subset of just correct and/or incorrect) questions in your book. There is configurable set of data that can include the question text, the correct answer, the student's answer, and more. You can include a link back to the question page for reviewing the question or trying it again. To support getting their hands on the question text, all question objects can be configured to either find the most likely field holding the text, use some literal text, use the name of the question, or use a field that you define. We've had to come up with custom "question text" solutions for our TBK Tracker and Progress Tracker products over the years. It is great to get it built into ToolBook. Check out the Expert Information topic below for some information as to how the Quiz Summary is implemented and the OpenScript Tip on how its companion Print Quiz Summary button is implemented in native mode.

Those of you importing content from PowerPoint will be pleased to know that embedded audio is now included. It is implemented as a hidden Universal Media Player on the page. Speaker Notes are added to a new Notes tab on the Properties for Page dialog. You can use this Notes feature to communicate with other members of the development team (similar to our Sticky Notes in the Plug-In Pro) even if you are not using PowerPoint.

Probably my favorite feature is the native support for virtually all graphic types, including JPG, GIF, WMF, and EMF (adding to previous support of PNG and BMP). Along with this is the new Image object. It is similar to a Button but with only normal graphic and disabled graphic states. Paint Object and Picture objects no longer have an interface (inserting a graphic creates an Image along with a bitmap resource) but can still be created via OpenScript. As the "preferred" way of working with graphics, the Image object has been added to the new Commonly Used Objects category of the Catalog. The "Web Graphic Placeholder" and "Reusable Graphics Placeholder" objects are still available but have been relegated to a "Legacy Objects" category in the Catalog.

When you export to DHTML, you can now choose Google Android, along with various Internet Explorer, Firefox, and Safari versions. And if you have matching objects, you'll be very impressed with their curved lines and color gradients. No more boxy, jagged lines! Tim Barham showed me the HTML behind these lines this summer at TBCON one evening. The fact that Internet Explorer and Firefox needed different implementations makes the result even more impressive.

Controlling Voice Recordings is now very easy. Best of all is that all the OpenScript and Actions Editor code you already have appears to work flawlessly. As you have probably concluded on your own by now, this is a "must have" release.

Platte Canyon ToolBook Instructor Information

ToolBook 10 User Guide

ToolBook Web Site



ToolBook 10 Pricing Information

ToolBook 10 is now shipping. If you currently have a support or maintenance contract, you'll receive an email from SumTotal Systems with download instructions. If not and your support or maintenance expired on August 15th or later, you can still get TB 10 by renewing by September 29th.

The upgrade price from Instructor 9.5 to 10 is $1,595. If you are starting up your ToolBook shop, you can take advantage of the ToolBook 2 User Starter Pack: Through October 15th, 2009 - Purchase ToolBook with Support and Maintenance and get the second license for 50% off list price* (a savings of over $1,300). We also have a great price for a single license of ToolBook.

If you are on an older version of Instructor, it is important to understand that SumTotal is no longer offering upgrades for customers more than one version back. So once ToolBook gets to the next version (10.5 or 11), users of 9.5 or older versions will have to pay full price to get to the current version.

If you are in the U.S. or Canada, you can buy ToolBook itself, support, and/or maintenance from Platte Canyon. There is a link below for our online store. Or you can call us at 888-866-5251 (888-ToolBk1) or 719-548-1110. Otherwise, contact your local reseller or SumTotal directly.

Platte Canyon ToolBook Store



TBCON 2009 Report

The eleventh year of The ToolBook User's Conference and the fourth year of The e-Learning Authoring Conference (August 3 - 5, 2009) was down in attendance but not in energy. Developers from across the country as well as Germany and Australia previewed ToolBook 10, learned how to create animations and much more in Flash, understood Programming for e-Learning Developers in ToolBook, Flash, JavaScript, and Silverlight, saw demonstrations on importing content from PowerPoint, picked up some management tips, met fellow members of the ToolBook List, and much more.

Congratulations to these SumTotal Systems ToolBook Design award winners:
  • Material Master for Buyers/Planners - Iris Peceny, Goodrich
  • eTrade Tutorial - Dan Richards, IAC
  • Good Manufacturing Practices - Margie Grande, Malt-O-Meal


The "Hack Ack" topic this year was Board Games. Stephanie Hicks won a close vote with her nice Monopoly game. Don Bair and Mike Dickinson had their own cool take on Monopoly. Lee Jay Karns and Mauro Rech grilled some of the faculty members with funny "Clue" questions with Denny Dedmore and Sheri Miller coming out the winners. James Leavelle started the night out with a great story incorporating Aggravation, Sorry, and other games. Thanks goes to Bill Hurley (right) for starting the fun out with "Mentos and Diet Coke" as well as being "MC" of the Hack Ack.

Be sure to mark your calendars for TBCON 2010: June 14 - 16, 2010 with preconference training June 12 and 13.

TBCON 2009 Resources

TBCON 2009 Archives for Attendees Application ($50)



"Programming for e-Learning Developers" Book Shipping

Many of you have already bought this new 358-page book by Jeff Rhodes which covers the gamut of e-Learning programming tasks in ToolBook (OpenScript and Actions Editor), Flash, JavaScript, and Silverlight. Here is the description from the back cover:

As an e-Learning developer since 1993, I have found that even a little programming can go a long way in terms of increasing our ability to create meaningful interactions for our users. To do that, however, entails understanding basic programming concepts like events, properties, and methods. Add to that the requirement to perform more advanced tasks like adding hyperlinks, communicating via SCORM with your Learning Management System, loading media or graphics, and using a web service to send email from your application, and you have the need for some "real" programming. Rather than hiring a pricey consultant, however, you can use this book to learn the concepts to get the job done. The complete sample applications used in the book (including source code) are available for download for those who purchase the book.

Many e-Learning developers use multiple tools. Even if you stick to a single tool like Flash or ToolBook, you still likely have the need to make external JavaScript calls in order to get extra functionality. So rather than focus on a single tool, this book takes each of our programming challenges and solves it in ToolBook - OpenScript, ToolBook - Actions Editor, Flash, JavaScript, and Silverlight. Even if you don't use all these environments currently, seeing the similarly of programming concepts across all the environments will enhance your skills in your tool(s) of choice.

The book is $45 and is shipping now. Postage is $4 within the U.S. and $15 to the rest of the world. You can order using the link below. You can also order at online bookstores but you can get it signed if you go through Platte Canyon:)

Information

Table of Contents

Sample Chapter

Reader Comments

Order

Plug-In Pro Spotlight - Import/Export Resources 

These are two of the earliest and most useful tools in the Plug-In Pro. The idea is that you can put a bunch of graphics in a directory and import them all at once rather than painstakingly doing it one-by-one in Resource Manager. Or you can export resources contained within a book to external files, edit the files as needed, and then import them again -- all the while keeping chromakey and other settings in place. With Plug-In Pro 8, we've added the ability to do this import and export for each of the file types (PNG, JPG, PNG, BMP, WMF, and EMF) supported by ToolBook 10. This is particularly helpful if you want to swap out your existing BMP resources for ones in, say, PNG format. You can choose to only export the resources that are in BMP format. You can then use PhotoShop or another tool to convert them to PNG images of the same name, and then import them all back to into your book. The time-savings on this for one book alone is worth the price of the product.

To learn more, you can follow these links.

Importing Resources help topic

Exporting Resources help topic

Plug-In Pro web page

Expert Information from the Learning & Mastering ToolBook Series 

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Loading Quiz Summary Data into the Web Browser Control

The Quiz Summary control uses the Microsoft Web Browser ActiveX control in native ToolBook. The way that the SumTotal team loads data into this control is quite elegant.

The first step is to create a temporary HTML page. On my machine, this file has a path like this:

C:\Users\Jeff\AppData\Local\Temp\qsD98F.html
If you open this file in a browser, you can view its source but you cannot see any data. That is because the data is loaded dynamically from OpenScript. To see this, you can first look at the HTML body tags as shown below.

<body onkeydown='handleKeyDown()' onload='pageLoaded()' style='background-color:#ebf2fa;padding:0px;margin:0px;border:0px #ffffff none;overflow:auto>

In response to the onload event, the JavaScript "pageLoaded" function is called. Here is that function.

function pageLoaded()
{
	notifyToolBook( "PageLoaded" );
}

It in turn calls the JavaScript "notifyToolBook" function, which is shown below:

function notifyToolBook( command )
{
	window.status = "ToolBook:" + command;
	window.status = "";
}

This function sets the status of the window object to "TookBook:PageLoaded" in this case. This would normally just show that value in the control's status bar. However, the authors use this as the communication method between the browser control and ToolBook by handling the extStatusChange event as shown below.

-- OpenScript in the shared script of the Web Browser control
to handle extStatusTextChange txt
	if offset ( "ToolBook:", txt ) = 1
		clear chars 1 to 9 of txt
		conditions
		when txt = "PageLoaded"
			send pageLoaded target
		-- other items omitted
		end
	end
end

So this code calls the pageLoaded OpenScript function, shown below.

to handle pageLoaded browserRef
	local qnData[][]

	-- Collect the Raw Summary Data
	get quizSummaryData( qnData )
	_qnData() = qnData

	qnDataTypes = "QuestionName,QuestionType, StudentScore,Attempts, 
		Time,StudentAnswer, QuestionText,CorrectAnswer, Result,Review"
	qnDataTypeCount = itemCount( qnDataTypes )

	qnCount = item 1 of dimensions( qnData )
	step qnNum from 1 to qnCount
		val = "{ "
		step i from 1 to qnDataTypeCount
			qnDataType = item i of qnDataTypes
			qnDataValue = getText( qnDataType, qnNum, qnData )
			qnDataValue = replaceString( qnDataValue, "\", "\\" )
			qnDataValue = replaceString( qnDataValue, quote, "\""" )
			if not ASYM_IsNumber( qnDataValue )
				qnDataValue = quote & qnDataValue & quote
			end
			put quote & qnDataType & quote && ":" && qnDataValue after val
			if i < qnDataTypeCount
				put ", " after val
			end
		end
		put " }" after val

		get extSetTimeout( "addQuestion(" && val && ")", 1 ) of 
			extParentWindow of extDocument of browserRef
	end

	get extSetTimeout( "buildTable()", 50 ) of extParentWindow of 
		extDocument of browserRef
end

The pageLoaded function builds the complete information on each question (notice that it grabs all items such as CorrectAnswer even if the Quiz Summary isn't currently using it) and puts it in the "val" local variable. For each question, it calls the extSetTimeout method of the Web Browser to call the "addQuestion" JavaScript function with "val" as a parameter after a delay of 1 millisecond. Here is that function:

-- JavaScript
function addQuestion( questionData )
{
	allQuestionData[ allQuestionData.length ] = questionData;
}

This populates a JavaScript array with the question data we need. After calling this function for each question, the pageLoaded method calls the JavaScript "buildTable" function to actually populate the HTML file. That function is shown below.

-- JavaScript
function buildTable()
{
	qaTableRef = document.getElementById( "mainTable" );
	qaTableBodyRef = qaTableRef.tBodies[0];
 
	var qnCount = allQuestionData.length;
	for ( qnNum = 1; qnNum <= qnCount; qnNum++ )
	{
		tr = document.createElement( "tr" );
		td = document.createElement( "td" );
		att = document.createAttribute( "class" );
 
		className = "row";
		if ( qnNum < qnCount )
		{
			className += " row-inner";
		}
 
		if ( qnNum % 2 == 1 )
		{
			className += " row-odd";
		}
		else
		{
			className += " row-even";
		}
 
		att.value = className;
		td.setAttributeNode( att );
		td.innerHTML = questionHTML;
 
		tableList = td.getElementsByTagName( "table" );
 
		for ( tableNum = 0; tableNum < tableList.length; tableNum++ )
		{
			tableRef = tableList[tableNum];
 
			rowList = tableRef.rows;
			for ( rowNum = 0; rowNum < rowList.length; rowNum++ )
			{
				rowRef = rowList[ rowNum ];
				cellList = rowRef.cells;
				for ( cellNum = 0; cellNum < cellList.length; cellNum++ )
				{
					cellRef = cellList[cellNum];
					divRef = cellRef.getElementsByTagName( "div" )[0];
					divId = divRef.id;
					divRef.innerHTML = getText( divId, qnNum );
				}
			}
		}
 
		tr.appendChild( td );
		qaTableBodyRef.appendChild( tr );
	}
 
}

This function grabs the "allQuestionData" array that we populated in the addQuestion function and then creates an HTML table row and appropriate columns to display the various pieces of data. This function also has logic for setting different CSS (Cascading Style Sheet) classes for alternating rows so that they have different colors for readability. Pretty cool stuff!



OpenScript Tip from the Learning & Mastering ToolBook Series

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation
Implementing the Print Quiz Summary Button

The code below is from the Shared Script for the Quiz Summary control. It gets called from the "Print Quiz Summary" button. The first thing the code does is initialize some local variables that correspond to constants used by the Web Browser ActiveX control. Using constants like this (OLECMDID_PRINT instead of just the number 6) makes the code much more understandable and maintainable. The code then gets a reference to the browser ActiveX instance and calls its extQueryStatusWB method. This returns an AND of the various statuses, including whether the control is enabled. That's why the code using a bitAnd rather than "=" for the logic. If the control is enabled, it calls the extExecWB method. The first parameter is the command to implement. The code sends the print command but it could send various other options like find, zoom, or paste. The second parameter says to prompt the user for input, in this case to pick the printer to use and so forth. The code sends NULL for the two optional values.

to get ASYM_Print
	OLECMDID_PRINT = 6
	OLECMDF_ENABLED = 2
	OLECMDEXECOPT_PROMPTUSER = 1
	OLECMDEXECOPT_DONTPROMPTUSER = 2
	browserRef = browserRef()
	status = extQueryStatusWB ( OLECMDID_PRINT ) 
		of browserRef
	if status bitAnd OLECMDF_ENABLED > 0
		get extExecWB ( OLECMDID_PRINT, 
			OLECMDEXECOPT_PROMPTUSER, null, null ) 
			of browserRef
		return true
	else
		return false
	end
end



Web Hint from the Learning & Mastering ToolBook Series

By Peter Jackson, ToolBookDeveloper.com


Dynamic Navigation via JavaScript

Question: Does anyone have a method of being able to navigate to pages in your book without using Insert | Action | Navigation | Go To Page? I'm attempting to create a JavaScript function that would be used to navigate pages in ToolBook.

Answer: The JavaScript would be

function tbfunction_gotoPage(pageID){
    	TBK._Gc._Vc(pageID,'');
    	// Editor note: this exact method name varies by ToolBook version due to ToolBook's obfuscation
    }
Getting the page IDs in JavaScript is possible, but unless you want to go to a given page number then that will not help.

To explain, ToolBook assigns page IDs as you create them, starting from 0 (zero), if you delete a page then ToolBook will not re-use that ID or if you change the page display order then the ID numbers will not be in order. When we run the repair utility, the page IDs change and become a numerically ordered list, starting from 0 (zero).

The OpenScript to get the page ID in DHTML form is:

pageID = "p" & idNumber of page ...
Where ... is either the page name or page number.

Therefore, to do this in JavaScript, you need to build some JavaScript at export to build an array of page IDs, names, and numbers. Then using this array, you can get the appropriate DHTML page ID and use the above function to dynamically navigate to a given page.

To build a JavaScript array in OpenScript, you could use this type of code:

..
local stack pageObjs
local object pageObj
local int pNum
pageObjs = pages of this book
pNum = 1

pageNames = "var pageNames=new Array();" & crlf
while pageObjs <> ""
    pop pageObjs into pageObj
    pName = name of pageObj
    pID = "p" & idNumber of pageObj
    increment pNum
    pageNames = pageNames & "pageNames['" &\
        pName &"']='" & pID & "';" & crlf &\
        "pageNames['" & pID & "']='" & pName &\
        "';" & crlf & "pageNames[" & pNum &\
        "]='" & pID & ";" & crlf
end while

Now pageName could look like:

var pageNames=new Array();
pageNames['Introduction'] = 'p0';
pageNames['p0'] = 'Introduction';
pageNames[1] = 'p0';
...
pageNames['Score'] = 'p45';
pageNames['p45'] = 'Score';
pageNames[25] = 'p45'

From the above, you can do go to a page via a number or name:

// JavaScript
function tbfunction_gotoPage(pageNameOrNumber){
    var pageID = pageNames[pageNameOrNumber];
    TBK._Gc._Vc(pageID,'');
}
Using the page ID, name, or number, you can now get the page ID or Name:
The certificate Control Panel (consisting of a Print button and a Close button) has these actions:

var pageID = pageName[pageNumber];
var pageID = pageName[pageName];
var pageName = pageName[pageID];
var pageName = pageName[pageName[pageNumber]];



Flash ActionScript Tip

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Reading XML

One of the examples in the new book is all the resources from a SCORM manifest. As many of you know, this is an XML file. It is interesting to see how to do this in each of our target environments. Flash has excellent XML support as shown in the ActionScript below.

function LoadXmlManifest(eventId:MouseEvent):void {
    var fileName:String = XmlPath.text;
    var requestId:URLRequest = new URLRequest(fileName);
    var xmlLoader:URLLoader = new URLLoader();
    
    xmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
    xmlLoader.addEventListener(Event.COMPLETE, onXmlComplete);
    xmlLoader.load(requestId);
}

function onXmlComplete(eventId:Event):void {
    var xmlLoader:URLLoader = eventId.target as URLLoader;
    
    if (xmlLoader != null) {
        var xmlId:XML = new XML(xmlLoader.data);
        
        xmlId.ignoreWhitespace = true;
        
        var resources:XML = xmlId.children()[2];
        var resourcesList:XML = resources.children()[0];
        var elementId:XML;
        var fileId:String;
        
        for each (elementId in resourcesList.children()) {
            fileId = elementId.@href;
            xmlResult.addItem({label:fileId});
        }
    }
    else {
        trace("xmlLoader is not a URLLoader!");
    }
}

We use the ActionScript URLRequest and URLLoader classes to download and read the XML file. We listen for this to be completed. We then go through the nodes until we find the resources that we want. At that point, we do a nice "for each" loop through the children of this node and read the href attribute of each one (which is the relative path of each file). As we find the relative path, we use the addItem method of our List component to display each one.

VBTrain.Net Nugget

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Reading XML

Lets look at the same book sample in Silverlight that we did in the previous article for Flash.

Private Sub ReadXmlBtn_Click(ByVal sender As System.Object, _
    ByVal e As System.Windows.RoutedEventArgs)
    
    Dim fileName As String = XMLPath.Text
    
    If fileName <> "" Then
        Dim xmlId As XmlReader = XmlReader.Create(fileName)
        Dim elementName As String
        Dim foundResource As Boolean = False
        Dim resList As New List(Of String)
        Dim fileId As String
        
        While xmlId.Read = True AndAlso foundResource = False
            If xmlId.NodeType = XmlNodeType.Element Then
                elementName = xmlId.Name
                If elementName = "resource" Then
                    foundResource = True
                End If
            End If
        End While
        
        While xmlId.Read = True ' Now in file nodes
            If xmlId.NodeType = XmlNodeType.Element Then
                fileId = xmlId.GetAttribute("href")
                If fileId <> "" Then
                    resList.Add(fileId)
                End If
            End If
        End While
        
        xmlResult.ItemsSource = resList
    End If
End Sub

The logic is similar to the Flash example. We don't need to listen for the completion event but rather create an XmlReader object. We then call its Read method to loop through the XML until we find the resource node. We then loop through its nodes, again grabbing the href attribute. We add it to a Generic List object (similar to an array) and then set the ItemSource property of our ListBox to this Generic List in order to databind the box to our collection of file names.



The EnterPage is distributed up to four times per year, with occasional special issues. Individuals who have expressed interest in Platte Canyon Multimedia Software Corporation or its products receive The EnterPage. Suggestions for articles or proposals for article submissions are welcome. Send information to ep@plattecanyon.com. Back issues of the EnterPage are available at:

http://www.plattecanyon.com/enterpage.aspx

Platte Canyon Multimedia Software Corporation, 8870 Edgefield Drive, Colorado Springs, CO 80920, (719) 548-1110