Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Text /
Chapter 7 - Text Services Manager / Using the Text Services Manager (for Text Service Components)


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:

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.
To send Apple events to a client application, your text service component calls 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 the NewServiceWindow 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 the FindServiceWindow function. Your text service component can close the floating window you originally allocated by using the CloseServiceWindow function.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
6 JUL 1996