The EnterPage 14-02
October 13, 2011

In this issue:

ToolBook 11 Review

ToolBook 11 Pricing Information

Min-e-Con Report

Plug-In Pro, Storyboarder, TBK Tracker, and ToolBook Translation System for ToolBook 11 Available

Preorder Learning & Mastering ToolBook 11 Plus Lower Pricing

Programming for e-Learning Developers Segment

Expert Information from Learning & Mastering ToolBook

OpenScript Tip from Learning & Mastering ToolBook

Web Hint from Learning & Mastering ToolBook

JavaScript Tip

VBTrain.Net Nugget


It has been some time since our last newsletter, but we are back with news of ToolBook 11, updates of our ToolBook products, a report about the first Min-e-Con, and a large helping of Programming for e-Learning Developers tips on ToolBook, JavaScript (New), and .NET.

ToolBook 11 Review

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

It is nice to see a new ToolBook release. While there are not many "must have" features, there are some good additions to the product. ToolBook 11 should be a good basis for more substantial features in future versions. My personal wish list includes HTML 5 export (including media via HTML 5 rather than Windows Media Player or Flash), additional SmartPages, the capability to access the new Question Wizard from an existing question, and the ability to export PowerPoint directly to a SmartPage. Here are some of the new features:
  • Improved Startup Dialog:  The Startup Dialog has been redesigned to have a more modern look, which also provides for a better process flow for a user trying to start a new book. The Help Resources section has been filled with over a dozen helpful resources to assist you in using ToolBook. We particularly like the ability to start a blank book with SmartStyles so that you don't have an "empty" page that you have to delete later.
  • Question Wizard:  A new catalog object labeled "Question Wizard" has been added to the catalog within the Questions category. When added to your page, this new object will step you through options available for configuring one of the following four question types: Multiple Choice, True/False, Fill in the Blank and Match Item. These four represent the most commonly used question types.
  • Additional SmartStyles:  SmartStyles is a feature that makes it easy to apply a consistent look and style to pages and objects in a book. ToolBook 11 introduces 39 additional SmartStyles including 16 which are specifically designed for mobile device delivery.
  • Arrows (Clipart) Catalog Category:  A new catalog category has been added to ToolBook 11 which provides access to 192 different graphical arrows. These are PNG images with full alpha channel support, which means they will perfectly overlay any other page elements used and are resizable as well.
  • Google Chrome and BlackBerry Support:  The Publish to Web feature of ToolBook has been enhanced to now offer support for Chrome 5+ browsers and BlackBerry 6+ mobile devices.
  • Randomization Enhancements:  The ability to randomize the order of questions displayed to a user has existed in ToolBook for some time as a feature that you can turn on using the Behavior tab of the Properties for Lesson dialog. ToolBook 11 introduces two new features to this dialog, an option to Validate if the book is properly set up for randomization, and a Configure option to allow you exclude certain pages from the randomization.
  • Delete Unused Resources Tool:  This new feature will delete from your book, resources that are no longer actively being used by any objects within your book.
  • Export All Text Tool:  This utility will create a text file containing all of the text found within the book. This is useful when a third party will need to proofread or grammar check the contents of your lesson.
  • Move/Reassign a Range of Pages Tools:  There are new tools to move a range of pages or assign them to a different background.

Some of these features such as the Delete Unused Resources tool were moved into the main product from LiveXtensions. We've had this feature in the Plug-In Pro since 1996 as well:).

We recommend keeping your support current and getting your hands on this new release. In particular, those of you who are publishing to DHTML will want to stay with the newest release to support the widest range of browsers.

Platte Canyon ToolBook Information

ToolBook 11 User Guide

ToolBook Web Site

ToolBook 11 Pricing Information

ToolBook 11 is now shipping. If you currently have a support contract, you should have already received an email from SumTotal Systems with download instructions. If not, contact us or your local representative to see what kind of options we have.

Our upgrade price from ToolBook 10 or 10.5 to 11 is $1,545. If you have a version older than that or are starting up your ToolBook shop, we are selling ToolBook 11 for $2,595 and Support & Maintenance (mandatory for new customers) for $995.

If you would like to purchase ToolBook and/or Support & 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. When you purchase a full version of ToolBook from us, you receive a $100 credit off any of our products. With an upgrade purchase, you get a $50 credit.

