Introduction Welcome to The EnterPage newsletter. It has been a busy few months since the last newsletter. As with many of you, our lives recently have been best described by one word: ToolBook. ToolBook Instructor 9 came out with positive reviews (see report in this issue). As described below, we released the ToolBook Translation System 9 and Learning & Mastering Instructor 9. We took some brief time out for the annual ToolBook User's Conference / e-Learning Authoring Conference, which was a great deal of fun as always. We hope this newsletter contains some useful information for you about the latest news in the Platte Canyon and ToolBook worlds and serves as a source of tips and tricks about ToolBook, Flash, and .NET. Enjoy! |
Learning & Mastering ToolBook Instructor 9 Now Available Our flagship training CD has been completely updated for ToolBook Instructor 9. There is new content on such topics as:
Information Outline Order |
ToolBook User's Conference / e-Learning Authoring Conference Report
The ninth year of The ToolBook User's Conference and the second year of The e-Learning Authoring Conference was another hit. With Dan Carr and Dane Williams joining Adam Brown on our Flash track faculty, we had the Flash developers as jazzed as the ToolBook developers. Almost 100 developers from around the U.S. as well Australia, Canada, Denmark, and the UK converged on Colorado Springs from July 28 - August 1 to share knowledge on ToolBook 9, increase their skills in Flash, learn about management topics like SCORM, share tips, meet new friends, and reconnect with old ones. Some highlights included Tim Barham and Tomas Lund's "Boy Band" performance, great hack ack presentations from Iris Peceny/Tina Lechner, Mauro Rech/Lee Jay Karns, and Mike Cline/Bob Culver, the famous group photo, a fire alarm on the last day, and more! Congratulations to these SumTotal Systems ToolBook Design Award winners:
TBCON 2007 Resources Archives for Attendees Mark Your Calendars for Next Year June 16 - 18, 2008 Preconference Training June 14 and 15, 2008 |
Special TBCON Pricing on ToolBook Extended! SumTotal Systems has extended the special ToolBook pricing for TBCON attendees through the end of September. So act now to receive these great discounts on ToolBook Instructor 9:
Online Store |
TBCON Archives for Attendees Available Conference attendees receive free access to the Archives for Attendees web application. This allows access to all session content from TBCON 2007, including ToolBook files, Flash movies and source files, JavaScript and HTML documents, .NET solutions, PowerPoint slides, web links, bonus materials, descriptions of each session, faculty information, etc. You can filter by session type or faculty member, navigate through matching sessions, view material online, and more. Those of you who couldn't join us can get continuous access for only $50. Here are some links: Available Presentations and More Information Order |
ToolBook Translation System 9 Released
With a new user interface, the ability to have identically-named objects in different groups, explicit support for Text Panes and other catalog objects, a Word Count feature, ToolBook 9 support, and more, this is a MUST HAVE version.
Information Order |
Report on ToolBook Instructor 9 By Jeff Rhodes, Platte Canyon Multimedia Software Corporation I've been using Instructor 9 virtually every day since the availability of the preview release in early May. I was surprised at how smooth it was moving to the new version. My first test was to see if ActiveX Data Objects (ADO) would work, as its ability to communicate with Access and SQL Server is critical to many of our products. Luckily, ADO worked immediately. And as Shayne Hamel posted to the ToolBook List, it is considerably faster than in the past as well. Speaking of speed, exporting to DHTML is about five times faster than in ToolBook 2004 (thanks to Tomas Lund for the statistics on this). Another high priority was playing Flash. Although playing Flash via the Universal Media Player and directly as an ActiveX control worked fine, I did get a "Compatibility" message in Vista on exiting a book that had the Flash player in it. This turns out to be a Vista problem. SumTotal has coded around it and will incorporate the fix into the next dot release (you can also download an unsupported fix from the Knowledge Base). Media clips (.wav, .mid, .avi, .bmp) played fine for me, though there are reports on the ToolBook List of some issues with mmSeek and mmStep. HTTP Post continues to work fine (and now tbcom.dll does not need to be registered for it to work with native applications). The main area that I had to change existing OpenScript is where I was linking to 16-bit DLL's. The Version Updater utility does a nice job of changing what it can and flagging the rest for you to address. What about the new features? SmartPages and SmartStyles are very cool technologies. What I really like about them is that fonts, colors, graphics, AND layout are all defined by the SmartStyle. So if you "re-skin" a book by dragging on a different SmartStyle, navigation elements will re-position themselves to match the new interface. Questions will use matching graphics, the "Show Info," "Show More", and "Show Less" buttons used on some of the SmartPages will get new graphics, and the headings and text will change to the font and colors defined by the SmartStyle. You can even drag on a question from the Catalog onto a SmartPage and it will grab the "look and feel" of the book. That is why there is a new "Questions" category in the Catalog that is separate from "Questions (Multiple Choice)" and so forth -- the idea is that you only need a single Multiple Choice question since it will grab the graphics from the SmartStyle. But if you want the various permutations and graphics, you can still get them from the "Questions (Multiple Choice)" category. The same goes for the other question types. It will take some time for all of us to get used to using these new features in actual content, but they have tremendous possibilities. Tom Hall wrote a nice article this week about these new features. I recommend reading it. We also cover SmartStyles and SmartPages in the new Learning & Mastering ToolBook Instructor 9. Another nice new feature is the Book Explorer. The Book Explorer replaces the Object Browser and has much more functionality. Hidden objects are grayed out so you can immediately spot them. Right-clicking on an object in the Book Explorer brings up the standard Right-click menu, just like if you were on the actual object. You can drag objects within a page or background to change their layer order or move them between pages and backgrounds. When you hover over a page or background, you see a thumbnail of it. This is quite handy. AutoPackager has gotten a major facelift. I like that it uses Microsoft's .msi technology. The biggest other change is the updated toolbar and tool palette graphics. They give version 9 a more modern interface. There are also some minor but useful new features like the Quiz Summary and the "Go To" dialog (though I'm still not happy that this has the Ctrl + G shortcut and grouping/ungrouping has been relegated to Ctrl + Shift + G). The DHTML export process is mostly unchanged but the output itself has been updated for Internet Explorer 7 and to avoid "Eolas" messages. As you can tell, I am quite pleased with this release, particularly given the technological hurdle of getting to 32-bit. SumTotal has a good starting point for adding more functionality in future releases. |
The Best of Elearning! Nominations If you are so inclined, please nominate your favorite products in Elearning! Magazine's balloting. Please consider ToolBook for "Best Web Authoring Tool," "Best Simulation Solution," and "Best Assessment Tool." You might also consider Tracker.Net for "Best LMS," Training Studio for "Best Web Authoring Tool" and Exam Engine for "Best Assessment Tool." Nominations |
Special ToolBook Pricing for Authorware Developers Plus Training Discounts With the recent announcement that Adobe will discontinue development of Authorware, this is a great time to move to ToolBook. This is especially true since SumTotal has authorized its partners like Platte Canyon to offer ToolBook Instructor at a 50% discount ($1,397.50) to existing Authorware customers who also purchase Premium Support ($995). You can order online (just add a note that you are an Authorware user), via email (sales@plattecanyon.com), via fax (719-548-1114), or phone (888-866-5251 or 719-548-1110). Note that we'll need a screen shot of your license to process your order. Online Store SumTotal and Authorized Training Centers are also offering some specials on classroom training through the end of September. ToolBook Classroom Training Specials |
Attend Sessions By Tim Barham and Simon Price at SumTotal's EMEA Conference in London Those of you in Europe who couldn't make TBCON have a great opportunity next month to attend presentations by two of our key TBCON faculty members (Tim Barham of SumTotal Systems and Simon Price of the University of Bristol). They are giving these sessions at SumTotal's Europe, Middle East, and Africa (EMEA) User Conference being held in London on October 3, 2007:
EMEA Agenda and Registration toolbook.org Event Description |
Plug-In Pro Spotlight - Command Window Tools As you become more experienced with ToolBook and start to understand the power of OpenScript, you'll learn how helpful the Command Window can be. One simple example of a Command Window script is the one we used to make a book ready for making a Show Me movie for the new Learning & Mastering ToolBook CBT. To make all the movies consistent, we needed to have the ToolBook book at a particular size, without scroll bars, and without extra author-level menus added by our Plug-In Pro. So we came up with this Command Window script: size of mainWindow = 726,453 send sizeToViewer remove menu "Platte" at author remove menu "Custom" at author But since the Command Window doesn't retain its contents after a book is closed, we need a way to store the script for the next time. In the past, we'd make a "CommandWindow.txt" file and try to remember to save scripts to it. We'd then open it up, find the script we want, and paste it into the window. But this got old and took some time (not to mention the fact that we had to remember to paste our scripts in the file). With Plug-In Pro 7, you now can use the Command Window Tools. It has a button called "New From Command Window" that will copy the current script into the editor. You can then give it a title and a description. Or you can enter a new script directly in the Editor. The best part is that you can immediately recall any script and either "Copy To Command Window" or even "Run From Command Window." You can even send your "tbCommandScripts.txt" file to another developer to let him or her use your scripts. To learn more, you can follow these links: Help topic Plug-In Pro web page |
Expert Information from the Learning & Mastering ToolBook Series By Simon Price, University of Bristol, http://simonprice.info Hashes, Heaps, Array, and Other Data Structures Question: Are there any special Dlls for implementing Data Structures besides Arrays, such as Hash Maps, or Heaps etc ???? Good question. Some answers (for OpenScript) below... 1. HASHES For the non-computer science people, a hash is like an array where you can use text for the index instead of numbers one would normally use with arrays. For example, arrays in JavaScript can be used like this: email["simon"] = "simon@example.com" email["fred"] = "fred@somewhere.com" In ToolBook, there's a fairly quick association list implementation of hashes written in OpenScript (look at ASYM_SetDataElement and ASYM_GetDataElement). The entire hash is subject to all the current size implementation of variables (64k max) and is slow compared to arrays. Also, you can mimic hashes by using dynamic naming of user properties which gets around the 64k limit and is fast too. For example: email("simon") of this book = "simon@example.com" email("fred") of this book = "fred@somewhere.com" Note that you will often see (in old code) the following much uglier, slower version of roughly the same trick but this isn't recommended; use the propname(index-string) notation as shown above. execute "email_" & "simon" & " of this book = " \ & QUOTE & "simon@example.com" & QUOTE I keep nagging STS about adding string indexing for arrays which, in effect, would give you hashes but I'm not expecting this for the next release at least. 2. HEAPS Again, for the non-computer science people, a heap provides your program with a way of asking for chunks of memory and returning them once your program has finished with the memory. Tidying up all the released memory on the heap (and sometimes elsewhere too) is called garbage collection. Like Java, OpenScript runs in a virtual machine and does its own heap allocation for variables, arrays, etc. and it does its own garbage collection once they go out of scope and have no references, so you tend not to need an explicit heap structure yourself. You may need access to a heap when you want to call Windows API or other external API functions which may expect to receive data on the heap. OpenScript lets you call the Windows kernel to allocate and de-allocate blocks of memory using ASYM_GetMemBlock and ASYM_FreeMemBlock which are just wrappers around the GlobalAlloc() and GlobalFree() kernel functions (which incidentally, you can call directly if you need to). 3. LISTS Native built-in type in OpenScript. Use push/pop instead of "item N of" when constructing large lists because it is much faster. 4. STACKS Use a list in conjunction with push and pop. 5. QUEUES Use lists in conjunction with push and "last item of" operation (assuming the last item is the head of the queue and the first item is the tail). Or more nicely, wrapper these queue and dequeue operations using "to get" and "to set" handlers. 6. TREES & GRAPHS No libraries I know of. Grow your own :-) These can be implemented using an array of lists or list of lists or with user properties. Trade-off between clarity and performance but not rocket science to implement. 7. SETS & MULTISETS Sets can be implemented using hash techniques described in 1. Ditto multisets. For smallish sets you can just use a list and search for membership before pushing a new element onto the list if not already present. I'd guess that maintaining a sort order in the list makes union, intersection, difference etc. easier to write. In fact, most (if not all) of the usual computer science data structures can be implemented in ToolBook quite easily using the built-in list processing, arrays and (most powerfully) user properties. It just takes a little while to learn the corresponding OpenScript idiom for each. Also, you can access user properties (as well as regular object properties) across different books (at high speed), which is really neat - provided you don't go mad and create spaghetti cross referencing of course. Furthermore, you can generate code at runtime too which makes it possible to roll-out data structures into hard-wire code specific to a given task. Finally, there are intraspection properties which let you see a list of all user properties, system variables and so on. You have to work hard to get performance sometimes, but everything is possible. |
OpenScript Tip from the Learning & Mastering ToolBook Series
By Jeff Rhodes, Platte Canyon Multimedia Software Corporation SysOperatingSystem, Vista, and ToolBook 9 One of the challenges with Windows Vista is that the default "Aero" scheme draws bigger windows than in XP or Windows 2000. ToolBook 2004 and older versions could not correctly create windows of the correct size, particularly when you use the "Auto Size to Page" setting for viewers. This was a problem for our Plug-In Pro as most of our viewers were set that way. At the same time, one code base supported ToolBook versions 8.6 through 9. So we edited the shared script for our viewers and called the handler below. Notice that we use sysOperatingSystem to figure out if we are in Vista and sysVersion to figure out if we are in ToolBook 9 (where the problem was fixed). to handle plg_setViewerProperties object viewerId local string opSystem, tbVersion local word numWords local string opSystemVersion local logical isVistaNot9 local page pageId local word pageWidth isVistaNot9 = false opSystem = sysOperatingSystem tbVersion = sysVersion if word 1 of tbVersion < 9 -- problem fixed in 9.0 and later numWords = wordCount(opSystem) if numWords > 2 opSystemVersion = word 3 of opSystem if isNumber(opSystemVersion) = true if word 2 of opSystem = "XP" AND opSystemVersion >= 6 isVistaNot9 = true end if end if end if end if if isVistaNot9 = true AND platteIsOpen of viewerId <> true -- so don't change it after viewer is open autoSize of viewerId = false pageId = currentPage of viewerId if size of parent of pageId = "0,0" pageWidth = item 1 of size of parent of parent of pageId else pageWidth = item 1 of size of parent of pageId end if item 1 of clientSize of viewerId = (pageWidth + 100) -- to account for wider window in Vista end if end plg_setViewerProperties |
Web Hint from the Learning & Mastering ToolBook Series
By Jeff Rhodes, Platte Canyon Multimedia Software Corporation Formatting your ASP.NET Pages for HTTP Post One thing that can trip you up in creating ASP.NET pages for use in HTTP Post is that any extra HTML within the .aspx page will end up coming back as part of the return value for your post. For example, when you create a page called mailViaPost.aspx in Visual Studio.NET 2005, here is what the content of the .aspx page looks like: <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="mailViaPost.aspx.vb" Inherits="tbcbt9examples.mailViaPost" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html> To clean this out, you need to get rid all the HTML and just leave this line: <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="mailViaPost.aspx.vb" Inherits="tbcbt9examples.mailViaPost" %> Note that web services don't have this problem but DO send the return value within XML that needs to be stripped out. |
Flash ActionScript Tip
By Jeff Rhodes, Platte Canyon Multimedia Software Corporation Using ExternalInterface to Communicate between Flash and ToolBook With the advent of Flash 9 (CS3) and ActionScript 3, Adobe recommends replacing fsCommand with ExternalInterface when targeting version 8 or new players. The ActionScript 3 help topic for ExternalInterface puts it this way: This functionality is a replacement for the older fscommand() method.We use ExternalInterface in our Training Studio product to make SCORM (JavaScript) calls. There is downloadable sample of doing this in the TBCON Archives for Attendees. But what about using ExternalInterface to communicate with both a native ToolBook book and a DHTML ToolBook application? That's one of the topics that we explored for the new Learning & Mastering ToolBook Instructor 9 CD. The good news is that it works quite well in both cases. A nice bonus is that the communication works both ways without needing to set a Flash variable or use an even older method like TCallLabel. Let's first look at sending information FROM Flash TO ToolBook (or any other container such as a browser or a Windows Forms .NET application). Here's what the Flash side looks like (ActionScript 3): initializeMovie(); function initializeMovie():void { SendText_btn.addEventListener(MouseEvent.CLICK, sendText); GrabText_btn.addEventListener(MouseEvent.CLICK, grabText); } function sendText(event:MouseEvent):void { var sendString:String = Input_txt.text; ExternalInterface.call("sendTextToTB", sendString); } function grabText(event:MouseEvent):void { var returnString:String; Result_txt.text = "Sent call to getTextFromTB"; returnString = ExternalInterface.call("getTextFromTB"); Result_txt.text = returnString; }The addEventListener lines define what ActionScript functions to call in response to clicking our "SendText_btn" and "GrabText_btn" buttons within the Flash movie. In the sendText function, we grab the text of a field (where the user can type something) and use the ExternalInterface class to call a "sendTextToTB" function with a parameter of "sendString." In the grabText function, we want to get the text from ToolBook. So we call it with the "getTextFromTB" method and display the result in a field. To respond to either of these calls in ToolBook, we handle the "on Flash call" (Actions Editor) or extFlashCall (OpenScript). Here is the OpenScript version: to handle extFlashCall local string flashText, textFromFlash, textToFlash local word startChar, endChar flashText = argument 1 if flashText contains "sendTextToTB" startChar = offset(">string<", flashText) endChar = offset(">/string<", flashText) textFromFlash = chars (startChar + 8) to (endChar - 1) of flashText request "Text from Flash = " & textFromFlash else ask "Enter the text to send to Flash" with "Learning & Mastering" textToFlash = it get extSetReturnValue(">string<" & textToFlash & ">/string<") end if end extFlashCallThe information we need from Flash comes in the argument parameter (I figured this out by looking at the OpenScript generated from doing this in the Actions Editor). Flash sends it in XML format, so the entire flashText string will look like this for the first function: >invoke name="sendTextToTB" returntype="xml"<>arguments<>string<Hi. There.>/string<>/arguments<>/invoke<. It will have this format for the second function: >invoke name="getTextFromTB" returntype="xml"<>arguments<>/arguments<>/invoke<. Notice how the text we want from Flash in the first instance is between the >string< and >/string< tags. We find the position of these and get the text in between. Sending values BACK to Flash is more challenging. Luckily, there is a SetReturnValue method of the Flash player expressly for this. Thanks goes to Tim Barham of SumTotal for brainstorming with me on this via Instant Messaging. Notice how we need to send this back to Flash in XML format. We can also set up "callbacks" where we can call an ActionScript function directly from ToolBook. We'll look at that in the next issue of the EnterPage. Or you can check out the new Learning & Mastering CD :) |
VBTrain.Net Nugget
By Jeff Rhodes, Platte Canyon Multimedia Software Corporation Simple Inheritance One of my favorite sessions from this year's TBCON was "Object-Oriented Programming with .NET, Flash, and ToolBook." In each environment, I did a sample with an Animal "parent" class. There are then Cat and Dog classes that inherit from Animal. Let's look at how to do this inheritance in .NET with just a single method and two properties. Here is the simplified Animal class: Imports System.Drawing Imports System.Io Public Class Animal Private c_CommunicationSound As String = "Grunt" Private c_NumberOfLegs As Integer = 4 Public Overridable Function DrawSelf() As Bitmap Dim streamId As Stream = Me.GetType().Assembly.GetManifestResourceStream("OOP_NET.animal.gif") Dim bitmapId As Bitmap = New Bitmap(streamId) Return bitmapId End Function Public Overridable Property CommunicationSound() As String Get Return c_CommunicationSound End Get Set(ByVal value As String) c_CommunicationSound = value End Set End Property Public Overridable Property NumberOfLegs() As Integer Get Return c_NumberOfLegs End Get Set(ByVal value As Integer) c_NumberOfLegs = value End Set End Property End ClassSo the Animal class has a DrawSelf method and CommunicationSound and NumberOfLegs properties, all of which we explicitly set to be "overridable." We have embedded "animal.gif" right inside the DLL, which is why we need the "GetManifestResourceStream" code to reference it in the DrawSelf method. To inherit from this class, we use the code below. Imports System.Drawing Imports System.Io Public Class Cat Inherits Animal Private c_CommunicationSound As String = "Meow" Public Overrides Function DrawSelf() As Bitmap Dim streamId As Stream = Me.GetType().Assembly.GetManifestResourceStream("OOP_NET.cat.gif") Dim bitmapId As Bitmap = New Bitmap(streamId) Return bitmapId End Function Public Overrides Property CommunicationSound() As String Get Return c_CommunicationSound End Get Set(ByVal value As String) c_CommunicationSound = value End Set End Property End ClassWe use the Inherits keyword to show we are inheriting from Animal. We then override DrawSelf and CommunicationSound. Note that we don't override NumberOfLegs, which means that the "base" class (Animal) value will be used. |
Platte Canyon Products in the Pipeline
We are working on updating our TBK Tracker Learning Management System to work with native Training Studio or other Flash content. We are also getting ready to tackle Learning & Mastering ToolBook Assistant 9. |
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 |