Tải bản đầy đủ - 0 (trang)
Chapter 11. Scripting and Extending REALbasic

Chapter 11. Scripting and Extending REALbasic

Tải bản đầy đủ - 0trang

Scripting

IfyouarerunningyourapplicationonaMacintosh,youcanuse

AppleScripttomakeyourapplicationscriptable,butthatwill

workonlyforwhenyou'rerunningitonaMacintosh.REALbasic

providesacross-platformsolutiontotheproblemwiththe

RBScriptclass.



RBScript

RBScriptisasubsetoftheREALbasicprogramminglanguage.It

retainsmostofthefeaturesofthelanguageitself,withafew

limitationsthemostnotableisthatmanyoftheglobalfunctions

thatareavailabletoyouwhenwritingREALbasiccodeinthe

IDEwillnotbeavailabletoyouwhenwritingascript.For

instance,MsgBoxcannotbecalledfromRBScript.TheLanguage

Referenceprovidesadetailedlistofavailablefunctions,soIwill

notrepeatthatinformationhere.



RBScriptObject

TheRBScriptlanguageisafairlycompleteimplementationof

REALbasic,andyoucandoquitealotwithit.Itsupports

classes,interfaces,andmodules.Youcaninstantiatethe

RBScriptobjectincode,justlikeanyotherclass,oryoucan

dragitontoaWindowlikeaControl.Eitherway,afterthe

objectisavailable,youthenneedtosetitupsothatyourusers

canuseittoscriptyourapplication.

AsImentionedearlier,onethingthatisnotavailableto

RBScriptissomeglobalfunctions.Thislimitationisagoodone

becausethepurposeofRBScriptistoprovideascripting

interfacetoyourapplication.Asadeveloper,youwillwant



controloverwhichpartsofyourapplicationareaccessibleby

RBScript,andyoudothisbyassigninganobjecttothe

RBScript.Contextproperty:

RBScript.ContextasObject



TheobjectthatyouassigntotheContextshouldbeonethat

providesthescriptwiththefunctionsyouwantyourusersto

havecontrolover.Forstarters,supposeyouwanttheuserto

accesstheSystemRBScript.Contextpropertyobjectthrough

RBScript.It'saseasyasthefollowing:

RBScript1.Context=System



Now,ifinyourcodeyoutrytoaccesstheSystemobject

directly,you'llbeinforasurprise,becauseitwon'twork.You

canaccessitbyworkingdirectlywiththeContextobject,but

REALbasicprovidesaneasierwaybecauseallthemembersof

theSystemobjectwillbeavailabletoyourscriptasglobal

methodsandproperties.Ifyouwanttocheckthevalueforan

environmentvariable,youcandothefollowing:

DimsasString

s=EnvironmentVariable("PATH"RBScript.Contextproperty)



Torunascript,youneedtoassignthesourcecodeofthescript

totheSourcepropertyofRBScript:

RBScript.SourceasString



Priortoexecutingthescript,youshouldcheckthecurrentstate

oftheRBScriptobjecttoseeifitisreadytoexecuteanew

script,whetheritisalreadyrunning,completed,orifthe

executionofthescripthasbeenabortedinsomeway:

RBScript.StateasInteger



LegalvaluesforRBScript.Stateare

0=Ready

1=Running

2=Complete

3=Aborted



TherewasatimewhenRBScriptwasaninterpreter,which

meantthatthescriptsthemselveswereneverdirectlycompiled

intomachinecode.Thatisnolongerthecase.One

consequenceofthis(besidesmuchbetterperformance)isthat

thefollowingpropertydoesn'tworkanymoreifyouareusinga

currentversionofREALbasic:

RBScript.CurrentLineNumberasInteger(Deprecated)



Becausethescriptisastring,itsometimesneedstouse

charactersfromlanguages,suchasJapanese,thatrequire2

bytestorepresent.

RBScript.EncodingFontasString



Nowthatscriptsarenolongerrunthroughtheinterpreter,they