Platte Canyon ToolBook Store

Min-e-Con Report

Developers from Texas, Colorado, Louisiana, Nebraska, and Virginia met at the Old Santa Fe Inn in Santa Fe, New Mexico from May 24 - 26, 2011. We had a great meeting room as well as a large suite that we used for an extra session room plus a great reception area. We spent the days in intensive sessions on ToolBook (from beginning to advanced), instructional design, the best use of media, Exam Engine, JavaScript/jQuery, SCORM/AICC, and more. Most of the group enjoyed a great Indian buffet one day and everyone shared local food, margaritas, and the great location of Santa Fe in the evenings. Special thanks go out to Pat Frederick and Beverly Poplin of Del Mar College for suggesting Santa Fe and helping us organize the event.

We've had some inquiries about another Min-e-Con next year. We're not sure right now, but please email us if you are interested. If you would like to suggest another location, please do that was well.

Plug-In Pro, Storyboarder, TBK Tracker, and ToolBook Translation System for ToolBook 11 Available

We have updated Plug-In Pro for ToolBook 11 and have also made it more affordable. A full license is now only $395. The upgrade from 10.5 is $75 and upgrading from any previous Plug-In Pro version is $260. With over 140 utilities, editors, and short-cuts, the Platte Canyon® Plug-In Pro is the ToolBook developer's best friend.

We have also created Storyboarder for ToolBook 11. If you own Storyboarder for a different ToolBook version, the price is only $95. A full version is $295. The Platte Canyon® Storyboarder creates a Microsoft Word storyboard document from an existing ToolBook book. The document includes an optional screen capture of each page, field, button, and other text, question answers/feedback, simulation information, and other content - all the same order top to bottom as in your book. You can run in author-level ToolBook or download the complete ToolBook runtime installation.

We have also updated TBK Tracker and the ToolBook Translation System for ToolBook 11. There is no charge to download the ToolBook 11 files for developers who own the current versions of these products.

Plug-In Pro Information

Storyboarder Information

TBK Tracker Information

ToolBook Translation System Information

Preorder Learning & Mastering ToolBook 11 Plus Lower Pricing

We are hard at work on latest incarnation of our popular ToolBook training series, Learning & Mastering ToolBook 11. Even better news is that we have reduced the price to $495. We have also lowered the prices of upgrading as well as previous versions. We have a CD for each version of ToolBook all the way back to 6.5!

Preorder Learning & Mastering ToolBook 11 or order previous versions

Programming for e-Learning Developers Segment

This feature has put a short segment from Jeff's Programming for e-Learning Developers book.

Hyperlinking to a URL

Clicking on "hyperlinks" is not only a critical part of the web itself but also important to many e-Learning applications. ToolBook and HTML itself make it easiest to hyperlink. But all of our environments can do this task with a little work. To concentrate on the programming part of things, we will read the URL that we want to hyperlink to dynamically. In our first example, the user can type a URL in a field and then click a "Show Window" button. In some environments, we'll also be able to implement a "Close Window" button. In our second example, we'll have one or more hyperlinks in a field. Clicking on the hyperlinks will bring up those sites in a browser.
ToolBook - OpenScript
Let's look at the implementation of the top part of Figure 51 first. There are a number of ways to link to a URL in OpenScript. My personal favorite is shown below.

-- button script
to handle buttonClick
	local string urlString
	urlString = text of field "WindowUrl"
	get tbfunction_ShowWindow(urlString)
end buttonClick

