The EnterPage 11-02
May 5, 2008

In this issue:

Save $50 by Signing Up for ToolBook User's Conference / e-Learning Authoring Conference by May 15

Schedule Available for the ToolBook User's Conference / e-Learning Authoring Conference

ToolBook 9.5 Preview Available

Plug-In Pro Spotlight - Generating a Spell-Check File

Expert Information from the Learning & Mastering ToolBook Series

OpenScript Tip from the Learning & Mastering ToolBook Series

Web Hint from the Learning & Mastering ToolBook Series

ToolBook Actions Editor Advice

Flash ActionScript Tip

VBTrain.Net Nugget


Welcome to The EnterPage newsletter. Conference preparations are in high gear. Bags, T-shirts, notebooks, and even "hoodies" have all either arrived or are on order. We are excited about this tenth version of TBCON. We hope you will be able to join us in Colorado in June. In addition to conference news, we've also packaged our best ToolBook, Flash, and .NET tips and tricks for your enjoyment.

Save $50 by Signing Up for ToolBook User's Conference / e-Learning Authoring Conference by May 15

If you haven't signed up yet, don't forget to do so before prices go up by $50 after May 15. Even after the increase, it will be one of the best training and networking values anywhere, but why part with the extra cash?

We'll be celebrating the tenth anniversary of the conference with the usual great lineup of 18 one-hour session blocks over three days, with each block containing five sessions to choose from. We also have an excellent lineup of preconference workshops, including the first ever by Tim Barham and Simon Price. In addition to all the scheduled learning, there will be three great receptions, the always popular "Hack Ack" contest, the Help Desk where you can get answers to your individual questions, and the ability to meet with SumTotal's Brad Crain (Vice President, ToolBook) and Sheri Miller (Global Sales Director, ToolBook).


June 16 - 18, 2008
Preconference Training June 14 - 15, 2008

Rates (All Options Include Three Meals Per Day Plus Snacks)
  • Off Campus ($780)
  • Windom House Double ($855)
  • Windom House Single ($925)
  • CC Inn Single ($975)
  • Apartment Multiple Occupancy ($975)
  • Apartment Single ($1,175)
Note that the above prices rise by $50 after May 15, 2008.

Preconference Training

  • One Preconference Session ($150)
  • Two Preconference Sessions ($285)
  • Three Preconference Sessions ($420)
  • Four Preconference Sessions ($555)






Schedule Available for the ToolBook User's Conference / e-Learning Authoring Conference

The complete TBCON schedule is now online. You can get the overall view using the Daily Schedule and can build a complete schedule to show the boss just what you would learn using the Scheduler Application. The Scheduler is particularly handy since most of the sessions are repeated twice. It allows you to jump to the next time a session is offered so see if you can squeeze the one you want into that time slot instead.

ToolBook 9.5 Preview Available

If you aren't already working with the ToolBook Instructor 9.5 preview version, we recommend trying it out today. Some of the exciting new features include:
  • Apple iPhone/iPod Support
  • Safari Browser Support
  • Voice Recording
  • Enhanced Right-Click Menus
  • Ability to Hide the Universal Media Player

Note that SumTotal will be doing two sessions on 9.5 at TBCON: "ToolBook - A Look Ahead: Preview the Upcoming ToolBook 9.5 Release" and "ToolBook - A Look Ahead: ToolBook XML Format." Tom Hall will also be previewing the mobile learning capabilities in his "Developing ToolBook Content for iPhone and iPod Touch" session.

Preview Site

New Features

Plug-In Pro Spotlight - Generating a Spell-Check File 

One of the challenges of a successful e-Learning project is ensuring that your content does not have any spelling or grammatical errors. While ToolBook has a basic spell-check capability, it does not dig into question objects, simulations, user properties, etc. Nor does it check your grammar. That's why we added the ability to export all your content to an external file to the Plug-In Pro. You can then do a spelling and grammar check within Microsoft Word or a similar program. The Plug-In Pro dialog box allows you to specify page ranges, backgrounds (and associated pages) to include, whether to include question and/or simulation objects, whether to include user properties, and what object properties (to find the offending pages and objects later) to include in the file. We use this feature for each module of the "Learning & Mastering ToolBook" series before going to production.

To learn more, you can follow these links.

Help topic

Plug-In Pro web page

Expert Information from the Learning & Mastering ToolBook Series 

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Why Read a Database into a ToolBook Array

In many cases, it makes a great deal of sense to read an entire table into a ToolBook array. The main reason to do this is to only have to access the database a single time. While you have it open, why not just read it all and be done with it? This is especially a factor if your database is on a network server or available via the Internet. Minimizing queries to the database will reduce the load on the server and speed up your application. Since each cell can hold up to 64K of data, you are unlikely to run out of "space" as long as your database contains text. However, if you have a very large database and don't need access to the entire table, you can query the database for only the data you need first using ADO and THEN put it in your array.

If you need to write information back to the database at the end of the session, you can keep the array updated and then use ADO to write to the database at the end. This is what we do with our TBK Tracker™ and Progress Tracker™ products.

Note that Jeff covers this topic in detail in his "Connecting to Databases in ToolBook Using ADO" session at TBCON.

