home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / DVIM72-Mac 1.9.6 / source / Append2hdlg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-14  |  5.3 KB  |  126 lines  |  [TEXT/R*ch]

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /* Append2hdlg - Append one 'hdlg' resource onto another.                    */
  4. /*                                                                            */
  5. /*    So what we want to do here is append the hdlg resource with resource ID    */
  6. /* srcID, onto the end of the hdlg resource, ID dstID.  Here's what these    */
  7. /* things look like:                                                        */
  8. /*                                                                            */
  9. /*                    *-----------------------------------*                    */
  10. /*                    | Header (version, options, etc.)    |                    */
  11. /*                    *-----------------------------------*                    */
  12. /*                    / # of items in item array            /                    */
  13. /*                    *-----------------------------------*                    */
  14. /*                    | Missing item marker                |                    */
  15. /*                    *-----------------------------------*                    */
  16. /*                    / Array of items                    /                    */
  17. /*                    /    …                                /                    */
  18. /*                    *-----------------------------------*                    */
  19. /*                                                                            */
  20. /* Okay, so this chart breaks up the resource into logical blocks for this    */
  21. /* exercise.  We're most interested in the blocks marked with '/'s.  The    */
  22. /* first one of these is the # of items in the item array.  We need to read    */
  23. /* this field in the source hdlg to know how many items we are adding.  We    */
  24. /* need to update this field in the destination hdlg so the Help Manager     */
  25. /* knows that we added some items.  This missing item is a generic item     */
  26. /* used by the Help Manager anytime it can't find a resource entry for an    */
  27. /* item.  In most hdlg resources, this item is simply HMSkipItem (a no op),    */
  28. /* but this code makes no assumptions about that.  It does however assume    */
  29. /* that you want to preserve the missing item in the DESTINATION hdlg,        */
  30. /* rather than copying from the source.                                      */
  31. /* So this code does this:                                                    */
  32. /*                                                                            */
  33. /*                    Source                            Destination                */
  34. /*        *---------------------------*        *---------------------------*    */
  35. /*        | Header                    |          | Header                    |    */
  36. /*        |    (version, options, etc.)|         |    (version, options, etc.)|    */
  37. /*        *---------------------------*        *---------------------------*    */
  38. /*        / # of items in item array    /--Add->/ # of items in item array    /    */
  39. /*        *---------------------------*        *---------------------------*    */
  40. /*        | Missing item                 |        | Missing item                 |    */
  41. /*        *---------------------------*        *---------------------------*    */
  42. /*                                            / Array of items            /    */
  43. /*                                            /    …                        /    */
  44. /*        *---------------------------*-Copy->*---------------------------*    */
  45. /*        / Array of items            /                                        */
  46. /*        /    …                        /                                        */
  47. /*        *---------------------------*                                        */
  48. /*                                                                            */
  49. /* Nothing to it.  The number of items is updated by adding the count from    */
  50. /* source hdlg, no 'minus 1' or anything tricky.  Then just append the item    */
  51. /* array from the source onto the end of the destination.  The Help Manager    */
  52. /* finds the new items no problem.  Okay, but since we are a guest in some-    */
  53. /* one elses closet, we need to play some games with memory.  First of all,    */
  54. /* we make sure that the destination 'hdlg' resource isn't already in mem-    */
  55. /* ory using the ol' SetResLoad trick.  If it's not there, we load it, but    */
  56. /* in any case, the hdlg is loaded into memory.  Once there, we make the    */
  57. /* rather large assumption that it's not going anywhere.  This means that    */
  58. /* we don't lock the hdlg handle, we don't even mark it non-purgeable.  The    */
  59. /* assumption is that the Help Manager will be finding the resource as soon */
  60. /* as we are done with it, and he will take care of keeping it around after    */
  61. /* that.  Once the dialog is dismissed, the resource is naturally purged,    */
  62. /* along with the changes that we made to it.  Since we never told the        */
  63. /* Resource Manager that we had changed the resource, it doesn't try to save*/
  64. /* it.                                                                        */
  65.  
  66. /* Types for accessing the Help Manager 'hdlg' resources. */
  67. typedef struct {
  68.     short    hdlgVers;
  69.     short    hdlg1stItem;
  70.     long    hdlgOptions;
  71.     short    hdlgProcID;
  72.     short    hdlgVarCode;
  73.     short    hdlgNumItems;
  74. } hdlgHeader, *hdlgHeaderPtr, **hdlgHeaderHdl;
  75.  
  76. typedef short *IntPtr, **IntHdl;
  77.  
  78. void Append2hdlg( short srcResID, short dstResID );
  79.  
  80. void Append2hdlg( short srcResID, short dstResID )
  81. {
  82.     Handle            srcHdl, dstHdl;
  83.     Ptr                srcPtr, dstPtr;
  84.     short            srcLength, dstLength;
  85.     short            missingItmSz;
  86.     SignedByte        dstHState;
  87.     
  88.     
  89.     srcHdl = GetResource('hdlg', srcResID);    
  90.     if (srcHdl != nil) {                        
  91.         SetResLoad(false);                        /* System Resource, make sure it’s not    */
  92.         dstHdl = GetResource('hdlg', dstResID);    /* already loaded.                */
  93.         SetResLoad(true);
  94.         if (*dstHdl == 0)
  95.             dstHdl = GetResource('hdlg', dstResID);
  96.         dstHState = HGetState(dstHdl);
  97.         
  98.         if (dstHdl != nil) {
  99.             srcPtr = (Ptr)*srcHdl + sizeof(hdlgHeader);
  100.             missingItmSz = *((IntPtr)srcPtr);
  101.             srcLength = GetHandleSize(srcHdl) - (sizeof(hdlgHeader) - missingItmSz);
  102.  
  103.             dstLength = GetHandleSize(dstHdl);
  104.             SetHandleSize(dstHdl, dstLength + srcLength);
  105.             if (MemError() != noErr) {
  106.                 DebugStr("\pMemError");    /* Use this error handler, go to jail.    */
  107.                 ExitToShell();        /*        It's the law!            */
  108.             }
  109.             dstPtr = (Ptr)*dstHdl + dstLength;
  110.             srcPtr = (Ptr)*srcHdl + sizeof(hdlgHeader) + missingItmSz;
  111.  
  112.             HLock(srcHdl);
  113.             HLock(dstHdl);
  114.  
  115.             BlockMove(srcPtr, dstPtr, srcLength);
  116.  
  117.             HUnlock(srcHdl);
  118.             HSetState(dstHdl, dstHState);
  119.  
  120.             ((hdlgHeaderPtr)*dstHdl)->hdlgNumItems += ((hdlgHeaderPtr)*srcHdl)->hdlgNumItems;        
  121.             
  122.         }
  123.     }
  124.     ReleaseResource(srcHdl);
  125. }
  126.