-- book script
to get tbfunction_ShowWindow string url
	get ASYM_AddHyperlink(target, "showUrl", url, NULL, "popup", NULL, \
	get ASYM_DoHyperlink(target,"showUrl")
	get ASYM_ClearHyperlink(target, "showUrl")
	return TRUE
end tbfunction_ShowWindow

In the button script, we get the URL that the person typed in and put this in the urlString local variable. We then call the tbfunction_ShowWindow function that is located in the book script. We put "tbfunction_" at the beginning of the function name so that it will be recognized from the Actions Editor. We will cover this in the next section. Within this function, we call a built-in method called ASYM_AddHyperlink. The most important parameters are the link name ("showUrl") and the destination (the url that we passed in as a parameter). This method doesn't actually launch the window since it can actually be used to create a hyperlink that will be initiated later by the user . To get the hyperlink launched right this moment, we call the ASYM_DoHyperlink method. We tell it which object we are concerned with (this needs to match the first parameter in ASYM_AddHyperlink) and the link name. Note that we don't have any ability to configure the characteristics of the browser (remove the toolbar, set the window size, etc.). We'll get greater fidelity when we use JavaScript. Finally, we clear the hyperlink that we created.

Another way to implement the tbfunction_ShowWindow method would be to call ShellExecute. This is demonstrated in below.

to get tbfunction_ShowWindow string url
	local string nullString
	local long sw_showNormal
	linkDLL32 "shell32.dll"
		LONG ShellExecuteA (Long, String, String, String, String, Long)
	end linkDLL32
	sw_showNormal = 1
	nullString = null
	get ShellExecuteA(windowHandle32 of mainWindow, "open", url, \
 		nullString, nullString, sw_showNormal)
	return TRUE
end tbfunction_ShowWindow

This is our first example of linking to a Windows DLL. Native ToolBook and JavaScript (Internet Explorer only) are the only ones of our target environments that can do this. Once we correctly link the function(s) that we want to call, we use them just like the built-in OpenScript methods. The most important parameters are the operation ("open" or "print"), the file to use, and whether to show the application. One challenge with this last parameter, though, is that we need to figure out the numeric value that equates to the enumeration shown in the documentation. In other environments, we might be provided with a list of valid values. But here we have to search deeper to see that showing the application when it is launched (sw_showNormal) equates to the number 1. By creating a variable with the name of what we are trying to do, we make our code much more readable (e.g., as compared with just putting in "1" for the last parameter).

Still another way to implement tbfunction_ShowWindow is with "automation." Automation is a general term for using one software application to control another one. For example, we have forms in an Access database that we use to hold our customers that calls up the Word envelope dialog box and populates it with the customer's address. We can then just put an envelope in the printer and click the Print button. This is much faster than launching Word every time we want to print an envelope. It turns out that ToolBook has its own "Shell Execute" functionality that can be reached via Automation. I wouldn't recommend this for your e-Learning applications as ASYM_AddHyperlink is easier and less reliant on things being installed. But the code below shows a more advanced concept that may be helpful in another context. We also use automation in native ToolBook to read databases and read/write XML files, among other tasks.

to get tbfunction_ShowWindow string url
	local long sw_showNormal
	local string bs
	local shell
	bs = ASYM_BlockSuspend()
	shell = createAutoObject("TBCOM.ShellAPI",null)
	get extShellExecute(0, "open", url, "", "", sw_showNormal) of shell
	get ASYM_RestoreSuspend()
	return TRUE
end tbfunction_ShowWindow

We anticipate the possibility that the we won't be able to perform the automation and call the ASYM_BlockSuspend method before the line(s) that may cause errors. We then launch our automation with the createAutoObject call. Notice that we didn't declare a type for our shell variable. That is because an automation object is not a built-in OpenScript variable type. We then call a method of the automation object. In OpenScript, properties, methods, and events of automation or ActiveX objects all start with ext. Notice that the parameters of extShellExecute are basically the same as for ShellExecute in the previous set of code. We then call ASYM_RestoreSuspend to turn back on error messages.

Programming for e-Learning Developers Information

Order Programming for e-Learning Developers ($45 with free shipping in the U.S.)

Expert Information from Learning & Mastering ToolBook 

By Peter Jackson,

Showing a Running Quiz Score

Question: I want to have the Feedback button on each of my quiz pages show 1 out of 10 and change with each question if answered correctly/incorrectly. If question 1 and 2 are correct, then question 2 would show 2 out of 10 and so on. But if question 2 is incorrect, it would show 1 out of 10. I went to the Generic Runtime System Prompts and changed the <ScoreisXoutofX> from Score: %1 out of %2 to Score: %1 out of 10. It is correct on question 1 but then on question 2-10 it still only shows 1 out of 10 or 0 out of 10.

Answer: If you add a field to the background and name the field "Score," then use the Actions Editor to handle its Trigger event that will score the book. Edit the Properties of the Score Action and ensure that it will not reset questions or lock them. Now all you need to do is trigger the Score field.

Note that each time you load the page, the Score field is reset. If you want to show the "x out of y" score at all times, then you could try adding another field on top of the Score field that is set with the text of the Score field at "On unload page..." and is cleared when the Score field is triggered.

Peter made it even easier in a follow up post:

On refection, a less complicated way of maintaining the text in the Score field would be to use a global variable to both save and load the text, as follows:

Create a global variable and call it LastScoreText, with an initial value of null.

The Actions of the Score field on the background could then be:

On load page ...
        Set text of self to LastScoreText

    On Unload page ...
        Set LastScoreText to text of self

    On Trigger ...
        Score current book

Note that with the Trigger event on the Score field, the cursor will become the finger when you mouse over the field and when clicked it will score the book. It may be a better idea to add the action to the "On User" event:-)