OpenScript Tip from the Learning & Mastering ToolBook Series

By Denny Dedmore, SumTotal Systems, Inc.

RichText to Word via Automation

Question: Is there any way of exporting the richtext of a tbk (along with the graphics) to a Word type document?

Here is some code that should do the trick. It uses Automation to connect silently to Word (Word will not appear to the user as being launched) and then copy/paste the field into Word and then closes the document. It will copy all the formatting and the any images you have in the field too. You will need to modify only two lines as denoted in the code. I have done just very basic testing on this code to ensure it worked for me. You may want to tweak the code a bit to fit your exact needs.

to handle buttonClick
	-- Update this line with the reference to 
	-- the file you wish to save.
	fName = "c:\temp.doc"

	-- Update this line with the reference to 
	-- your field.
	select text of field "foo"
	send copy

	bs = ASYM_BlockSuspend()
	wordObject = 
	err = ASYM_RestoreSuspend(bs)

	if err <> NULL OR wordObject = NULL
		request "Can't open Word"

	bs = ASYM_BlockSuspend()
	emptyDoc = extAdd() of extDocuments of 
	err = ASYM_RestoreSuspend(bs)

	if err <> NULL OR emptyDoc = NULL
		request "Can't create a new document"
		get closeAutoObject(wordObject)

	bs = ASYM_BlockSuspend()
	get extSaveAs(fName) of emptyDoc
	err = ASYM_RestoreSuspend(bs)

	if err <> NULL
		request "Error saving Word Document"
		get closeAutoObject(wordObject)

	get extPaste() of extSelection of wordObject

	-- save and close the storyBoard file
	get extSave() of emptyDoc
	get extClose(0) of emptyDoc

-- Close the Automation Object
to get closeAutoObject obj
	bs = ASYM_BlockSuspend()
	get extQuit(0) of obj
	get ASYM_RestoreSuspend(bs)
	return null

Web Hint from the Learning & Mastering ToolBook Series

By Tim Barham, SumTotal Systems, Inc.

SCORM Calls for "Exit (Mark as Complete)"

Question: Can somebody tell me the code that gets fired to the LMS when the "Exit (Mark as Complete)" button gets triggered?

During HTML export, the object is recognized as an "Exit (Mark as complete)" button, which results in JavaScript that calls our Exit function (in classes.js) with parameters indicating we're exiting and marking the lesson as complete, which results in the following calls to the SCORM API (assuming SCORM 1.2 - for SCORM 2004 the calls are similar):
LMSSetValue( "cmi.core.lesson_location", [URL to current page] );
LMSSetValue( "cmi.core.exit", "" );
LMSSetValue( "cmi.core.lesson_status", "completed" );
LMSSetValue( "cmi.core.score.min", [min score for book] );
LMSSetValue( "cmi.core.score.max", [max score for book] );
LMSSetValue( "cmi.core.score.raw", [actual score achieved] );
LMSSetValue( "cmi.core.session_time", [accumulated time spent in lesson] );

[in here we construct the suspend data and write it out to the LMS]

ToolBook Actions Editor Advice

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Working With Global Variables Stored in the LMS

I was helping a customer of our Tracker.Net LMS a few weeks ago. In their lesson, they set global variables when certain pages were visited and then showed corresponding links on a Table of Contents page. The problem was that their logic worked while within the session but not once the user exited and returned in a later session. Here's a section of the original "on load page" action for the Table of Contents page.
If P1begininning = true
  Set visible of Auto-Sizing Field "P1 Text Field" to true
  Set visible of Hotspot Area "P1Hotspot" to true
  Set enabled of Hotspot Area "P1Hotspot" to true
  Set visible of Auto-Sizing Field "P1 Text Field" to false
  Set visible of Hotspot Area "P1Hotspot" to false
  Set enabled of Hotspot Area "P1Hotspot" to false
End if

The corresponding page in the book had this "on unload page" action:
Set P1begininning to true
There was nothing obviously wrong with the code, but I confirmed with our SCORM Watch product that although the values of P1beginning and similar variables was stored in the "suspend data" and restored to the lesson on the next session, the fields and hotspots on the Table of Contents page were not shown. It occurred to me that the problem might be with the difference you can get in JavaScript between the boolean value of true and the string value of "true." Sure enough, that was it. So I rewrote the logic to be:
Define local variable "showP1" (Initial value: "")

Set showP1 to P1begininning = true or P1begininning = "true"

Set visible of Auto-Sizing Field "P1 Text Field" to showP1
Set visible of Hotspot Area "P1Hotspot" to showP1
Set enabled of Hotspot Area "P1Hotspot" to showP1
Notice how I used a local variable (showP1) that was true if the global variable was true or "true". I also cut down the number of lines by setting the visible of the objects directly to this variable rather than the original "if" condition. The lesson is that any global variable stored in the LMS will come back as a string rather than its original data type.

Flash ActionScript Tip

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Setting Font and Other Properties for Flash Components

