Introduction 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). Dates June 16 - 18, 2008 Preconference Training June 14 - 15, 2008 Rates (All Options Include Three Meals Per Day Plus Snacks)
Preconference Training
Registration Rates Sessions Faculty Preconference |
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:
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 = createAutoObject("Word.Application") err = ASYM_RestoreSuspend(bs) if err <> NULL OR wordObject = NULL request "Can't open Word" break end bs = ASYM_BlockSuspend() emptyDoc = extAdd() of extDocuments of wordObject err = ASYM_RestoreSuspend(bs) if err <> NULL OR emptyDoc = NULL request "Can't create a new document" get closeAutoObject(wordObject) break end bs = ASYM_BlockSuspend() get extSaveAs(fName) of emptyDoc err = ASYM_RestoreSuspend(bs) if err <> NULL request "Error saving Word Document" get closeAutoObject(wordObject) break end get extPaste() of extSelection of wordObject -- save and close the storyBoard file get extSave() of emptyDoc get extClose(0) of emptyDoc end -- Close the Automation Object to get closeAutoObject obj bs = ASYM_BlockSuspend() get extQuit(0) of obj get ASYM_RestoreSuspend(bs) return null end |
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] LMSCommit(); LMSFinish(); |
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 Else 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 trueThere 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 showP1Notice 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 TrainingStudioSupport.as 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) { objectId.setStyle("fontSize",fontSize); if (isBold == true) { objectId.setStyle("fontWeight","bold"); } } } }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)) Else listId.Add(String.Format("{0}{1}{2}{1}{3}", FormatRelativePath(dirName, _ fileName), ControlChars.Tab, fileInfoId.LastWriteTime.ToShortDateString, _ fileInfoId.LastWriteTime.ToShortTimeString)) End If End If Next ' 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 Next 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 FunctionWe 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 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 |