OpenScript Tip from Learning & Mastering ToolBook

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

International Date Formats

Question: I need to get out of my provincial ways and format dates appropriate to the local preference (i.e., US, European, etc). Are there any functions I could take advantage of in ToolBook to make my path easier for localization of date formats?

The function below from our TBK Tracker product should be helpful. In early versions, we ran into problems with dates stored in an Access database on the user's machine being in a different format than what we expected in ToolBook. This was particularly true in regions that put the day first (25/2/2012 as opposed to 2/25/2012).

to handle tbk_setSysDateFormat
	-- if not ASP mode, converts registry date 
	-- format to ToolBook equivalent
	-- else gets ToolBook date format from ASP 
	-- page

	system string s_originalSysDateFormat, 
		s_fileDir, s_tbk_iniFile, s_tbk_dbType

	local string newFormat, blkSus, errorString, aspPage
	local word offsetNum

	if s_originalSysDateFormat <> NULL 
		-- already set
	end if

	if s_tbk_dbType = "ASP" -- get date format 
		-- from server-side ASP page
		aspPage = tbk_getASPPage("formatData")
		get platte_SetHTTPPostParameter("formatType", "date")
		s_originalSysDateFormat = platte_HTTPPost(aspPage)
		if s_originalSysDateFormat = null
			s_originalSysDateFormat = "mm/dd/y"
		end if
	else -- use date format of client machine
		blkSus = ASYM_blockSuspend()
		newFormat = RegistryGetKey("HKEY_CURRENT_USER\ControlPanel\International", \
		errorString = ASYM_restoreSuspend(blkSus)
		if (errorString <> null) OR (newFormat = null) 
		    -- unable to read date format 
			-- from registry; try win.ini
			newFormat = getWinIniVar("intl", "sShortDate")
			if (newFormat = null) OR (ASYM_isNumber(newFormat) = TRUE) 
				-- unable to read from ini file
				s_originalSysDateFormat = sysDateFormat -- default
			end if
		end if

		-- year
		offsetNum = offset("yyyy", newFormat)
		if offsetNum <> 0
			chars offsetNum to (offsetNum + 3) of newFormat = "y"
		end if

		-- month
		if offset("MMM", newFormat) = 0 -- leave 
			-- alone if contains MMM; else make 
			-- lower case
			newFormat = lowerCase(newFormat)
		end if

		-- day
		-- no conversion req'd

		s_originalSysDateFormat = newFormat
	end if
end tbk_setSysDateFormat

You can skip the "ASP" part. The rest reads the registry and uses that to set the s_originalSysDateFormat system variable. When it comes time to display a date, we temporarily set sysDateFormat to this variable. The rest of the time, we set sysDateFormat to "seconds" since we use the sysDate for time tracking. You likely could just set sysDateFormat once.

Web Hint from Learning & Mastering ToolBook

By Denny Dedmore, SumTotal Systems, Inc.

Bullets Require a Click on Page

Question: I must be missing something real simple. I have converted my first PowerPoint presentation and imported it into ToolBook. I'm going to be exporting to DHTML. I added bullets to a converted page (ToolBook bullets, not PowerPoint), but when I export, they don't fire. I tried covering the whole page with a transparent draw object to trigger the bullets upon click, still no love. What am I missing?

Answer: For a bullet to fly in you must click on the page. If you instead click on some object (a button, and image) instead of the page....then the page does not get the "click" and the bullet will not fly in.

I'm guessing that if you look at your Background, you'll find an image is there, covering the entire area of the page. This would be the thing blocking the CLICK from getting to the page.

I'd suggest adding Actions Editor code to that image, saying:

on click
      Trigger this page

This programmatically simulates a click to the page any time you click the image.

JavaScript Tip

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

Introduction to jQuery

I have been doing quite a bit of HTML and JavaScript and am very impressed with the jQuery library. It is free and is being adopted widely. I like it because 1) it keeps you from having to worry about cross-browser differences, 2) it makes coding in JavaScript more like using Visual Basic or OpenScript. Here is a short example to get you started. The HTML below has two buttons and four images. We want to show all the images when you click the showBtn and hide them when you click the hideBtn.

    <input id="showBtn" type="button" value="Show Images" />
    <input id="hideBtn" type="button" value="Hide Images" />
    <img id="Img1" class="ImageClass" src="media/help.png" />
    <img id="Img2" class="ImageClass" src="media/coda.png" />
    <img id="Img3" class="ImageClass" src="media/Desperado.png" />
    <img id="Img4" class="ImageClass" src="media/5150.png" />