One of our Training Studio customers wanted to change the font of CheckBox and RadioButton component used on question_multipleChoice and question_trueFalse Flash templates. This is not as trivial as you might think as there is no interface in Flash for doing this. As with the rest of the Training Studio design, we wanted to limit the code in the templates as much as possible. So we added this single, optional, line in the loadData function:
master_mc.setAnswerFont(this, 1, 8, "16", true);  
        //Sets up the font size and font weight (Bold = true)
The master_mc variable is a reference to the parent (starting) movie. We call its setAnswerFont method, passing a reference to the current template (needed to find the checkBoxes or radioButtons themselves), the starting number (using the fact that the objects are named answer_1, answer_2, etc.), then ending number, and whether to make the font bold as well. We then put this code in the starting movie:
function setAnswerFont(contentMovieId:MovieClip, startingNumber:Number, 
        endingNumber:Number, fontSize:String, isBold:Boolean):Void {
    studioClassId.setAnswerFont(parentMc, contentMovieId, startingNumber, 
        endingNumber, fontSize, isBold);
This function is just a wrapper for the real code, which is located in the file and referenced from the studioClassId object. We send a reference to the starting movie (parentMc) and then send the rest of the parameters we received from the template. Here is the function in the .as file:
public function setAnswerFont(movieId:MovieClip, contentMovieId:MovieClip, startingNumber:Number, 
        endingNumber:Number, fontSize:String, isBold:Boolean):Void {
    var objectId;
    var num:Number;
    for(num=startingNumber; num<=endingNumber; num++) {
        objectId = contentMovieId["answer_" + num];
        if (objectId != null) {
            if (isBold == true) {
We just loop through the objects referenced by name using this helpful syntax: objectId = contentMovieId["answer_" + num];. If we are able to retrieve a reference to the component, we call its setStyle method, passing the attribute ("fontSize" or "fontWeight") as the first parameter and the value as the second parameter.

VBTrain.Net Nugget

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

File Date/Version Information

One of the desired new features for our Tracker.Net LMS is the ability to compare a user's installation will a "master" copy located online. As part of that functionality, we've added a web service that lists all files with dates and versions of both the local and the master versions, with the ability to exclude help, image, and other files if desired. The implementing code also demonstrates the use of recursion (e.g., a function calling itself). This was a topic that recently stimulated some good discussion in other context on the ToolBook List.
Private Sub BuildResourceList(ByVal dirName As String, ByRef listId As List(Of String), _
    ByVal dirInfoId As DirectoryInfo, ByVal skipHelpImageReports As Boolean, ByVal skipCodeFiles As Boolean)
	Dim fileInfoArray As FileInfo() = dirInfoId.GetFiles()
	Dim fileInfoId As FileInfo
	Dim fileVersionInfoId As FileVersionInfo
	Dim fileName As String

	For Each fileInfoId In fileInfoArray
		fileName = fileInfoId.FullName
		If skipCodeFiles = False OrElse fileInfoId.Extension <> ".vb" Then
			fileVersionInfoId = FileVersionInfo.GetVersionInfo(fileName)
			If fileVersionInfoId.FileVersion IsNot Nothing Then
				listId.Add(String.Format("{0}{1}{2}{1}{3}{1}{4}", FormatRelativePath(dirName, _
				    fileName), ControlChars.Tab, fileInfoId.LastWriteTime.ToShortDateString, _
				    fileInfoId.LastWriteTime.ToShortTimeString, fileVersionInfoId.FileVersion))
				listId.Add(String.Format("{0}{1}{2}{1}{3}", FormatRelativePath(dirName, _
				    fileName), ControlChars.Tab, fileInfoId.LastWriteTime.ToShortDateString, _
			End If
		End If
	' Add subdirectory info
	Dim directoryInfoArray As DirectoryInfo() = dirInfoId.GetDirectories()
	Dim directoryInfoId As DirectoryInfo

	For Each directoryInfoId In directoryInfoArray
		Dim subDirName As String = FormatRelativePath(dirName, directoryInfoId.FullName)
		Dim isHelpImageReports As Boolean = (subDirName.ToLower.Contains("images") = True OrElse _
		    subDirName.ToLower.Contains("help") = True OrElse subDirName.ToLower.Contains("reports") = True)

		If skipHelpImageReports = False OrElse isHelpImageReports = False Then
			listId.Add(String.Format("------{0}-------", subDirName))
			BuildResourceList(dirName, listId, directoryInfoId, skipHelpImageReports, skipCodeFiles)
		End If
End Sub

Private Function FormatRelativePath(ByVal dirName As String, ByVal inputPath As String) As String
	Dim returnString As String = inputPath

	If returnString.StartsWith(dirName) = True Then
		returnString = returnString.Substring(dirName.Length + 1)
	End If

	Return returnString
End Function
We pass in the top-level directory and loop through all of its files, grabbing name, date, and, if available, version information. We then loop through each subdirectory and call the same function (BuildResourceList) to get a list of its files. If that directory has subdirectories, then it calls BuildResourceList still again. Along the way, we check for whether files and directories are for help, image, report, or code files. We use similar code in products like Training Studio and Exam Engine to build SCORM manifests that include all files in a lesson or exam.

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 Back issues of the EnterPage are available at:

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