home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / APLocation / Sources / APLocation.cpp next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  18.1 KB  |  718 lines

  1. /*==================================================================
  2.     File:        APLocation.cpp
  3.     
  4.     Contains:    An AirPort Location Manager module.
  5.  
  6.     Written by:    Ned Holbrook and Eric Gundrum
  7.     
  8.     Copyright:    None
  9. ==================================================================*/
  10.  
  11. /*
  12.      File:        Sample.c
  13.  
  14.      Contains:    Location Manager SDK Sample main code...
  15.  
  16.      Version:    ALM SDK 2.0
  17.                  Package:    Location Manager SDK 2.0
  18.  
  19.      Copyright:    © 1996-1997 by Apple Computer, Inc.
  20.                  All rights reserved.
  21.  
  22.      Bugs?:        Please include the the file and version information (from above) with
  23.                  the problem description.  Developers belonging to one of the Apple
  24.                  developer programs can submit bug reports to:
  25.  
  26.                      devsupport@apple.com
  27.  
  28. */
  29.  
  30. // ------------------------------------------------------------------------------------------------- 
  31.  
  32. #include    <ConditionalMacros.h>
  33.  
  34. // We recommend using the most updated headers currently available; at this writing, that is
  35. // Universal Headers 3.0.1.  More recent editions should work as well; if you want to use older
  36. // headers for some reason, it should be possible, but you're on your own and other parts of this
  37. // sample may need to change...
  38.  
  39. #if        !defined (UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0301)
  40.  
  41.     #error    "Please use header files 3.0.1 or newer"
  42.  
  43. #endif    // updated headers...
  44.  
  45. // Having gotten _that_ out of the way, let's be sure that nobody fiddled with the project
  46. // settings by accident...
  47.  
  48. #if            !TARGET_CPU_68K | TARGET_RT_MAC_CFM
  49.  
  50.     #error        This project MUST be classic 68K!
  51.  
  52. #endif        // not 68K classic build
  53.  
  54. // ------------------------------------------------------------------------------------------------- 
  55.  
  56. // Module Include...
  57.  
  58. #include    "APLocation.h"
  59.  
  60. // Project Includes...
  61.  
  62. #include    "Utilities.h"
  63.  
  64. #include "MacOS_UMemory.h"
  65.  
  66. // MacOS Includes...
  67.  
  68. #define        ALM_BASENAME()
  69. #define        ALM_GLOBALS()        GlobalsHandle
  70.  
  71. #include    <Components.h>
  72. #include    <Fonts.h>
  73. #include    <LocationManager.k.h>
  74. #include    <PLStringFuncs.h>
  75. #include    <Resources.h>
  76. #include    <TextUtils.h>
  77.  
  78. // ------------------------------------------------------------------------------------------------- 
  79.  
  80. // Readability Constants...
  81.  
  82. #define        kInvalidFunction            ((ComponentFunctionUPP) -1)
  83.  
  84. #define        kAllocateMemory                NULL
  85. #define        kPlaceInFront                (WindowPtr)-1
  86.  
  87. #define        kUseStandardFilterProc        NULL
  88.  
  89. // ------------------------------------------------------------------------------------------------- 
  90.  
  91. // Local prototypes...
  92.  
  93. static Boolean
  94. CallSupported (SInt16 selector);
  95.     // Return true if the specified selector code is one this module supports...
  96. static ComponentResult
  97. HandleComponentManagerCall (ComponentParameters* params, SInt16 selector);
  98.     // Dispatch a component manager call (selector < 0)...
  99. static ComponentResult
  100. HandleLocationManagerCall (ComponentParameters* params, SInt16 selector, 
  101.         Handle globals);
  102.     // Dispatch a Location Manager specific call...
  103.  
  104. // Component prototypes...
  105.  
  106. static pascal ComponentResult
  107. Open (ComponentInstance self);
  108.     // Initialize the modules's global variables, etc...
  109. static pascal ComponentResult 
  110. Close (ComponentInstance self);
  111.     // Deinitialize the modules's global variables...
  112.  
  113. // ------------------------------------------------------------------------------------------------- 
  114.  
  115. /*------------------------------------------------------------------
  116.     main
  117.     
  118.     Main entry point as expected by Component Manager. We dispatch
  119.     the calls from here. Also, for ALM calls we'll make sure the
  120.     current resource fork is ours.
  121. ------------------------------------------------------------------*/
  122.  
  123. pascal ComponentResult
  124. main(
  125.     ComponentParameters *    params,
  126.     Handle                    storage)
  127. {
  128.     ComponentResult            result;
  129.     SInt16                    selector     = params->what;
  130.     SInt16                    svResFile    = CurResFile ();
  131.  
  132.     if (selector < 0)
  133.     {
  134.         // Component manager request codes are negative...
  135.         result = HandleComponentManagerCall(params, selector);
  136.     }
  137.     else
  138.     {
  139.         // ALM selectors...
  140.         if (storage != NULL)
  141.         {
  142.             UseResFile((**(GlobalsHandle) storage).resFile);
  143.         }
  144.         
  145.         result = HandleLocationManagerCall(params, selector, storage);
  146.     }
  147.             
  148.     UseResFile(svResFile);
  149.  
  150.     return result;
  151. }
  152.  
  153.  
  154. /*------------------------------------------------------------------
  155.     CallSupported
  156. ------------------------------------------------------------------*/
  157.  
  158. static Boolean
  159. CallSupported(
  160.     SInt16        selector)
  161. {
  162.     Boolean        response;
  163.  
  164.     switch (selector)
  165.     {
  166.         case kALMGetCurrentSelect:
  167.         case kALMSetCurrentSelect:
  168.         case kALMCompareSettingSelect:
  169.         case kALMDescribeSettingSelect:
  170.         case kALMDescribeErrorSelect:
  171.         case kALMEditSettingSelect:
  172.         case kALMGetInfoSelect:
  173.         case kALMImportExportSelect:
  174.         case kALMGetScriptInfoSelect:
  175.             response = true;
  176.             break;
  177.         
  178.         default:
  179.             response = false;
  180.             break;
  181.     }
  182.  
  183.     return response;
  184. }
  185.  
  186.  
  187. /*------------------------------------------------------------------
  188.     HandleComponentManagerCall
  189. ------------------------------------------------------------------*/
  190.  
  191. static ComponentResult
  192. HandleComponentManagerCall(
  193.     ComponentParameters *    params,
  194.     SInt16                    selector)
  195. {
  196.     ComponentResult            result     = (ComponentResult) noErr;
  197.     ComponentFunctionUPP     func     = NULL;
  198.     
  199.     switch (selector)
  200.     {
  201.         case kComponentOpenSelect:
  202.             func = (ComponentFunctionUPP) Open;
  203.             break;
  204.         case kComponentCloseSelect:
  205.             func = (ComponentFunctionUPP) Close;
  206.             break;
  207.         case kComponentCanDoSelect:
  208.             result = CallSupported (*(SInt16*) params->params);
  209.             break;
  210.         case kComponentVersionSelect:
  211.             result = kModuleVersion;
  212.             break;
  213.         case kComponentRegisterSelect:
  214.             result = false;            // false means "yes, please register me"    
  215.             break;
  216.         case kComponentTargetSelect :
  217.         case kComponentUnregisterSelect :
  218.             result = badComponentSelector;
  219.             break;
  220.     }
  221.     
  222.     if (func != NULL)
  223.     {
  224.         result = CallComponentFunction(params, func);
  225.         check(result == noErr);
  226.     }
  227.     
  228.     return result;
  229. }
  230.  
  231.  
  232. /*------------------------------------------------------------------
  233.     HandleLocationManagerCall
  234. ------------------------------------------------------------------*/
  235.  
  236. static ComponentResult
  237. HandleLocationManagerCall(
  238.     ComponentParameters *    params,
  239.     SInt16                    selector,
  240.     Handle                    globals)
  241. {
  242.     ComponentResult            result     = (ComponentResult) noErr;
  243.     ComponentFunctionUPP     func     = NULL;
  244.     
  245.     switch (selector)
  246.     {
  247.         case kALMGetCurrentSelect:
  248.             func = (ComponentFunctionUPP) GetCurrent;
  249.             break;
  250.         case kALMSetCurrentSelect:
  251.             func = (ComponentFunctionUPP) SetCurrent;
  252.             break;
  253.         case kALMCompareSettingSelect:
  254.             func = (ComponentFunctionUPP) CompareSetting;
  255.             break;
  256.         case kALMDescribeSettingSelect:
  257.             func = (ComponentFunctionUPP) DescribeSetting;
  258.             break;
  259.         case kALMDescribeErrorSelect:
  260.             func = (ComponentFunctionUPP) DescribeError;
  261.             break;
  262.         case kALMEditSettingSelect:
  263.             func = (ComponentFunctionUPP) EditSetting;
  264.             break;
  265.         case kALMGetInfoSelect:
  266.             func = (ComponentFunctionUPP) GetInfo;
  267.             break;
  268.         default:
  269.             func = kInvalidFunction;
  270.             break;
  271.     }
  272.     
  273.     if (func == kInvalidFunction)
  274.     {
  275.         result = badComponentSelector;
  276.     }
  277.     else if (func != NULL)
  278.     {
  279.         result = CallComponentFunctionWithStorage(globals, params, func);
  280.     }
  281.     
  282.     return result;
  283. }
  284.  
  285.  
  286. /*------------------------------------------------------------------
  287.     Open
  288. ------------------------------------------------------------------*/
  289.  
  290. static pascal ComponentResult
  291. Open(
  292.     ComponentInstance    self)
  293. {
  294.     // Keep the Open routine lightweight, and only fail in the case of dire
  295.     // emergencies that indicate a major problem; under ALM 2.0, you might wish to return an
  296.     // error here to quietly suppress your module from being usable--for example if you require
  297.     // Infrared hardware found only on some models of computer--but it is generally better to
  298.     // _succeed_ here and describe an _error_ from your GetCurrent call...
  299.  
  300.     OSErr                err        = noErr;
  301.     GlobalsHandle        globals    = (GlobalsHandle) NewHandle(sizeof(Globals));
  302.     
  303.     if (globals != NULL)
  304.     {
  305.         SetComponentInstanceStorage(self, reinterpret_cast<Handle>(globals));
  306.         
  307.         (**globals).self     = reinterpret_cast<Component>(self);
  308.         (**globals).resFile    = OpenComponentResFile(reinterpret_cast<Component>(self));
  309.         
  310.         err = ResError();
  311.     }
  312.     else
  313.     {
  314.         err = memFullErr;
  315.     }
  316.     
  317.     return (ComponentResult) err;
  318. }
  319.  
  320.  
  321. /*------------------------------------------------------------------
  322.     Close
  323. ------------------------------------------------------------------*/
  324.  
  325. static pascal ComponentResult
  326. Close(
  327.     ComponentInstance    self)
  328. {
  329.     OSErr                err        = noErr;
  330.     GlobalsHandle        globals    = (GlobalsHandle) GetComponentInstanceStorage(self);
  331.     
  332.     if (globals != NULL)
  333.     {
  334.         SInt16        resFile = (**globals).resFile;
  335.         
  336.         if (resFile > 0)
  337.         {
  338.             CloseComponentResFile(resFile);
  339.             (**globals).resFile = 0;
  340.         }
  341.         
  342.         DisposeHandle(reinterpret_cast<Handle>(globals));
  343.         SetComponentInstanceStorage(self, NULL);
  344.     }
  345.     
  346.     QuitAPScripting();
  347.     
  348.     return (ComponentResult) err;
  349. }
  350.  
  351.  
  352. /*------------------------------------------------------------------
  353.     GetCurrent
  354. ------------------------------------------------------------------*/
  355.  
  356. pascal ComponentResult
  357. GetCurrent(
  358.     GlobalsHandle    globals,
  359.     Handle            setting)
  360. {
  361.     OSErr    err = noErr;
  362.  
  363.     err = ReadSetting(globals, reinterpret_cast<APSettingHandle>(setting));
  364.     check(err == noErr);
  365.     
  366.     return (ComponentResult) err;
  367. }
  368.  
  369.  
  370. /*------------------------------------------------------------------
  371.     SetCurrent
  372. ------------------------------------------------------------------*/
  373.  
  374. pascal ComponentResult
  375. SetCurrent(
  376.     GlobalsHandle        globals,
  377.     Handle                setting,
  378.     ALMRebootFlags *    flags)
  379. {
  380.     OSErr                err                = noErr;
  381.     Handle                tempSetting        = NewHandle(1);
  382.     StHandleDisposer    dispose(tempSetting);
  383.  
  384.     *flags = kALMNoChange;        // Safe value...
  385.     
  386.     if (tempSetting != NULL)
  387.     {
  388.         err = ReadSetting(globals, (APSettingHandle)tempSetting);
  389.         require(err == noErr, ReadSettingFailed);
  390.         
  391.         *flags = kALMAvailableNow;
  392.         err = UseSetting(globals, (APSettingHandle)tempSetting, (APSettingHandle)setting, flags);
  393.         require(err == noErr, UseSettingFailed);
  394.     }
  395.     else
  396.     {
  397.         err = memFullErr;
  398.     }
  399.     
  400. ReadSettingFailed:
  401. UseSettingFailed:
  402.     return (ComponentResult) err;
  403.  
  404. } // SetCurrent
  405.  
  406.  
  407. /*------------------------------------------------------------------
  408.     CompareSetting
  409. ------------------------------------------------------------------*/
  410.  
  411. pascal ComponentResult
  412. CompareSetting(
  413.     GlobalsHandle    globals,
  414.     Handle            setting1,
  415.     Handle            setting2,
  416.     Boolean *        equal)
  417. {
  418.     APSettingHandle    apSetting1 = reinterpret_cast<APSettingHandle>(setting1);
  419.     APSettingHandle    apSetting2 = reinterpret_cast<APSettingHandle>(setting2);
  420.     
  421.     *equal = (((**apSetting1).powerOn == (**apSetting2).powerOn)
  422.         && (PLstrcmp((**apSetting1).network, (**apSetting2).network) == 0));
  423.     
  424.     return (ComponentResult) noErr;
  425. }
  426.  
  427.  
  428. /*------------------------------------------------------------------
  429.     EditSetting
  430. ------------------------------------------------------------------*/
  431.  
  432. pascal ComponentResult
  433. EditSetting(
  434.     GlobalsHandle    globals,
  435.     Handle            setting)
  436. {
  437.     OSErr            err                = noErr;
  438.     UInt32             savedA5;
  439.     QDGlobals        mqd;                    // So we can put up an alert...
  440.     QDGlobalsPtr    moduleQuickdraw = &mqd;
  441.     DialogPtr        theDialog         = NULL;
  442.  
  443.     // In ALM 2.0, if you don't support EditSetting, the control panel will display a default
  444.     // error message if the user tries to edit your setting.  Of course, how to edit the setting
  445.     // is entirely dependant on the content of the setting.  In the case of this sample, we
  446.     // really don't know what the meaning of the preference file is, but we can, at the very least,
  447.     // give the user a more helpful error message...
  448.     
  449.     savedA5 = SetA5 ((UInt32) &moduleQuickdraw);
  450.  
  451.     // Initialize a QD world...
  452.     
  453.     InitGraf (&mqd.thePort);        // always init _our_ QD structure
  454.     InitFonts ();
  455.     InitWindows ();
  456.     InitMenus ();
  457.     TEInit ();
  458.     InitDialogs (NULL);
  459.     InitCursor ();
  460.  
  461.     // Get and display the "sorry" dialog...
  462.  
  463.     theDialog = GetNewDialog (kEditMessageRsrcID, kAllocateMemory, kPlaceInFront);
  464.  
  465.     if (theDialog != NULL) {
  466.     
  467.         SInt16        itemHit;
  468.         GrafPtr        svPort;
  469.  
  470.         GetPort (&svPort);
  471.         SetPort (theDialog);
  472.         SetDialogDefaultItem (theDialog, kEditOpenButton);
  473.         SetDialogCancelItem (theDialog, kEditCancelButton);
  474.         ShowWindow (theDialog);
  475.         
  476.         // Loop until closed; note that, as long as we use the standard filter proc, 
  477.         // the ALM control panel will manage launches and moveable-modal things for us...
  478.         
  479.         do {
  480.             ModalDialog (kUseStandardFilterProc, &itemHit);
  481.             switch (itemHit) {
  482.                 case kEditCancelButton:
  483.                     err = userCanceledErr;
  484.                     break;
  485.                 case kEditOpenButton:
  486.                     err = LaunchAP();
  487.                     break;
  488.                 case kEditApplyButton:
  489.                     err = GetCurrent(globals, setting);
  490.                     break;        
  491.             } // switch
  492.         } while (itemHit != kEditCancelButton && itemHit != kEditApplyButton);
  493.     
  494.         DisposeDialog (theDialog);
  495.         SetPort (svPort);
  496.     
  497.     } else {
  498.     
  499.         err = resNotFound;
  500.     
  501.     } // if
  502.  
  503.     // Restore a5...
  504.  
  505.     (void) SetA5 (savedA5);
  506.  
  507.     return (ComponentResult) err;
  508.  
  509. } // EditSetting
  510.  
  511.  
  512. /*------------------------------------------------------------------
  513.     DescribeSetting
  514. ------------------------------------------------------------------*/
  515.  
  516. pascal ComponentResult
  517. DescribeSetting(
  518.     GlobalsHandle    globals,
  519.     Handle            setting,
  520.     CharsHandle        text)
  521. {
  522.     OSErr    err = noErr;
  523.     Str255    what = "\pWireless network: “^0”.";
  524.     
  525.     check((**reinterpret_cast<APSettingHandle>(setting)).version == 'nheg');
  526.     
  527.     if ((**reinterpret_cast<APSettingHandle>(setting)).powerOn)
  528.     {
  529.         Str255    what = "\pWireless network: “^0”.";
  530.         
  531.         InsParamStr("\p^0", (**reinterpret_cast<APSettingHandle>(setting)).network, what);
  532.         
  533.         SetHandleSize((Handle)text, StrLength(what));
  534.         BlockMoveData(&what[1], *text, StrLength(what));
  535.     }
  536.     else
  537.     {
  538.         Str255    what = "\pAirPort powered off.";
  539.         
  540.         SetHandleSize(reinterpret_cast<Handle>(text), StrLength(what));
  541.         BlockMoveData(&what[1], *text, StrLength(what));
  542.     }
  543.  
  544.     return (ComponentResult) err;
  545. }
  546.  
  547.  
  548. /*------------------------------------------------------------------
  549.     DescribeError
  550. ------------------------------------------------------------------*/
  551.  
  552. pascal ComponentResult
  553. DescribeError (GlobalsHandle globals, OSErr lastErr, Str255 errStr) {
  554.  
  555. #ifndef    __SC__
  556. #pragma unused (globals)
  557. #endif    // __SC__
  558.  
  559.     OSErr                err        = noErr;
  560.  
  561.     // We're just going to be very superficial about this, and deal with a very few
  562.     // "plain text" messages only. We could get fancy, and try to be a bit more 
  563.     // descriptive...
  564.  
  565.     if ((lastErr > 0) && (lastErr <= kSampleBiggestKnownIdx)) {
  566.         GetIndString (errStr, kSampleErrStrRsrcID, lastErr);
  567.     } else {
  568.         err = paramErr;    // Get ALM to generate default "error number" text...
  569.     } // if
  570.  
  571.     return (ComponentResult) err;
  572.  
  573. } // DescribeError
  574.  
  575.  
  576. /*------------------------------------------------------------------
  577.     ImportExport
  578. ------------------------------------------------------------------*/
  579.  
  580. pascal ComponentResult
  581. ImportExport (GlobalsHandle globals, Boolean import, Handle setting, SInt16 resRefNum) {
  582.  
  583.     OSErr                err            = noErr;
  584.     SInt16                svResFile    = CurResFile ();
  585.  
  586.     // Not a lot of work to do here; but if we are importing _and_ the current settings
  587.     // on the machine match the import, we have a problem in that our mechanism doesn't
  588.     // let us distinguish the new setting properly. It is possible that the user would
  589.     // prefer to overwrite the existing settings, but we won't handle that case.
  590.     
  591.     UseResFile (resRefNum);    // Need to do this if we use separate resources for import/export...
  592.     
  593.     // If this were a real module, your might need to grab more information from this
  594.     // machine in order to carry the setting over to another machine; for example, the
  595.     // extension set module that comes with ALM only stores the _name_ of an extension
  596.     // manager set, which is good enough for using on one machine, but when that setting
  597.     // is exported, the names of all the on/off extensions get spooled away in a separate
  598.     // resource (which the module adds to the "resRefNum" resource fork)...
  599.     
  600.     if (import) {
  601.     
  602.         Handle        tempSetting        = NewHandle (1);
  603.         
  604.         if (tempSetting != NULL) {
  605.             err = (OSErr) GetCurrent (globals, tempSetting);
  606.             if (err == noErr) {
  607.                 Boolean        lookTheSame;
  608.                 err = CompareSetting (globals, tempSetting, setting, &lookTheSame);
  609.                 if ((err == noErr) && lookTheSame) {
  610.                     err = kSampleImportPrefDatesIdx;
  611.                 } // if
  612.             } // if
  613.         } else {
  614.             err = memFullErr;
  615.         } // if
  616.     
  617.         if (tempSetting != NULL) {
  618.             DisposeHandle (tempSetting);    
  619.         } // if
  620.  
  621.     } // if
  622.  
  623.     UseResFile (svResFile);
  624.  
  625.     return (ComponentResult) err;
  626.  
  627. } // ImportExport
  628.  
  629.  
  630. /*------------------------------------------------------------------
  631.     GetScriptInfo
  632. ------------------------------------------------------------------*/
  633.  
  634. pascal ComponentResult
  635. GetScriptInfo (GlobalsHandle globals, ALMScriptManagerInfo* info) {
  636.  
  637. #ifndef    __SC__
  638. #pragma unused (globals)
  639. #endif    // __SC__
  640.  
  641.     OSErr                                err            = noErr;
  642.     ALMAltScriptManagerInfoHandle        scriptInfo    = NULL;
  643.  
  644.     // We stored this stuff in a resource, so it can be localized easily; we have to do a bit of
  645.     // translation, though, from the alternate format to the ALM format (fortunately
  646.     // the alternate format is given to us in the headers!)...
  647.     
  648.     scriptInfo = (ALMAltScriptManagerInfoHandle) 
  649.                 GetResource (kALMAltScriptManagerInfoRsrcType, kALMAltScriptManagerInfoRsrcID);
  650.     
  651.     if (scriptInfo != NULL) {
  652.  
  653.         HLock ((Handle) scriptInfo);
  654.         
  655.         info->version         = (**scriptInfo).version;
  656.         info->scriptCode     = (**scriptInfo).scriptCode;
  657.         info->regionCode     = (**scriptInfo).regionCode;
  658.         info->langCode         = (**scriptInfo).langCode;
  659.         info->fontSize         = (**scriptInfo).fontSize;
  660.         GetFNum ((**scriptInfo).fontName, &info->fontNum);
  661.         
  662.         HUnlock ((Handle) scriptInfo);
  663.  
  664.     } else {
  665.         err = ResError ();
  666.     } // if
  667.  
  668.     if (scriptInfo != NULL) {
  669.         ReleaseResource ((Handle) scriptInfo);
  670.     } // if
  671.  
  672.     return (ComponentResult) err;
  673.  
  674. } // GetScriptInfo
  675.  
  676.  
  677. /*------------------------------------------------------------------
  678.     GetInfo
  679. ------------------------------------------------------------------*/
  680.  
  681. pascal ComponentResult
  682. GetInfo (GlobalsHandle globals, CharsHandle* text, STHandle* style, ModalFilterUPP filter) {
  683.  
  684. #ifndef    __SC__
  685. #pragma unused (globals, filter)
  686. #endif    // __SC__
  687.  
  688.     OSErr                err        = noErr;
  689.  
  690.     // This code is pretty cookie-cutter, unless you want to make it context-sensitive...
  691.  
  692.     do {
  693.     
  694.         *text = (CharsHandle) Get1Resource ('TEXT', kGetInfoRsrcID);
  695.         err = ResError ();
  696.         if (err != noErr) {
  697.             break;
  698.         } else if (*text == NULL) {
  699.             err = resNotFound;
  700.             break;
  701.         } // if
  702.         *style = (STHandle) Get1Resource ('styl', kGetInfoRsrcID);
  703.         err = ResError ();
  704.         if (err != noErr) {
  705.             break;
  706.         } else if (*style == NULL) {
  707.             err = resNotFound;
  708.             break;
  709.         } // if
  710.         DetachResource ((Handle) *text);
  711.         DetachResource ((Handle) *style);
  712.     
  713.     } while (false);    // execute once...
  714.     
  715.     return (ComponentResult) err;
  716.  
  717. } // GetInfo
  718.