Let's write the logic with jQuery. We first add a reference to its .js file:

<script src="jquery/jquery-1.5.1.js" type="text/javascript"></script>

Next, we add the code below.
    <script type="text/javascript">
        $(document).ready(function () {
            $("#showBtn").click(function (e) {
            $("#hideBtn").click(function (e) {

The $ symbol is the shortcut for making a jQuery call. The parameter is either an object like document or a selector like we will see below. So $(document) is a jQuery object that references the HTML document. We then define what to do when it is ready. This means that the page is fully loaded. This equivalent to Load in Visual Basic or enterPage in ToolBook OpenScript.

When ready, we configure what our two buttons do. This starts to show the real power of jQuery. The $("#showBtn") code gets the jQuery object reference to an HTML object with an id of "showBtn." This is our button. We then define what to do in response to its click event. In that case, we use another jQuery selector, $(".ImageClass"). The "." means that we are looking for all objects with a class of "ImageClass." We then call its show method. Notice that even though there are four of the objects (our images), jQuery takes care of calling the show method for each one. jQuery also takes care of how to show the object based on its type and the browser. This typically means changing the object's display style.

Similarly, we find the hideBtn and defined to hide all the image objects in response to its click event. This just scratches the surface of what jQuery can do. But hopefully, it gives you an incentive to learn more.

VBTrain.Net Nugget

By Jeff Rhodes, Platte Canyon Multimedia Software Corporation

.NET Structures

When I am programming, I often into situations where I need to pass around related data of different types. In some languages, the best you can do is create some sort of array and then stuff the data into elements of the array and hopefully be able to convert the data in and other of strings. But languages like Visual Basic.Net have a more powerful option, a Structure. Like a full-fledged Class, a structure has its own properties and can even have its own methods.

For a custom project I was working on, I needed to read a bunch of related files and keep track of them until I wrote their data to the database. At that time, I needed to move the "successful" files to a "Success" directory, the problem files to an "Error" directory, and those that needed to be skipped to a "Skip" directory. To do this efficiently, I needed to keep track of a reference to the original file and the path to move it to. For that, I used the structure below:
    Friend Structure MoveFileStructure
        Friend FileInfoId As FileInfo
        Friend TargetPath As String
    End Structure

The structure has two properties. The FileInfoId is of type FileInfo and is a reference to the file itself. The TargetPath is the complete path to where I want to move the file later. I then carry that data around the program until I needed to work with the files. For example, the method below actually moved the files to their new location.
    Friend Sub MoveFiles(ByRef moveFileList As List(Of MoveFileStructure))
        Dim newFilePath As String
        Dim structureId As MoveFileStructure

        For Each structureId In moveFileList
            newFilePath = structureId.TargetPath
            If File.Exists(newFilePath) Then
            End If
            Catch ex As Exception
                ' don't do anything
            End Try
    End Sub

We pass in a Generic List (another great concept in .NET) of MoveFileStructure objects. So each of these are instances of the structure, which means they have FileInfoId and TargetPath properties. We then loop through the list. We read the TargetPath and delete any existing file with that path. We then use the MoveTo method of our FileInfo object to move the file to the new location. We put the code into a Try-Catch block just in case the file got listed twice and has already been moved. Finally, we clear our list since the files have now been moved.

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