Important: The information in this document is obsolete and should not be used for new development.
Making Calls
Your text service component needs to make two kinds of calls to the Text Services Manager: calls that cause the sending of an Apple event to a client application, and calls that request a floating window from the Text Services Manager.Sending Apple Events to Client Applications
Apple events allow text service components to send information to and request specific services of client applications. It is the responsibility of the client application to install Apple event handlers for these Apple events. Using these events, the text service component controls the text services environment by requesting a variety of services from the client application.Your text service component can send Apple events to request that a client application perform the following actions:
- create or update text in an active input area
- help you track cursor movements by converting global coordinates to the byte offset of characters in the active input area
- help you position items on the screen by converting the byte offset of characters in the active input area to global coordinates
- show or hide a floating input window
To send Apple events to a client application, your text service component calls the Text Services Manager
- Note
- Your text service component must always use the
kCurrentProcess
constant as the target address when it creates an Apple event to send to the Text Services Manager.SendAEFromTSMComponent
function. The Text Services Manager then completes the Apple event and sends it to the application. For general information on constructing and sending Apple events, see the discussion of the Apple Event Manager in Inside Macintosh: Interapplication Communication.Listing 7-11 shows an example of a text service component preparing and sending an Update Active Input Area Apple event. The component creates the Apple event and constructs the required parameters, including the text to be sent to the application. It also constructs the optional parameters that specify highlighting and update ranges in the text. It then calls
SendAEFromTSMComponent
to send the Apple event. In this listing,globalHandle
is a handle to a data structure in which the text service component maintains all information about the text in the active input area.Listing 7-11 Constructing and sending an Update Active Input Area Apple event
FUNCTION MyCreateUpdateInlineAreaAE(globalHandle: TglobalHandle) : OSErr; VAR psnRecord: ProcessSerialNumber; myErr: OSErr; addrDescriptor: AEAddressDesc; theAEvent: AppleEvent; theReply: AppleEvent; slRecord: ScriptLanguageRecord; theRangeTableSize: LongInt; theTextData: Handle; theUpdateRangeTable: TextRangeArray; theHiliteRangeTable: TextRangeArray; BEGIN {Apple event must go to the current process } psnRecord.highLongOfPSN := 0; psnRecord.lowLongOfPSN := kCurrentProcess; myErr := AECreateDesc(typeProcessSerialNumber, @psnRecord, sizeof(psnRecord), addrDescriptor); IF myErr <> noErr THEN BEGIN MyCreateUpdateInlineAreaAE := myErr; Exit(MyCreateUpdateInlineAreaAE); END; {create the Apple event record} myErr := AECreateAppleEvent(kTextServiceClass, kUpdateActiveInputArea, addrDescriptor, kAutoGenerateReturnID, kAnyTransactionID, theAEvent); IF myErr <> noErr THEN BEGIN MyCreateUpdateInlineAreaAE := myErr; myErr := AEDisposeDesc(addrDescriptor); {ignore the error} Exit(MyCreateUpdateInlineAreaAE); END; {construct the required parameter keyAEServerInstance-- } { globalHandle^^.fSelf = global containing component instance} myErr := AEPutParamPtr(theAEvent, keyAEServerInstance, typeComponentInstance, @globalHandle^^.fSelf, sizeof(ComponentInstance)); IF myErr = noErr THEN BEGIN {construct required parameter keyAEScriptTag } { --Korean in this case} slRecord.fScript := smKorean; slRecord.fLanguage := langKorean; myErr := AEPutParamPtr(theAEvent, keyAEScriptTag, typeIntlWritingCode, @slRecord, sizeof(slRecord)); END; IF myErr = noErr THEN BEGIN {construct required parameter keyAETheData. globalHandle } { is a handle to component's data structure describing } { all text in the active inline area} theTextData := globalHandle^^.fTextData; HLock(theTextData); myErr := AEPutParamPtr(theAEvent, keyAETheData, typeChar, theTextData^, globalHandle^^.fTextDataLength); HUnlock(theTextData); END; IF myErr = noErr THEN {construct the required parameter keyAEFixLength} myErr := AEPutParamPtr(theAEvent, keyAEFixLength, typeInteger, @globalHandle^^.fFixedLength, sizeof(LongInt)); IF myErr = noErr THEN BEGIN {construct the optional parameter UpdateRangeTable} theUpdateRangeTable := globalHandle^^.fUpdateRangeTable; theRangeTableSize := sizeof(TextRangeArray) + theUpdateRangeTable.fNumOfRanges * sizeof(TextRange); myErr := AEPutParamPtr(theAEvent, keyAEFixLength, typeInteger, @theUpdateRangeTable, theRangeTableSize); END; IF myErr = noErr THEN BEGIN {construct the optional parameter HiliteRangeTable} theHiliteRangeTable := globalHandle^^.fHiliteRangeTable; theRangeTableSize := sizeof(TextRangeArray) + theHiliteRangeTable.fNumOfRanges * sizeof(TextRange); myErr := AEPutParamPtr(theAEvent, keyAEFixLength, typeInteger, @theHiliteRangeTable, theRangeTableSize) END; IF myErr <> noErr THEN BEGIN MyCreateUpdateInlineAreaAE := myErr; myErr := AEDisposeDesc(theAEvent); {ignore the errors} myErr := AEDisposeDesc(addrDescriptor); Exit(MyCreateUpdateInlineAreaAE); END; {send the Apple event} myErr := SendAEFromTSMComponent(theAEvent, theReply, kAEWaitReply + kAENeverInteract, kAENormalPriority, 120, NIL, NIL); MyCreateUpdateInlineAreaAE := myErr; myErr := AEDisposeDesc(theAEvent); {ignore the errors} myErr := AEDisposeDesc(addrDescriptor); myErr := AEDisposeDesc(theReply); END;Opening Floating Utility Windows
To open a floating utility window in front of the current client application, you use theNewServiceWindow
function. If the call is successful,NewServiceWindow
allocates a floating window in the floating window service layer, and returns a pointer to the window. See "Floating Input Windows" on page 7-13 and "Floating Utility Windows" on page 7-14 for a discussion of the Text Services Manager floating window service and the floating window service layer.Your text service component can open multiple floating windows. When your component receives an event, you must determine if the event belongs to one of your text service floating windows. To get a pointer to the frontmost window in the floating window service layer, call the
GetFrontServiceWindow
function. To find out which part of your floating window an event occurred in, call theFindServiceWindow
function. Your text service component can close the floating window you originally allocated by using theCloseServiceWindow
function.