getcompiledintonativeapplicationcode.Yourunascriptby

callingtheRunmethod:

RBScript.Run()



Atthattime,thescriptwillbecompiledandexecuted.Youhave

theoption,however,ofcompilingthescriptatsomearbitrary

pointpriortorunningit,andforthatyoucallthefollowing

method:

RBScript.Precompile()



Youarealsogivetheoptionofrunningthescriptforonlya

certainnumberofseconds,usingPartialRun:

RBScript.PartialRun(millisecasInteger)



Youwoulddothistoyieldtimebacktotheapplication.

Afterascriptisfinishedrunning,thevalueforRBscript.Stateis2,

whichmeansthescripthascompletedexecution.Ifyouwantto

runthescriptagain,youmustresetitusingtheResetmethod:

RBScript.Reset()



Theinterestingpartofallthisislinkingthescripttoyour

application.AsIalreadymentioned,youcanassignanobjectto

theContentpropertyandyourscriptwillbeabletoaccessthe

propertiesandmethodsglobally.Thatinitselfisenoughtoget

somethingdonethat'smeaningful,butREALbasicprovides



anotherwayofinteractingwiththescriptthroughtheuseof

twoeventsintheRBScriptclass:

RBScript.Input(promptasString)asStringHandlesEvent

RBScript.Print(msgasString)HandlesEvent



Mostprogramsacceptsomekindofinputandproducesome

kindofoutput.RBScriptusestheInputandPrinteventsasa

meansofgettingadditionalinputduringtheexecutionofthe

scriptandofoutputtingdataduringtheexecutionofthescript.

InputandPrintarebotheventsthatyourscriptcanraiseatany

timeduringtherunningofthescript.Youusebothofthemasif

theyweremethods,likethis:

DimsasString

s=Input("Pleasegivemeinput.")



Whenthiscoupletofcodegetsexecuted,theInputeventis

triggered,andifyouhaveimplementedthatevent,thecodein

thatimplementationgetspassedthe"Pleasegivemeinput."

string,doessomeprocessingbasedonthat,andthenreturnsa

stringofsomesortbacktothescript.Here'sonepossibleway

toimplementtheInputevent:

RBScript1.Input(PromptasString)asString

DimresultasInteger

result=MsgBox(Prompt,3)

Ifresult=6Then

//6signifies"Yes"button

Return"Yes!"

Else

Return"No."



EndIf



Withinthebodyofyourscript,youdonothaveaccesstoMsgBox,

soyoucannotcallitfromthere.BecausetheInputeventis

implementedinREALbasiccode,notusingRBScript,youhave

accesstoeverythingyounormallyhaveaccessto.Inthis

instance,myscriptasksforinput,triggerstheInputevent,and

theInputeventhandlesgettingthatinputfromtheuserinsome

way.

ThePrinteventworksinasimilarway,butbysendingoutput.

Again,it'saneventthatgetscalledincodewhenandhowyou

wantto.Youpassastringtotheeventandyouimplementthe

PrinteventtodosomethingwiththatString.Youmaydisplay

theoutputtotheuser,youmayuseittoassignavaluetoa

propertyelsewhereinyourapplication,oryoumayexecutea

blockofcodebasedonthecontentofthestring.

Therearealsotwoerror-relatedevents,eachforadifferent

kindoferror.Ifthereisanerrorinyourcodethatkeepsitfrom

beingcompiledproperly,aCompilerErroreventistriggered:



RBScript.CompilerError(lineasInteger,errorNumberasInteger,

errorMsgasString)HandlesEvent



Ifanyotherkindoferroroccurs,thiseventistriggered:



