|
|
黄 穗 (暨南大学 计算机科学系 ) (广州、邮码510632) 内容摘要: ToolBook 是美国Asymetrix公司推出的Windows 3.1与Windows 95多媒体应用开发工 具,它以易学易用、功能强大而深受广大应用开发者的喜爱。本文总结了作者用它 开发各种多媒体应用的经验,介绍几种实用功能的实现方法。 关键词:对象、脚本、消息、处理子 1、ToolBook使用简介 ToolBook 是Asymetrix公司推出的Windows 应用开发工具,其版本已经从较早时只 支持Windows 3.1的1.5版发展到目前同时支持Windows 3.1和Windows 95 的4.0版, 它所提供的可视化集成开发环境、近乎自然语言的面向对象编程语言OpenScript及 其强大的多媒体功能,既使是没有专业程序设计经验的普通计算机用户都能独立自 主地开发出诸如计算机辅助教学(CAI)、旅游指南、服务向导以及广告宣传等多媒体 应用程序。ToolBook的应用程序基本上采取传统的书架构,以页面为组织基础,通 过线性的和超媒体的有机结合将书编织成一个整体。开发ToolBook应用的基本步骤 是: 第一、理解ToolBook的基本概念和消息驱动机制,如对象、性质、事件、消息、脚 本、处理子等; 第二、在集成开发环境中利用拖-放功能,从工具条中选择需要的对象建立页面内 容,确定各对象的性质和相互位置,输入资料(如文字说明、图片、声音文件、动 画、影像文件等); 第三、针对某些应具备特定功能的对象,如按钮、热字等,通过ToolBook的专门手 段或OpenScript编程实现功能。详细的使用方法可参考文献1。 2、几种实用功能的实现 2.1 书签功能 对于电子书一类的应用来说,读者往往希望记住每次阅读停止的位置,以便下次阅 读时能从上次停止的地方继续下去,书签功能就是实现这种记忆的功能。实现方 法:用一个字段(field)作为记存器,在进入应用消息(EnterBook)处理子中从记存 器中取出上次退出时的页面代码,在退出应用消息(LeaveBook)消息处理子中将当前 页面代码存入记存器中,每次进入应用时先询问读者是否要回到上次退出的地方, 然后根据回答决定进入应用后是否转到上次退出的页面,详细的程序清单见附录1。 另外有一个与此类似的功能,即"阅读历史",程序记住读者阅读的页面顺序,可以 随时倒退到前面读的页面,实现方法是建立一个记录阅读顺序的数组,在进入页面 (EnterPage)消息处理子中将页面代码存入数组,另外做一个历史回退按钮,每按一 次从数组中取出上一个页面的代码并转入相应的页面。 2.2 自动演示功能 对于导游、CAI等类的应用,当读者一段时间未做任何操作时,应用程序能够好象一 位导游一样给读者从头到尾展示整个应用的内容。实现方法:首先用键按下 (KeyDown)消息处理子判断有无按键操作,并设置空闲时间的记时起点,然后用空闲 (Idle)消息处理子设置转入自动演示的时间和演示方式,如果设定的时间到了还没 有键盘和鼠标操作,则启动自动演示操作,每隔2秒钟就翻到下一页面,逐页遍历整 个应用,如果演示过程中出现键盘或鼠标动作则立即回到原来的页面,程序清单见 附录2。 2.3 功能提示 在应用中往往有不少按钮或具备按钮功能的图片、图符等对象,当操作者仅凭按钮 上的字符仍不清楚其实际功能时,只要将鼠标指向该对象并停留片刻,在对象的下 面就会自动出现一个提示框,简要地说明该对象的功能。实现方案:首先对需要提 示功能的对象建立用户性质pophelptext,以存放要提示的内容,然后利用鼠标进入 对象(MouseEnter)消息处理子设置定时器,在定时(timerNotify)消息处理子中发出 显示消息(showText),最后由显示消息处理子完成功能提示;这样,当鼠标进入某 有提示内容(其popHelpText性质非空)对象时,只要停留时间超过预先设定的值,则 显示提示窗(用视窗Viewer实现)并在窗内显示提示内容,当鼠标移离对象时隐藏提 示窗。实现程序放在应用脚本(Book Script)中,此外程序还要自动处理提示框的位 置和大小,以便完整显示提示内容,程序清单及有关注解见附录3。 2.4 图片移动控制 在地图类应用中,经常会碰到尺寸很大的图片或者界面上用来展示图片的区域比较 小的问题,图形移动控制功能就是象移动显示窗口那样移动图片,以便观察到图片 的各个部分,使用时只需要将光标指向图片的八个位置(中上、中下、中左、中右、 左上、左下、右上、右下),显示窗口便自动向这八个方向移动,移动速度可调。实 现方案:当显示图片的窗口一打开,定时器就开始工作,每半秒钟发一个消息检查 当前鼠标与主窗口的相对位置,在显示图片的主窗口下有一个隐藏的矩形框,用它 确定坐标X,Y的范围,然后根据当前鼠标与展示窗口的相对位置,分别发出八个方 向的消息(如ScrollDown向下移动),在对应的消息处理子中移动图片。详细的程序 清单及有关注解见附录4。 3、结束语 ToolBook在目前众多的多媒体应用开发工具中,以其易学易用最为突出,它对开发 者的计算机专业知识要求较低,又提供了许多可以效仿甚至直接采用的样例,有利 于开发者提高兴趣进入角色,但是,更深入、更灵活地利用它的功能则不是普通用 户所能做到,因为这需要对各类对象的结构和消息传递机制有较清楚的了解,另一 方面,ToolBook的许多功能(尤其是多媒体功能)都要通过函数的调用去实现,如何 设置调用参数和根据函数返回值作相应的处理也不是一般用户所能轻易掌握的,所 以,只有不断地学习他人的经验、总结自己的实践,才能提高应用开发水平,开发 出功能更强大、操作更灵活的应用程序来。 参考文献 1、《多媒体应用开发工具ToolBook 3.0及其应用》黄 穗、 蔡成滇 《电脑开发与应用》第8卷 增刊2 P19-22 2、《OpenScript Reference Manual》By Asymetrix Corporation 3、《ToolBook User Manual》By Asymetrix Corporation 附录1:书签功能 进入应用的处理子: to handle enterBook system pNum set pNum to text of field "pagename" of page 1 用字段域存放页面 request "回到上次离开的那一页吗 ?"with Yes or No conditions when It is "Yes" go to page pNum when It is "No" go to page 1 end conditions 离开应用的处理子: to handle leaveBook system pNum clear text of field "pagename" of page 1 put pNum into text of field "pagename" of page 1 end leaveBook 附录2:自动演示 按键处理子: to handle KeyDown --检测是否有键按下 system CanTime CanTime=False end KeyDown 空闲时间处理子: to handle Idle system OldX,OldY,NewX,NewY,bool system CanTime,TimeCount,CurrentPageNum system GoFlag get mousePosition of this window NewX=Item 1 of it NewY=Item 2 of it If (OldX <>NewX) or (OldY <>NewY) --鼠标位置有无变化 CanTime=False systemTimeFormat="sec" Get systime If CanTimer If It-TimeCount=10 --设置时间段 GoFlag=true end if If GoFlag=true If CurrentPageNum=null set CurrentPageNum to PageNumber of this page end if bool=true go next page pause 2 seconds end if else If CurrentPageNum <>null bool=true go page CurrentPageNum end if GoFlag=False set CurrentPageNum to null TimeCount=It end if CanTimer=true OldX=NewX OldY=NewY end Idle 附录3:功能提示 鼠标离开处理子: to handle mouseLeave system popHelpTimer if popHelpTimer is not null then get timerStop(popHelpTimer) --关闭定时器 clear popHelpTimer end if if isOpen of viewer "poptext" hide viewer "popText" --隐藏提示窗 end end mouseLeave 鼠标进入处理子: to handle mouseEnter system popHelpTimer, currentObj, s_targetWindow system logical popHelp local oldCursor,temp, temp1,OldSysSuspend s_targetWindow = this window currentObj = target --置当前对象 temp1 = " " popHelp = true if sysLevel = reader temp = name of target notifyObj = "this book" --消息通知对象为本应用 popHelpTimer = timerStart("single",500,100,notifyObj) end end mouseEnter 定时器通知处理子: to handle timerNotify timerID system DEHomeBook,popHelpTimer,pophelp,currentObj,s_targetWindow CONDITIONS when timerID = popHelpTimer if popHelpText of currentObj <> null get flushMessageQueue() --删除鼠标和键盘消息 send showText to currentObj --将showText消息送当前对象 end if end CONDITIONS end timerNotify 显示提示处理子: to handle showText system EXEbook,s_targetWindow, DEHomeBook linkDLL "tb40win.dll" STRING clientFromPage(STRING,INT,STRING) --转换坐标 STRING screenFromPage(WORD,STRING,INT,STRING) INT popText(STRING,STRING,STRING) INT horizontalDisplayRes() INT verticalDisplayRes() end sysLockScreen = true if enabled of target is false newText = pophelpText of target && "(disabled)" else newText = pophelpText of target --目标的提示内容 end if set text of field "showText" of page "PopHelp" to newText if not visible of viewer "popText" show viewer "popText" as notActive send upDateDisplay to page "popHelp" end maxXCoord = horizontalDisplayRes() -- 以象素为单位 maxYCoord = verticalDisplayRes() -- 以象素为单位 popHelpWidth = item 1 of size of viewer "poptext" -- 以象素为单位 popHelpHeight = item 2 of size of viewer "poptext"-- 以象素为单位 --确定目标的象素值大小 targetBounds = pageUnitsToScreen(bounds of target,s_targetWindow) leftCorner = item 1 of targetBounds,item 2 of targetBounds targetSize = (item 3 of targetBounds - item 1 of targetBounds),(item 4 of targetBounds) - (item 2 of targetBounds) targetWidth = item 1 of targetSize targetHeight = item 2 of targetSize xPos = item 1 of leftCorner + (round(targetWidth/2)) --this indents the popup if room is available --如果主窗口的右边界已移出荧幕,将提示窗靠右以便提示内容能看得见。 if item 1 of leftCorner < 0 xPos = xPos + round(abs(item 1 of leftcorner)/2) end if YPos = item 2 of leftCorner + targetHeight + 2 --places popup below target; extra 2 pixels --防止鼠标进入提示窗内 combinedXPos = xPos + popHelpWidth if combinedXpos > maxXCoord offsetX = combinedXPos - maxXCoord xPos = xPos - offsetX end if combinedYPos = yPos + popHelpHeight if combinedYPos > maxYCoord yPos = yPos - targetHeight -popHelpHeight -2 end if --提示的父窗 = s_targetWindow position of viewer "Poptext" = xPos,yPos syslockscreen = false pophelp = true end showText 附录4、图片移动 进入图片页面处理子: to handle enterPage system mPosTimer send setConditions systimeFormat = "seconds" mPosTimer = timerStart("periodic",500,10,self) end enterPage 定时器通知处理子: to handle timerNotify timerID system mPosTimer if timerID = mPosTimer send checkMousePos else --非法定时值,关闭定时器 get timerStop(timerID) end if end timerNotify --检查鼠标位置,确定图片滚动值 检查鼠标位置处理子: to handle checkMousePos system topLeftx1,topLeftx2,topLefty1,topLefty2, \ topRightx1,topRightx2,topRighty1,topRighty2, \ bottomLeftx1,bottomLeftx2,bottomLefty1,bottomLefty2, \ bottomRightx1,bottomRightx2,bottomRighty1,BottomRighty2, \ midLeftx1,midLeftx2,midLefty1,midLefty2,\ midRightx1,midRightx2,midRighty1,midRighty2, \ upx1,upx2,upy1,upy2,\ downx1,downx2,downy1,downy2,scrollAmount,baseHeight,viewersize if scrollAmount is null;send fixScrollAmount;end if get mousePosition of viewer id 0 x = item 1 of it y = item 2 of it if x < topLeftx1 or x > topRightx2 or y < 0 or y > bottomLefty2; break checkMousePos;end if -- 设置 x , y 和系统时间 conditions when x < topLeftx2 and y < topLefty2 send scrollLeftUp when x > topRightx1 and y < topRighty2 send scrollRightUp when x < midLeftx2 and y > topLefty2 and y < midLefty2 send scrollLeft when x > midRightx1 and y > topRighty2 and y < midRighty2 send scrollRight when x < bottomLeftx2 and y > midLefty2 send scrollLeftDown when x > bottomRightx1 and y > midRighty2 send scrollRightDown when x > topLeftx2 and x < topRightx1 and y < baseHeight send scrollUp when x > bottomLeftx2 and x < bottomRightx1 and y > (item 2 of viewerSize) -- 基本高度 send scrollDown end conditions end checkMousePos 左上移动处理子: to handle scrollLeftUp system scrollAmount if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psx = psx - scrollAmount psy = psy - scrollAmount if psx < 0 psx = 0 end if if psy < 0 psy = 0 end if pageScroll of viewer "map" = psx,psy end 右上移动处理子: to handle scrollRightUp system scrollAmount,pageScrollXmax if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psx = psx + scrollAmount psy = psy - scrollAmount if psx > pageScrollXmax psx = pageScrollXmax end if if psy < 0 psy = 0 end if pageScroll of viewer "map" = psx,psy end 向左移动处理子: to handle scrollLeft system scrollAmount if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psx = psx - scrollAmount if psx < 0 psx = 0 end if pageScroll of viewer "map" = psx,psy end 向右移动处理子: to handle scrollRight system scrollAmount,pageScrollXmax if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psx = psx + scrollAmount if psx > pageScrollXmax psx = pageScrollXmax end if pageScroll of viewer "map" = psx,psy end 左下移动处理子: to handle scrollLeftDown system scrollAmount,pageScrollYmax if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psx = psx - scrollAmount psy = psy + scrollAmount if psx < 0 psx = 0 end if if psy > pageScrollYmax psy = pageScrollYmax end if pageScroll of viewer "map" = psx,psy end 右下移动处理子: to handle scrollRightDown system scrollAmount,pageScrollXmax,pageScrollYmax if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psx = psx + scrollAmount psy = psy + scrollAmount if psx > pageScrollXmax psx = pageScrollXmax end if if psy > pageScrollYmax psy = pageScrollYmax end if pageScroll of viewer "map" = psx,psy end 向上移动处理子: to handle scrollUp system scrollAmount,pageScrollYmax if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psy = psy - scrollAmount if psy < 0 psy = 0 end if pageScroll of viewer "map" = psx,psy end 向下移动处理子: to handle scrollDown system scrollAmount,pageScrollYmax if scrollAmount is null;send fixScrollAmount;end if get pageScroll of viewer "map" psx = item 1 of it psy = item 2 of it psy = psy + scrollAmount if psy > pageScrollymax psy = pageScrollymax end if pageScroll of viewer "map" = psx,psy end 设置条件处理子: to handle setConditions system topLeftx1,topLeftx2,topLefty1,topLefty2, \ topRightx1,topRightx2,topRighty1,topRighty2, \ bottomLeftx1,bottomLeftx2,bottomLefty1,bottomLefty2, \ bottomRightx1,bottomRightx2,bottomRighty1,BottomRighty2, \ midLeftx1,midLeftx2,midLefty1,midLefty2,\ midRightx1,midRightx2,midRighty1,midRighty2, \ upx1,upx2,upy1,upy2,\ downx1,downx2,downy1,downy2,viewerSize,\ pageScrollXmax,pageScrollYmax,baseheight,baseWidth if scrollAmount is null;send fixScrollAmount;end if pageScrollXmax = 3472 pageScrollYmax = 2392 get position of rectangle "marker" of page "start" xOffset = item 1 of it yOffset = item 2 of it viewerSize = size of rectangle "marker" of page "start" baseWidth = 400 baseHeight = 400 topLeftx1 = 0 + xOffset topLeftx2 = baseWidth + xOffset topLefty1 = 0 + yOffset topLefty2 = baseHeight + yOffset toprightx1 = (item 1 of viewerSize) - baseWidth + xOffset toprightx2 = item 1 of viewerSize + xOffset toprighty1 = 0 + yOffset toprighty2 = baseHeight + yOffset bottomLeftx1 = 0 + xOffset bottomLeftx2 = baseWidth + xOffset bottomLefty1 = (item 2 of viewerSize) - baseHeight + yOffset bottomLefty2 = item 2 of viewerSize + yOffset bottomRightx1 = (item 1 of viewerSize) - baseWidth + xOffset bottomRightx2 = item 1 of viewerSize + xOffset bottomRighty1 = (item 2 of viewerSize) - baseHeight + yOffset bottomRighty2 = item 2 of viewerSize + yOffset midLeftx1 = 0 + xOffset midLeftx2 = baseWidth + xOffset midLefty1 = baseHeight + yOffset midLefty2 = (item 2 of viewerSize) - baseHeight + yOffset midRightx1 = (item 1 of viewerSize) - baseWidth + xOffset midRightx2 = item 1 of viewerSize + xOffset midRighty1 = baseHeight + yOffset midRighty2 = (item 2 of viewerSize) - baseHeight + yOffset upx1 = baseWidth + xOffset upx2 = (item 1 of viewersize) - baseWidth + xOffset upy1 = 0 + yOffset upy2 = baseHeight + yOffset downx1 = baseWidth + xOffset downx2 = (item 1 of viewersize) - baseWidth + xOffset downy1 = (item 2 of viewersize) - baseHeight + yOffset downy2 = item 2 of viewerSize + yOffset end 离开图片页面处理子: to handle leavePage system mPosTimer if mPosTimer <> null get timerStop(mPosTimer) clear mPosTimer end if forward end 移动速度处理子: to handle fixScrollAmount system scrollAmount scrollAmount = 100 end 另注:作者备有上述全部功能的实现样例(.tbk文件),运行环境是Windows 95和 Multimedia ToolBook 4.0 。有兴趣者可来信联系索取。作者 e-mail 地址: [email protected] |