home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / FindIcon / Get_normal_file_icon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-01  |  6.1 KB  |  247 lines  |  [TEXT/KAHL]

  1. #include <Finder.h>
  2. #include <Folders.h>
  3. #include "Get_normal_file_icon.h"
  4. #include <exceptions.h>
  5. #include "Find_generic_icon_id.h"
  6. #include "Copy_each_icon.h"
  7. #include "Is_suite_empty.h"
  8. #include "Get_resource_icons.h"
  9.  
  10. /*    ------------------------------------------------------------------
  11.     Get_normal_file_icon        Get an icon suite for a file that does
  12.                                 not have a custom icon.
  13.     ------------------------------------------------------------------
  14. */
  15.  
  16. static    short    Find_desktop_database(
  17. /* --> */    short first_vRefNum,
  18. /* --> */    OSType file_creator );    // returns a DT refnum or 0
  19.  
  20. static    Boolean    In_one_desktop(
  21. /* --> */    short    vRefNum,
  22. /* --> */    OSType    file_creator,
  23. /* <-- */    short    *dt_refnum
  24. );
  25.  
  26. static    pascal OSErr Get_icon( ResType theType, Handle *theIcon,
  27.             void *yourDataPtr );
  28.  
  29. typedef struct 
  30. {
  31.     OSType        file_creator;
  32.     OSType        file_type;
  33.     short        DTRefNum;
  34. } Get_icon_data;
  35.  
  36. OSErr    Get_normal_file_icon(
  37. /* --> */    CInfoPBRec            *cpb,
  38. /* --> */    IconSelectorValue    icon_selector,
  39. /* <-- */    Handle    *the_suite
  40. )
  41. {
  42.     OSErr    err;
  43.     long    data_size;
  44.     Handle    icon_data;
  45.     Byte    icon_type;
  46.     Get_icon_data    get_data;
  47.     short    icon_id;
  48.     Boolean    in_Finder;
  49.     short    save_resfile, Finder_resfile, sys_vRefNum;
  50.     long    sys_dirID;
  51.     
  52.     icon_id = Find_generic_icon_id( cpb->hFileInfo.ioFlFndrInfo.fdType,
  53.         &in_Finder );
  54.     save_resfile = CurResFile();
  55.     
  56.     if (in_Finder)
  57.     {
  58.         (void) FindFolder( kOnSystemDisk, kSystemFolderType,
  59.               kDontCreateFolder, &sys_vRefNum, &sys_dirID );
  60.         SetResLoad( false );
  61.         Finder_resfile = HOpenResFile( sys_vRefNum, sys_dirID,
  62.             "\pFinder", fsRdPerm );
  63.         SetResLoad( true );
  64.         forbid_action( Finder_resfile == -1, HOpenResFile,
  65.             err = ResError() );
  66.         err = Get_resource_icons( the_suite, icon_id, icon_selector );
  67.         CloseResFile( Finder_resfile );
  68. HOpenResFile:    ;
  69.     }
  70.     else    // icons in desktop DB or in System
  71.     {
  72.         get_data.DTRefNum = Find_desktop_database( cpb->dirInfo.ioVRefNum,
  73.             cpb->hFileInfo.ioFlFndrInfo.fdCreator );
  74.         if ( get_data.DTRefNum != 0 )    // the right icons are in some desktop
  75.         {
  76.             err = NewIconSuite( the_suite );
  77.             forbid( err, NewIconSuite );
  78.             
  79.             get_data.file_creator = cpb->hFileInfo.ioFlFndrInfo.fdCreator;
  80.             get_data.file_type = cpb->hFileInfo.ioFlFndrInfo.fdType;
  81.             if (get_data.file_type == kApplicationAliasType)
  82.                 get_data.file_type = 'APPL';
  83.             err = ForEachIconDo( *the_suite, icon_selector,
  84.                 Get_icon, &get_data );
  85.         NewIconSuite:
  86.             ;
  87.         }
  88.         
  89.         if ( (get_data.DTRefNum == 0) || Is_suite_empty( *the_suite ) )
  90.         {
  91.             UseResFile( 0 );
  92.             err = Get_resource_icons( the_suite, icon_id, icon_selector );
  93.         }
  94.     }
  95.  
  96.     UseResFile( save_resfile );
  97.  
  98.     return err;
  99. }
  100.  
  101. /*    ------------------------------------------------------------------
  102.     Get_icon        This is an IconAction procedure to fill in one
  103.                     slot of an icon suite, given a file type, creator,
  104.                     and desktop database.
  105.     ------------------------------------------------------------------
  106. */
  107. static    pascal OSErr Get_icon( ResType theType, Handle *theIcon,
  108.             void *yourDataPtr )
  109. {
  110.     OSErr    err;
  111.     Get_icon_data    *data;
  112.     DTPBRec            desk_rec;
  113.     
  114.     err = noErr;
  115.     data = (Get_icon_data *) yourDataPtr;
  116.  
  117.     *theIcon = NewHandle( kLarge8BitIconSize );
  118.     require_action( *theIcon, NewHandle, err = memFullErr );
  119.     HLock( *theIcon );
  120.  
  121.     desk_rec.ioDTRefNum = data->DTRefNum;
  122.     desk_rec.ioDTBuffer = **theIcon;
  123.     desk_rec.ioDTReqCount = kLarge8BitIconSize;
  124.     desk_rec.ioFileCreator = data->file_creator;
  125.     desk_rec.ioFileType = data->file_type;
  126.     switch (theType)
  127.     {
  128.         case large1BitMask:
  129.             desk_rec.ioIconType = kLargeIcon;
  130.             break;
  131.         case large4BitData:
  132.             desk_rec.ioIconType = kLarge4BitIcon;
  133.             break;
  134.         case large8BitData:
  135.             desk_rec.ioIconType = kLarge8BitIcon;
  136.             break;
  137.         case small1BitMask:
  138.             desk_rec.ioIconType = kSmallIcon;
  139.             break;
  140.         case small4BitData:
  141.             desk_rec.ioIconType = kSmall4BitIcon;
  142.             break;
  143.         case small8BitData:
  144.             desk_rec.ioIconType = kSmall8BitIcon;
  145.             break;
  146.         
  147.         default:
  148.             // The desktop database does not have "mini" icons
  149.             desk_rec.ioIconType = 1000;
  150.             break;
  151.     }
  152.     err = PBDTGetIconSync( &desk_rec );
  153.     if (err == noErr)
  154.     {
  155.         HUnlock( *theIcon );
  156.         SetHandleSize( *theIcon, desk_rec.ioDTActCount );
  157.     }
  158.     else
  159.     {
  160.         DisposeHandle( *theIcon );
  161.         *theIcon = NULL;
  162.         err = noErr;
  163.     }
  164.     
  165. NewHandle:
  166.     return err;
  167. }
  168.  
  169. /*    ------------------------------------------------------------------
  170.     Find_desktop_database            Find the reference number of a
  171.                                     desktop database containing icons
  172.                                     for a specified creator code.
  173.     The search begins on a specified volume, but covers all volumes.
  174.     ------------------------------------------------------------------
  175. */
  176. static    short    Find_desktop_database(
  177. /* --> */    short first_vRefNum,
  178. /* --> */    OSType file_creator )    // returns a DT refnum or 0
  179. {
  180.     OSErr    err;
  181.     VolumeParam        vpb;
  182.     short            DTRefNum;
  183.  
  184.     DTRefNum = 0;
  185.     
  186.     if (!In_one_desktop(first_vRefNum, file_creator, &DTRefNum))
  187.     {
  188.         vpb.ioNamePtr = NULL;
  189.         for (vpb.ioVolIndex = 1;
  190.             PBGetVInfoSync( (ParmBlkPtr) &vpb ) == noErr;
  191.             ++vpb.ioVolIndex )
  192.         {
  193.             if ( vpb.ioVRefNum == first_vRefNum )
  194.                 continue;
  195.             if ( In_one_desktop( vpb.ioVRefNum, file_creator,
  196.                 &DTRefNum ) )
  197.                 break;
  198.         }
  199.     }
  200.     
  201.     return DTRefNum;
  202. }
  203.  
  204. /*    ------------------------------------------------------------------
  205.     In_one_desktop            Determine whether the desktop database for
  206.                             one particular volume contains icons for
  207.                             a given creator code, and if so, return its
  208.                             reference number.
  209.     ------------------------------------------------------------------
  210. */
  211. static    Boolean    In_one_desktop(
  212. /* --> */    short    vRefNum,
  213. /* --> */    OSType    file_creator,
  214. /* <-- */    short    *dt_refnum
  215. )
  216. {
  217.     OSErr        err;
  218.     DTPBRec        desk_rec;
  219.     Boolean        retval;
  220.     
  221.     retval = false;    // default to failure
  222.     desk_rec.ioNamePtr = NULL;
  223.     desk_rec.ioVRefNum = vRefNum;
  224.     err = PBDTGetPath( &desk_rec );
  225.     forbid( err, PBDTGetPath );
  226.     
  227.     /*
  228.         We want to ignore any non-icon data, such as the 'paul'
  229.         item that is used for drag-and-drop.
  230.     */
  231.     desk_rec.ioFileCreator = file_creator;
  232.     desk_rec.ioIndex = 1;
  233.     do {
  234.         desk_rec.ioTagInfo = 0;
  235.         err = PBDTGetIconInfoSync( &desk_rec );
  236.         desk_rec.ioIndex += 1;
  237.     } while ( (err == noErr) && (desk_rec.ioIconType <= 0) );
  238.     if (err == noErr)
  239.     {
  240.         retval = true;
  241.         *dt_refnum = desk_rec.ioDTRefNum;
  242.     }
  243.     
  244. PBDTGetPath:
  245.     return retval;
  246. }
  247.