RBScript.RuntimeError(lineasInteger,errorasRuntimeExceptio



TheLanguageReferenceprovidesacompletelistofcompiler

errorswiththeirexplanations.Italsodocumentswhichglobal

functionsandlanguageelementsareavailableinthescripting



environment.



WebServerScripting

Supposeyouwanttoaddascriptingcapabilityforyourweb

serversothateveryfilethatendsin.rsisexecutedasa

REALbasicscript.Theprocessfordoingthisissimple.Thefirst

stepistoidentifyrequestsforfilesthatendin.rsandthen

assignthemtotheSourcepropertyofanRBScriptobject.

Afterthat,thescriptshouldbeexecutedandtheresults

returnedtotheuser.Thisiswherethingsgetalittletricky.

RBScriptisexecutedasynchronously,whichcanbeaproblem

becausetheTCPSocketclassthattheHTTPServerclassis

builtonisasynchronousaswell.Whentherequestcomesin,

youwillwanttomaintaintheconnectiontotheclientfrom

withintheDataAvailableeventandthenprocessthescriptand

returntheresults.IntheHTTPServerexample,Iplacedallthe

WritemethodswithintheDataAvailableevent.IfIdidn'tdothat,a

newrequestcouldcomethroughandgenerateanew

DataAvailableeventwhileIwasstillprocessingthedatafromthe

previousrequest.Ineedtobeabletocallandexecutethe

scriptandgettheresultspriortoexitingtheDataAvailableevent,

andIcandoitthisway:

WhileTrue

IfRBScript1.Results=""Then

//loop

Else

WriteRBScript1.Results

EndIf

Wend



IcreateaclasstoserveastheContextobjectforthescript,



somethingwhichcouldeasilybeanHTTPRequestobjectwith

aResultproperty,whichiswheretheoutputofthescriptwillbe

assignedinthePrintevent:

Print(msgasString)

Results=msg



ThecodeintheDataAvailableeventwillloopwhileitwaitsforthe

Resultspropertytobeassigned.Assoonasitisassigned,it

writesthedatabacktotheclient.Forthescripttowork

properly,allithastodoisgeneratetheHTMLitisgoingtosend

backtotheclient,andthenpassthatStringtothePrintevent.

You'llneedtoaddmoreerrorcheckingandthingslikethatfor

thistoworkreliably,butatleastyouarewellonyourwayto

havingimplementedascriptablewebserver.



OfficeAutomation

REALbasicsupportsMicrosoftOfficeautomationonboththe

WindowsandtheMacintoshplatforms.TheMacintosh

implementationissomewhatmorelimited;themostobvious

distinctionisthatyouhavetoexecuteyourREALbasic

applicationfromwithinthesamefolderastheOfficeapplication

youareautomating.Theexamplesinthissectionwere

developedonWindowsbecausethisisthemostlikelyplacethat

youwillbeusingit.

Thebiggestchallengetousingtheseclassesisthattheyarenot

documented.REALbasicprovidessomesupportingclasses,plus

somecodecompletionsupportforOfficeautomation,butdon't

makethemistakeofbelievingthattheabsenceofcode

completionindicatesalackofsupport.Checkthe

documentationavailableinWord,PowerPoint,orExceltofind

outtheproperties,methods,andeventsthatareapplicableto



anygivenobject.

ControlscanbedraggedontoaWindowWordApplication,

PowerpointApplication,andExcelApplication,allofwhich

aresubclassesofOLEObject.Theyaren'ttruecontrols,

becausetheyarenotasubclassofRectControlandtheycan

beinstantiatedinthenormalwaywiththeNewoperator.All

theseclassesaresubclassesofOLEObject,whichiswhereI

willturnfirst.



OLEObject

InWindowsterminology,OLEstandsforobjectlinkingand

embedding.Itwasoriginallydesignedsothatyoucouldembed

oneapplicationintoanother.Inotherwords,youcouldembed

anExcelspreadsheetinthemiddleofaWorddocument.This

basictechnologyhasevolvedovertheyearsanditisnowpart

ofabroaderComponentObjectModel(calledCOM).Iwon'tget

intotoomuchdetailaboutCOM,butthereareafewthingsto

beawareofthatwillhelpyouunderstandwhat'sgoingoninthe

background.

Componentsaredistributed.Theyarepiecesofcode(muchlike

asharedlibrary)thatotherapplicationscanexecute.Each

componenthasauniqueIDthatislistedintheWindows

Registry.Ifyouwantyourapplicationtouseaparticular

component,youneedtohavethatuniqueID.ThereisaCOM

serverthatwillreturnareferencetothecomponentthatyour

applicationcanuse.

ThemostcommonlyusedcomponentsareActiveXcomponents,

manyofwhicharecontrols.Infact,thereisanOLEContainer

ControlinREALbasicthatcanbeusedtoincludeActiveX

controlsinyourapplication.TheCOMserverdoesotherthings,

too.Forinstance,itcontrolshowmanyinstancesofthe

componentareinmemory.



WhenautomatingOfficeapplications,youwillbeusingthe

OLEObjectclass,orasubclassofOLEObjectthroughout.An

OLEObjectisacomponent,whichmeansitissomething

managedbyaCOMserverandaccessiblethroughtheWindows

Registry.Therearethreesubclassesofmostimportance:

WordApplication,PowerpointApplication,and

ExcelApplication,eachofwhichisaclassthatrepresentsthe

respectiveOfficeapplication.Thesearenottheonly

OLEObjectsyouwillencounter,however,becausethereare

manyothers,someofwhichyou'llseemomentarily.

BecauseOLEObjectsarecomponents,allhaveaglobally

uniqueidentifierassignedtothem,andtheyarereferencedby

thisnumberinternally.Thenumberneedstobeuniquebecause

youcannotalwayspredictwhatotherOLEObjectsaregoingto

beavailableonasystem,andyouwanttobeabletoavoid

namespaceproblems.TherearetwoConstructors,oneofwhich

takestheuniqueidentifierasanargument(referredtoas

ProgramIDinthedocumentation).Thesecondalsotakesthe

identifier,butalsospecifieswhethertocreateanewinstanceof

theobject,ratherthanusinganexistinginstance.Behindthe

scenes,REALbasicisgettingareferencetothecomponentfrom

theCOMserver,whichiswhyyouneedtoletitknowwhether

tocreateanewinstanceortouseanexistinginstanceifoneis

alreadyavailable.



OLEObject.OLEObject(ProgramIDasString)

OLEObject.OLEObject(ProgramIDasString,NewInstanceasBoolean



Likeallobjects,OLEObjectshaveproperties,methods,and

events.BecauseOLEObjectisagenericrepresentationofa

particularOLEObject,italsohastoprovidesomegeneric

methodsforgettingandsettingproperties,executingmethods,

andsoon.Tosetaproperty,youusethefollowingmethod:



OLEObject.Value(PropertyNameasString,ByValueasBoolean)as



YoucanfindoutwhattypeofOLEObjectitis,usingthe

following:

OLEObject.TypeNameasString



Functionsareaccessiblebyname.Thefollowingtwomethods

provideawaytoexecutefunctions:



OLEObject.Invoke(NameOfFunctionasString)asVariant

OLEObject.Invoke(NameOfFunctionasString,Parameters()asVari



Thefirstfunctionrequiresonlythefunctionname,whereasthe

secondoneletsyoupassalongtheparametersaswell.Ifyou

passparameters,youwillneedtoknowwhichordertoplace

themintothearray,becausetheyaredeterminedbyposition.



OLEParameter

VisualBasicsupportsoptionalparameters,whichinpractice

worklikepolymorphism.InREALbasic,youcanhaveasingle

methodwithmultiplesignaturesutilizingdifferentparameters.

TohandleoptionalparametersinREALbasicinawaythat's

compatiblewiththeVBAimplementations,youneedtousethe

OLEParameterclass.Lateronintheexamples,youwillsee

exactlyhowtheOLEParameterclassishandled.

OLEParameter.PassByRefasBoolean

OLEParameter.PositionasInteger



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 11. Scripting and Extending REALbasic

Tải bản đầy đủ ngay(0 tr)

×