Annotation of mstools/samples/sdktools/aniedit/anifile.c, revision 1.1

1.1     ! root        1: /****************************************************************************\
        !             2: *
        !             3: *     MODULE: anifile.c
        !             4: *
        !             5: *     PURPOSE: Processes files for the Animated Cursor Editor
        !             6: *
        !             7: *     Copyright 1993, Microsoft Corp.
        !             8: *
        !             9: *
        !            10: * History:
        !            11: *   21-Apr-1993 JonPa   Wrote it.
        !            12: *
        !            13: \****************************************************************************/
        !            14: 
        !            15: #include <windows.h>
        !            16: #include <commdlg.h>
        !            17: #include "anidefs.h"
        !            18: 
        !            19: /****************************************************************************\
        !            20: *
        !            21: *     FUNCTION: BOOL CreateFrameFromCursorFile( LPSTR pszFile )
        !            22: *
        !            23: *     PURPOSE:  Opens a cursor file, reads the icon info out of it,
        !            24: *               and creates a frame and step for that icon, then links
        !            25: *               everything together and updates the listbox.
        !            26: *
        !            27: *     NOTES:    This function accesses the global flag gfEditFrame.
        !            28: *               If this bool is TRUE, then the currently selected frame
        !            29: *               in the listbox is overwritten.  If it is false, then
        !            30: *               a new frame is created and inserted after the currently
        !            31: *               selected frame (or at the end if no selection).
        !            32: *
        !            33: * History:
        !            34: *   21-Apr-1993 JonPa   Created it
        !            35: *
        !            36: \****************************************************************************/
        !            37: BOOL CreateFrameFromCursorFile(HWND hwnd,  LPTSTR pszFile, BOOL fEdit) {
        !            38:     PFRAME pf;
        !            39:     HANDLE hf;
        !            40:     PSTEP psOld, psNew;
        !            41:     DWORD ckSize;
        !            42:     int iSel;
        !            43:     int cSel;
        !            44: 
        !            45:     cSel = GetSelStepCount(hwnd);
        !            46: 
        !            47:     if ( (fEdit && (cSel != 1)) || cSel > 1) {
        !            48:         FmtMessageBox( hwnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
        !            49:                 TRUE, fEdit ? MSG_MUSTEQONEFAME : MSG_LESSEQONEFRAME);
        !            50:         return FALSE;
        !            51:     }
        !            52: 
        !            53:     /* get currently selected frame */
        !            54:     GetCurrentSel(hwnd, DLG_MAIN_FRAMELIST, &iSel, 1, &cSel );
        !            55: 
        !            56:     if (cSel == 0)
        !            57:         psOld = NULL;
        !            58:     else
        !            59:         psOld = GetStep(hwnd, iSel);
        !            60: 
        !            61:     /*
        !            62:      * If not editing, create a new step
        !            63:      */
        !            64:     if (!fEdit || !IsValidPS(psOld)) {
        !            65:         psNew = NewStep();
        !            66: 
        !            67:         if (psNew == NULL) {
        !            68:             return FALSE;
        !            69:         }
        !            70:     } else {
        !            71:         psNew = NULL;
        !            72:     }
        !            73: 
        !            74:     hf = CreateFile(pszFile, GENERIC_READ,
        !            75:              0, NULL,
        !            76:              OPEN_EXISTING,
        !            77:              FILE_ATTRIBUTE_NORMAL,
        !            78:              NULL);
        !            79: 
        !            80:     if (hf == INVALID_HANDLE_VALUE)
        !            81:         return FALSE;
        !            82: 
        !            83:     ckSize = GetFileSize(hf, NULL);
        !            84: 
        !            85:     /* get the frame out of the file */
        !            86:     pf = ReadIconFromFile(hwnd, hf, ckSize);
        !            87:     CloseHandle(hf);
        !            88: 
        !            89:     if (pf == NULL) {
        !            90:         if (psNew != NULL)
        !            91:             FreeMem(psNew);
        !            92:         return FALSE;
        !            93:     }
        !            94: 
        !            95:     if (psNew != NULL) {
        !            96: 
        !            97:         if (IsValidPS(psOld)) {
        !            98:             psNew->jif = psOld->jif;
        !            99:             iSel += 1;
        !           100:         } else {
        !           101:             psNew->jif = ganiAcon.anih.jifRate;
        !           102:             iSel = SendDlgItemMessage(hwnd, DLG_MAIN_FRAMELIST, LB_GETCOUNT,
        !           103:                     0, 0);
        !           104:         }
        !           105: 
        !           106:         LinkStepFrame(psNew, pf);
        !           107: 
        !           108:         SendDlgItemMessage(hwnd, DLG_MAIN_FRAMELIST, LB_INSERTSTRING, iSel,
        !           109:             (LPARAM)psNew);
        !           110: 
        !           111:         SetCurrentSel(hwnd, DLG_MAIN_FRAMELIST, FALSE, iSel);
        !           112: 
        !           113:     } else {
        !           114:         HWND hwndLB = GetDlgItem(hwnd, DLG_MAIN_FRAMELIST);
        !           115: 
        !           116:         /*
        !           117:          * Delete the old frame and point the step to the new one.
        !           118:          */
        !           119:         LinkStepFrame(psOld, pf);
        !           120: 
        !           121:         InvalidateRect(hwndLB, NULL, TRUE);
        !           122:     }
        !           123: 
        !           124:     return TRUE;
        !           125: }
        !           126: 
        !           127: 
        !           128: /****************************************************************************\
        !           129: *
        !           130: *     FUNCTION: HICON ConvertDataToIcon( PFRAME pf )
        !           131: *
        !           132: *     PURPOSE:
        !           133: *
        !           134: *
        !           135: *
        !           136: *
        !           137: * History:
        !           138: *   23-Apr-1993 JonPa   copied from Win NT USERs ReadIconGuts
        !           139: *
        !           140: \****************************************************************************/
        !           141: HICON ConvertDataToIcon( PFRAME pf, WORD *pxHotSave, WORD *pyHotSave )
        !           142: {
        !           143:     NEWHEADER *pnh;
        !           144:     NEWHEADER *pnhBase;
        !           145:     RESDIR *prd;
        !           146:     int offMatch;
        !           147:     ICONFILERESDIR *pird;
        !           148:     PCURSORRESOURCE pcres;
        !           149:     BOOL fIcon;
        !           150:     HICON hicon;
        !           151:     WORD x, y;
        !           152: 
        !           153:     pnhBase = (NEWHEADER *)pf->abIcon;
        !           154: 
        !           155:     /*
        !           156:      * Construct a fake array of RESDIR entries using the info at the head
        !           157:      * of the file.  Store the data offset in the idIcon WORD so it can be
        !           158:      * returned by RtlGetIdFromDirectory.
        !           159:      */
        !           160:     pnh = (NEWHEADER *)LocalAlloc(LMEM_FIXED, sizeof(NEWHEADER) +
        !           161:             (pnhBase->cResources * sizeof(RESDIR)));
        !           162:     if (pnh == NULL)
        !           163:         return NULL;
        !           164: 
        !           165:     *pnh = *pnhBase;
        !           166:     prd = (RESDIR *)(pnh + 1);
        !           167:     pird = (ICONFILERESDIR *)(pnhBase + 1);
        !           168: 
        !           169:     /* prime pird for first line of loop */
        !           170:     pird--;
        !           171: 
        !           172:     for (offMatch = 0; offMatch < (int)pnh->cResources; offMatch++, prd++) {
        !           173: 
        !           174:         /*
        !           175:          * Get the next resource directory from the icon file.
        !           176:          */
        !           177: 
        !           178:         ++pird;
        !           179: 
        !           180:         /*
        !           181:          * Convert from the icon editor's resource directory format
        !           182:          * to the post-RC.EXE format LookupIconIdFromDirectory expects.
        !           183:          */
        !           184:         if (pnh->rt == 1) {     // ICON
        !           185:             prd->ResInfo.Icon.Width = pird->bWidth;
        !           186:             prd->ResInfo.Icon.Height = pird->bHeight;
        !           187:             prd->ResInfo.Icon.ColorCount = pird->bColorCount;
        !           188:             prd->ResInfo.Icon.reserved = 0;
        !           189:         } else {                // CURSOR
        !           190:             prd->ResInfo.Cursor.Width = pird->bWidth;
        !           191:             prd->ResInfo.Cursor.Height = pird->bHeight;
        !           192:         }
        !           193:         prd->Planes = 0;                // Hopefully nobody uses this
        !           194:         prd->BitCount = 0;              //        "        "
        !           195:         prd->BytesInRes = pird->dwDIBSize;
        !           196:         prd->idIcon = (WORD)pird->dwDIBOffset;
        !           197:     }
        !           198: 
        !           199:     /*
        !           200:      * NOTE: nh.rt is NOT an RT_ type value.  For instance, nh.rt == 1 for
        !           201:      * an icon file where as 1 == RT_CURSOR, not RT_ICON.
        !           202:      */
        !           203: 
        !           204:     fIcon = (pnhBase->rt == 1);
        !           205:     offMatch = LookupIconIdFromDirectory((PBYTE)pnh, fIcon);
        !           206: 
        !           207:     LocalFree(pnh);
        !           208: 
        !           209:     if (fIcon) {
        !           210:         pcres = (PCURSORRESOURCE)&(pf->abIcon[offMatch]);
        !           211:         *pxHotSave = gcxCursor / 2;
        !           212:         *pyHotSave = gcyCursor / 2;
        !           213:     } else {
        !           214: 
        !           215:         offMatch -= (sizeof(pcres->xHotspot) + sizeof(pcres->yHotspot));
        !           216: 
        !           217:         for(; pird->dwDIBOffset != (WORD)offMatch &&
        !           218:                 pird != (ICONFILERESDIR *)(pnhBase + 1); pird--);
        !           219: 
        !           220:         pcres = (PCURSORRESOURCE)&(pf->abIcon[offMatch]);
        !           221: 
        !           222:         x = pcres->xHotspot;
        !           223:         y = pcres->yHotspot;
        !           224:         *pxHotSave = pcres->xHotspot = pird->xHotspot;
        !           225:         *pyHotSave = pcres->yHotspot = pird->yHotspot;
        !           226:     }
        !           227: 
        !           228:     hicon = CreateIconFromResource( (PBYTE)pcres,
        !           229:             pf->rtag.ckSize - offMatch, fIcon, 0x00030000);
        !           230: 
        !           231:     if(!fIcon) {
        !           232:         pcres->xHotspot = x;
        !           233:         pcres->yHotspot = y;
        !           234:     }
        !           235: 
        !           236:     return hicon;
        !           237: }
        !           238: 
        !           239: 
        !           240: 
        !           241: 
        !           242: /****************************************************************************\
        !           243: *
        !           244: *     FUNCTION: PFRAME ReadIconFromFile(HWND hwnd, HANDLE hf, DWORD ckSize)
        !           245: *
        !           246: *     PURPOSE:  Reads the icon info out of a file,
        !           247: *               and creates a frame for that icon.
        !           248: *
        !           249: *
        !           250: * History:
        !           251: *   22-Apr-1993 JonPa   Created it
        !           252: *
        !           253: \****************************************************************************/
        !           254: PFRAME ReadIconFromFile(HWND hwnd, HANDLE hf, DWORD ckSize) {
        !           255:     PFRAME pf = AllocMem( sizeof( FRAME ) + ckSize );
        !           256:     DWORD cbRead;
        !           257:     PFRAME pfList;
        !           258: 
        !           259:     if (pf != NULL) {
        !           260:         pf->cRef = 0;
        !           261: 
        !           262:         if (ReadFile(hf, pf->abIcon, ckSize, &cbRead, NULL) &&
        !           263:                 cbRead == ckSize) {
        !           264:             /* got the data, now set up the rest of the frame and link it in */
        !           265:             pf->dwCheckSum = CalcCheckSum( pf->abIcon, ckSize );
        !           266:             pf->rtag.ckID = FOURCC_icon;
        !           267:             pf->rtag.ckSize = ckSize;
        !           268: 
        !           269:             /* Check if this fram is already in the list */
        !           270:             for (pfList = gpfrmFrames; pfList != NULL;
        !           271:                     pfList = pfList->pfrmNext ) {
        !           272:                 if (pf->dwCheckSum == pfList->dwCheckSum &&
        !           273:                         pf->rtag.ckSize == pfList->rtag.ckSize &&
        !           274:                         memcmp( pf->abIcon, pfList->abIcon, ckSize ) == 0) {
        !           275:                     /*
        !           276:                      * These frames are the same, coalesce them into a
        !           277:                      * sequence.
        !           278:                      */
        !           279:                     FreeMem(pf);
        !           280:                     pf = pfList;
        !           281:                     break;
        !           282:                 }
        !           283:             }
        !           284: 
        !           285:             if (pfList == NULL) {
        !           286:                 /*
        !           287:                  * Did not find a dup, create an icon for this frame
        !           288:                  */
        !           289:                 pf->hcur = ConvertDataToIcon( pf, &(pf->xHotSpot),
        !           290:                         &(pf->yHotSpot) );
        !           291: 
        !           292:                 pf->pfrmNext = gpfrmFrames;
        !           293:                 gpfrmFrames = pf;
        !           294:             }
        !           295: 
        !           296:         } else {
        !           297:             /* File Error */
        !           298:             FreeMem(pf);
        !           299:             pf = NULL;
        !           300:         }
        !           301: 
        !           302:     }
        !           303: 
        !           304:     return pf;
        !           305: }
        !           306: 
        !           307: /****************************************************************************\
        !           308: *
        !           309: *     FUNCTION: HANDLE PromptAndOpenFile( )
        !           310: *
        !           311: *     PURPOSE:  Pust up the standard open dialog and then opens the file
        !           312: *
        !           313: *
        !           314: *
        !           315: *
        !           316: * History:
        !           317: *   21-Apr-1993 JonPa   Created it
        !           318: *
        !           319: \****************************************************************************/
        !           320: HANDLE PromptAndOpenFile(
        !           321:     HWND hwnd,
        !           322:     DWORD  cchFileTitle,
        !           323:     LPTSTR pszFileTitle,
        !           324:     DWORD  cchFileName,
        !           325:     LPTSTR pszFileName,
        !           326:     LPTSTR pszFilter
        !           327:     )
        !           328: {
        !           329:     HANDLE hf = INVALID_HANDLE_VALUE;
        !           330: 
        !           331:     if (PromptForFile( hwnd, cchFileTitle, pszFileTitle, cchFileName,
        !           332:                 pszFileName, pszFilter, NULL, FALSE )) {
        !           333: 
        !           334:         /* Open the file. */
        !           335: 
        !           336:         hf = CreateFile(pszFileName, GENERIC_READ,
        !           337:                 0, NULL,
        !           338:                 OPEN_EXISTING,
        !           339:                 FILE_ATTRIBUTE_NORMAL,
        !           340:                 NULL);
        !           341: 
        !           342:         if (hf == INVALID_HANDLE_VALUE) {
        !           343:             FmtMessageBox( hwnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP, TRUE,
        !           344:                 MSG_CANTOPENFILE, pszFileName );
        !           345:         }
        !           346:     }
        !           347: 
        !           348:     return hf;
        !           349: }
        !           350: 
        !           351: 
        !           352: /****************************************************************************\
        !           353: *
        !           354: *     FUNCTION: HANDLE PromptForFile( )
        !           355: *
        !           356: *     PURPOSE:  Pust up the standard open dialog
        !           357: *
        !           358: *
        !           359: *
        !           360: *
        !           361: * History:
        !           362: *   28-Apr-1993 JonPa   Created it from PromptAndOpenFile
        !           363: *
        !           364: \****************************************************************************/
        !           365: BOOL PromptForFile(
        !           366:     HWND hwnd,
        !           367:     DWORD  cchFileTitle,
        !           368:     LPTSTR pszFileTitle,
        !           369:     DWORD  cchFileName,
        !           370:     LPTSTR pszFile,
        !           371:     LPTSTR pszFilter,
        !           372:     LPTSTR pszDlgTitle,
        !           373:     BOOL fSave
        !           374:     )
        !           375: {
        !           376:     OPENFILENAME ofn;
        !           377: 
        !           378:     ZeroMemory(&ofn, sizeof(ofn));
        !           379: 
        !           380:     /* Set the members of the OPENFILENAME structure. */
        !           381: 
        !           382:     ofn.lStructSize = sizeof(OPENFILENAME);
        !           383:     ofn.hwndOwner = hwnd;
        !           384: 
        !           385:     ofn.lpstrFilter = pszFilter;
        !           386:     ofn.nFilterIndex = 0;
        !           387: 
        !           388:     ofn.lpstrFile = pszFile;
        !           389:     ofn.nMaxFile = cchFileName;
        !           390: 
        !           391:     ofn.lpstrFileTitle = pszFileTitle;
        !           392:     ofn.nMaxFileTitle = cchFileTitle;
        !           393: 
        !           394:     ofn.lpstrTitle = pszDlgTitle;
        !           395: 
        !           396:     ofn.lpstrDefExt = gpszANI;
        !           397: 
        !           398:     if (fSave) {
        !           399:         ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
        !           400:     } else {
        !           401:         ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
        !           402:     }
        !           403: 
        !           404:     /* Display the SaveAs or Open dialog box. */
        !           405: 
        !           406:     return fSave ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn);
        !           407: 
        !           408: }
        !           409: 
        !           410: /****************************************************************************\
        !           411: *
        !           412: *     FUNCTION: BOOL ReadAniFile( HWND hwnd, HANDLE hf ) {
        !           413: *
        !           414: *     PURPOSE:
        !           415: &
        !           416: *   Loads an animatied cursor from a RIFF file.  The RIFF file format for
        !           417: *   animated cursors looks like this:
        !           418: *
        !           419: *   RIFF( 'ACON'
        !           420: *       LIST( 'INFO'
        !           421: *           INAM( <name> )
        !           422: *           IART( <artist> )
        !           423: *       )
        !           424: *       anih( <anihdr> )
        !           425: *       [rate( <rateinfo> )  ]
        !           426: *       ['seq '( <seq_info> )]
        !           427: *       LIST( 'fram' icon( <icon_file> ) )
        !           428: *   )
        !           429: *
        !           430: *
        !           431: * History:
        !           432: *   02-Oct-1991 DarrinM     Created. (in Win32 user)
        !           433: *   17-Mar-1993 JonPa       Rewrote to use RIFF format instead of RAD
        !           434: *   21-Apr-1993 JonPa       Copied it to anifile.c and tweeked it.
        !           435: *
        !           436: \****************************************************************************/
        !           437: BOOL ReadAniFile( HWND hwnd, HANDLE hf ) {
        !           438: 
        !           439:     RTAG tag;
        !           440:     DWORD cbRead;
        !           441:     BOOL fSuccess = FALSE;
        !           442:     JIF *pjifRate = NULL;
        !           443:     DWORD *pseq = NULL;
        !           444:     PFRAME *ppfram = NULL;
        !           445:     int iFrame = 0;
        !           446:     int i;
        !           447: 
        !           448:     if (!ReadTag(hf, &tag))
        !           449:         return FALSE;
        !           450: 
        !           451:     /*
        !           452:      * Make sure it's a RIFF ANI file
        !           453:      */
        !           454:     if (tag.ckID != FOURCC_RIFF)
        !           455:         goto laiFileErr;
        !           456: 
        !           457:     /* read the chunk type */
        !           458:     if(!ReadFile(hf, &tag.ckID, sizeof(tag.ckID), &cbRead, NULL) ||
        !           459:             cbRead < sizeof(tag.ckID)) {
        !           460:         goto laiFileErr;
        !           461:     }
        !           462: 
        !           463:     if (tag.ckID != FOURCC_ACON)
        !           464:         goto laiFileErr;
        !           465: 
        !           466:     /* look for 'anih', 'rate', 'seq ', and 'icon' chunks */
        !           467:     while( ReadTag(hf, &tag)) {
        !           468: 
        !           469:         switch( tag.ckID ) {
        !           470:         case FOURCC_anih:
        !           471:             if (!ReadChunk(hf, &tag, &ganiAcon.anih))
        !           472:                 goto laiFileErr;
        !           473: 
        !           474:             if (!(ganiAcon.anih.fl & AF_ICON) || (ganiAcon.anih.cFrames == 0))
        !           475:                 goto laiFileErr;
        !           476: 
        !           477:             /*
        !           478:              * Allocate space for the ANIHEADER, and a seq and
        !           479:              * rate table (in case we run into one later).
        !           480:              */
        !           481: 
        !           482:             pjifRate = AllocMem( ganiAcon.anih.cSteps * sizeof(JIF) +
        !           483:                     ganiAcon.anih.cSteps * sizeof(DWORD) +
        !           484:                     ganiAcon.anih.cSteps * sizeof(PFRAME));
        !           485: 
        !           486: 
        !           487:             if (pjifRate == NULL)
        !           488:                 goto laiFileErr;
        !           489: 
        !           490:             pseq = (DWORD *)(pjifRate + ganiAcon.anih.cSteps);
        !           491:             ppfram = (PFRAME *)(pseq + ganiAcon.anih.cSteps);
        !           492: 
        !           493:             for( i = 0; i < (int)ganiAcon.anih.cSteps; i++ ) {
        !           494:                 pjifRate[i] = ganiAcon.anih.jifRate;
        !           495:                 pseq[i] = i;
        !           496:                 ppfram[i] = NULL;
        !           497:             }
        !           498:             break;
        !           499: 
        !           500: 
        !           501:         case FOURCC_rate:
        !           502:             /*
        !           503:              * If we find a rate chunk, read it into its preallocated
        !           504:              * space.
        !           505:              */
        !           506:             if(!ReadChunk(hf, &tag, (PBYTE)pjifRate))
        !           507:                 goto laiFileErr;
        !           508:             break;
        !           509: 
        !           510: 
        !           511:         case FOURCC_seq:
        !           512:             /*
        !           513:              * If we find a seq chunk, read it into its preallocated
        !           514:              * space.
        !           515:              */
        !           516:             if(!ReadChunk(hf, &tag, (PBYTE)pseq))
        !           517:                 goto laiFileErr;
        !           518:             break;
        !           519: 
        !           520: 
        !           521:         case FOURCC_LIST: {
        !           522:             DWORD cbChunk = PADUP(tag.ckSize);
        !           523: 
        !           524:             /*
        !           525:              * See if this list is the 'fram' list of icon chunks
        !           526:              */
        !           527:             if(!ReadFile(hf, &tag.ckID, sizeof(tag.ckID), &cbRead, NULL) ||
        !           528:                     cbRead < sizeof(tag.ckID)) {
        !           529:                 goto laiFileErr;
        !           530:             }
        !           531: 
        !           532:             cbChunk -= cbRead;
        !           533: 
        !           534:             if (tag.ckID == FOURCC_fram) {
        !           535: 
        !           536:                 while(cbChunk >= sizeof(tag)) {
        !           537:                     if (!ReadTag(hf, &tag))
        !           538:                         goto laiFileErr;
        !           539: 
        !           540:                     cbChunk -= sizeof(tag);
        !           541: 
        !           542:                     if(tag.ckID == FOURCC_icon) {
        !           543:                         PFRAME pfrm;
        !           544: 
        !           545:                         /*
        !           546:                          * Ok, load the icon/cursor bits,
        !           547:                          */
        !           548:                         pfrm = ReadIconFromFile(hwnd, hf, tag.ckSize);
        !           549: 
        !           550:                         if (pfrm == NULL) {
        !           551:                             goto laiFileErr;
        !           552:                         }
        !           553: 
        !           554:                         for( i = 0; i < (int)ganiAcon.anih.cSteps; i++ ) {
        !           555:                             if (pseq[i] == (DWORD)iFrame) {
        !           556:                                 ppfram[i] = pfrm;
        !           557:                             }
        !           558:                         }
        !           559: 
        !           560:                         iFrame++;
        !           561: 
        !           562:                     } else {
        !           563:                         /*
        !           564:                          * Unknown chunk in fram list, just ignore it
        !           565:                          */
        !           566:                         SkipChunk(hf, &tag);
        !           567:                     }
        !           568: 
        !           569:                     cbChunk -= PADUP(tag.ckSize);
        !           570:                 }
        !           571:             } else if (tag.ckID == FOURCC_INFO) {
        !           572:                 /* now look for INAM and IART chunks */
        !           573: 
        !           574:                 while( cbChunk >= sizeof(tag) ) {
        !           575: 
        !           576:                     if (!ReadTag(hf, &tag))
        !           577:                         goto laiFileErr;
        !           578: 
        !           579:                     cbChunk -= sizeof(tag);
        !           580: 
        !           581:                     switch( tag.ckID ) {
        !           582:                     case FOURCC_INAM:
        !           583:                         if (cbChunk < tag.ckSize ||
        !           584:                                 !ReadChunkN(hf, &tag, ganiAcon.azTitle,
        !           585:                                                 sizeof(ganiAcon.azTitle)))
        !           586:                             goto laiFileErr;
        !           587: 
        !           588:                         cbChunk -= PADUP(tag.ckSize);
        !           589:                         break;
        !           590: 
        !           591:                     case FOURCC_IART:
        !           592:                         if (cbChunk < tag.ckSize ||
        !           593:                                 !ReadChunkN(hf, &tag, ganiAcon.azCreator,
        !           594:                                         sizeof(ganiAcon.azCreator)))
        !           595:                             goto laiFileErr;
        !           596: 
        !           597:                         cbChunk -= PADUP(tag.ckSize);
        !           598:                         break;
        !           599: 
        !           600:                     default:
        !           601:                         if (!SkipChunk( hf, &tag ))
        !           602:                             goto laiFileErr;
        !           603: 
        !           604:                         cbChunk -= PADUP(tag.ckSize);
        !           605:                         break;
        !           606:                     }
        !           607:                 }
        !           608: 
        !           609:             } else {
        !           610:                 /*
        !           611:                  * Not the fram list or the INFO list.  Skip
        !           612:                  * the rest of this chunk.  (Don't forget that we have
        !           613:                  * already skipped one dword!)
        !           614:                  */
        !           615:                 tag.ckSize = cbChunk;
        !           616:                 SkipChunk(hf, &tag);
        !           617:                 break;
        !           618:             }
        !           619: 
        !           620:             break;
        !           621:         }
        !           622: 
        !           623: 
        !           624: 
        !           625:         default:
        !           626:             /*
        !           627:              * We're not interested in this chunk, skip it.
        !           628:              */
        !           629:             if(!SkipChunk(hf, &tag))
        !           630:                 goto laiFileErr;
        !           631:             break;
        !           632: 
        !           633:         }
        !           634: 
        !           635:     }
        !           636: 
        !           637:     /*
        !           638:      * Update the frame count incase we coalesced some frames while reading
        !           639:      * in the file.
        !           640:      */
        !           641:     ganiAcon.anih.cFrames = iFrame;
        !           642: 
        !           643:     /*
        !           644:      * Now build up the listbox
        !           645:      */
        !           646: 
        !           647:     for( i = 0; i < (int)ganiAcon.anih.cSteps; i++ ) {
        !           648:         PSTEP ps;
        !           649: 
        !           650:         ps = NewStep();
        !           651:         if (ps == NULL)
        !           652:             goto laiFileErr;
        !           653: 
        !           654:         ps->jif = pjifRate[i];
        !           655:         LinkStepFrame(ps, ppfram[i]);
        !           656: 
        !           657:         SendDlgItemMessage(hwnd, DLG_MAIN_FRAMELIST, LB_INSERTSTRING, i,
        !           658:                 (LPARAM)ps);
        !           659:     }
        !           660: 
        !           661:     SetDlgItemText(hwnd, DLG_MAIN_TITLE, ganiAcon.azTitle);
        !           662:     SetDlgItemText(hwnd, DLG_MAIN_AUTHOR, ganiAcon.azCreator);
        !           663: 
        !           664:     SendDlgItemMessage(hwnd, DLG_MAIN_PREVIEW, PM_NEWCURSOR, 0, 0);
        !           665:     fSuccess = TRUE;
        !           666: 
        !           667: laiFileErr:
        !           668: 
        !           669:     if (pjifRate != NULL)
        !           670:         FreeMem(pjifRate);
        !           671: 
        !           672:     if (!fSuccess)
        !           673:         NewAniCursor(hwnd);
        !           674: 
        !           675:     CloseHandle(hf);
        !           676: 
        !           677:     return fSuccess;
        !           678: }
        !           679: 
        !           680: 
        !           681: 
        !           682: /***************************************************************************\
        !           683: * DWORD CalcCheckSum( PBYTE pb );
        !           684: *
        !           685: *
        !           686: * History:
        !           687: *
        !           688: * 23-Apr-1993 JonPa     Created.
        !           689: \***************************************************************************/
        !           690: DWORD CalcCheckSum( PBYTE pb, DWORD cb ) {
        !           691:     DWORD dw = 0;
        !           692: 
        !           693:     while(cb--)
        !           694:         dw += (DWORD)*pb++;
        !           695: 
        !           696:     return dw;
        !           697: }
        !           698: 
        !           699: /***************************************************************************\
        !           700: * ReadTag, ReadChunk, SkipChunk
        !           701: *
        !           702: * Some handy functions for reading RIFF files.
        !           703: *
        !           704: * History:
        !           705: * 10-02-91 DarrinM      Created.
        !           706: * 03-25-93 Jonpa        Changed to use RIFF format instead of ASDF
        !           707: * 23-Apr-1993 JonPa     Copied from Win NT USER.
        !           708: \***************************************************************************/
        !           709: BOOL ReadTag(
        !           710:     HANDLE hf,
        !           711:     PRTAG ptag)
        !           712: {
        !           713:     DWORD cbActual;
        !           714: 
        !           715:     ptag->ckID = ptag->ckSize = 0L;
        !           716: 
        !           717:     if (!ReadFile(hf, ptag, sizeof(RTAG), &cbActual, NULL) ||
        !           718:             (cbActual != sizeof(RTAG)))
        !           719:         return FALSE;
        !           720: 
        !           721:     /* no need to align file pointer since RTAG is already word aligned */
        !           722:     return TRUE;
        !           723: }
        !           724: 
        !           725: 
        !           726: BOOL ReadChunk(
        !           727:     HANDLE hf,
        !           728:     PRTAG ptag,
        !           729:     PVOID pv)
        !           730: {
        !           731:     DWORD cbActual;
        !           732: 
        !           733:     if (!ReadFile(hf, pv, ptag->ckSize, &cbActual, NULL) ||
        !           734:             (cbActual != ptag->ckSize))
        !           735:         return FALSE;
        !           736: 
        !           737:     /* WORD align file pointer */
        !           738:     if( ptag->ckSize & 1 )
        !           739:         SetFilePointer(hf, 1, NULL, FILE_CURRENT);
        !           740: 
        !           741:     return TRUE;
        !           742: }
        !           743: 
        !           744: 
        !           745: BOOL ReadChunkN(
        !           746:     HANDLE hf,
        !           747:     PRTAG ptag,
        !           748:     PVOID pv,
        !           749:     DWORD cbMax)
        !           750: {
        !           751:     DWORD cbActual;
        !           752:     DWORD cbRead = min( cbMax, ptag->ckSize );
        !           753: 
        !           754:     if (!ReadFile(hf, pv, ptag->ckSize, &cbActual, NULL) ||
        !           755:             (cbActual != cbRead))
        !           756:         return FALSE;
        !           757: 
        !           758:     /* WORD align file pointer */
        !           759: 
        !           760:     cbRead = ptag->ckSize - cbActual;
        !           761: 
        !           762:     if( ptag->ckSize & 1 )
        !           763:         cbRead++;
        !           764: 
        !           765:     return SetFilePointer(hf, cbRead, NULL, FILE_CURRENT) != 0xFFFFFFFF;
        !           766: }
        !           767: 
        !           768: BOOL SkipChunk(
        !           769:     HANDLE hf,
        !           770:     PRTAG ptag)
        !           771: {
        !           772:     /* Round ptag->ckSize up to nearest word boundary to maintain alignment */
        !           773:     return SetFilePointer(hf, PADUP(ptag->ckSize), NULL, FILE_CURRENT) !=
        !           774:             0xFFFFFFFFL;
        !           775: }
        !           776: 
        !           777: /****************************************************************************\
        !           778: *
        !           779: *     FUNCTION: VOID GetTempCursorFileName( szFileName );
        !           780: *
        !           781: *     PURPOSE:  Create a temporary .cur filename
        !           782: *
        !           783: *
        !           784: * History:
        !           785: *   22-Apr-1993 JonPa   Created it
        !           786: *
        !           787: \****************************************************************************/
        !           788: BOOL GetTempCursorFileName( LPTSTR pszName ) {
        !           789:     TCHAR szPath[MAX_PATH];
        !           790: 
        !           791:     if( GetTempPath( MAX_PATH, szPath ) >= MAX_PATH )
        !           792:         lstrcpy( pszName, TEXT(".") );
        !           793: 
        !           794: 
        !           795:     return GetTempFileName(szPath, TEXT("ae"), 0, pszName) != 0;
        !           796: }
        !           797: 
        !           798: /****************************************************************************\
        !           799: *
        !           800: *     FUNCTION: BOOL SaveAniFile( HWND hwnd, HANDLE hf )
        !           801: *
        !           802: *     PURPOSE:
        !           803: &
        !           804: *   Saves an animatied cursor to a RIFF file.  The RIFF file format for
        !           805: *   animated cursors looks like this:
        !           806: *
        !           807: *   RIFF( 'ACON'
        !           808: *       [LIST( 'INFO'
        !           809: *           [INAM( <name> )]
        !           810: *           [IART( <artist> )]
        !           811: *       )]
        !           812: *       anih( <anihdr> )
        !           813: *       [rate( <rateinfo> )  ]
        !           814: *       ['seq '( <seq_info> )]
        !           815: *       LIST( 'fram' icon( <icon_file> ) )
        !           816: *   )
        !           817: *
        !           818: *
        !           819: * History:
        !           820: *   29-Apr-1993 JonPa   Created it.
        !           821: *
        !           822: \****************************************************************************/
        !           823: BOOL SaveAniFile( HWND hwnd, HANDLE hf ) {
        !           824:     int cSteps, i;
        !           825:     int cFrames;
        !           826:     PFRAME pf;
        !           827:     DWORD cbFile, cbFram, cbINFO, cbTitle, cbAuthor;
        !           828:     BOOL fRate, fSeq;
        !           829:     RTAG rtag;
        !           830:     PJIF pjif;
        !           831:     DWORD *pseq;
        !           832:     PFRAME *pfrm;
        !           833: 
        !           834:     fRate = fSeq = FALSE;
        !           835:     cbINFO = cbFram = cbFile = cbTitle = cbAuthor = 0;
        !           836: 
        !           837:     PausePreview(hwnd, DLG_MAIN_PREVIEW);
        !           838: 
        !           839:     cSteps = GetStepCount(hwnd);
        !           840: 
        !           841:     if( cSteps == LB_ERR ) {
        !           842:         FmtMessageBox( ghwndMain, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
        !           843:                 TRUE, MSG_OUTOFRESOUCES );
        !           844:         return FALSE;
        !           845:     }
        !           846: 
        !           847:     cFrames = 0;
        !           848:     for( pf = gpfrmFrames; pf != NULL; pf = pf->pfrmNext ) {
        !           849:         pf->iFrame = -1;
        !           850:         cFrames++;
        !           851:     }
        !           852: 
        !           853:     ganiAcon.anih.cSteps = cSteps;
        !           854: 
        !           855:     pjif = AllocMem( (sizeof(JIF) + sizeof(DWORD) + sizeof(PFRAME)) * cSteps );
        !           856: 
        !           857:     if(pjif == NULL)
        !           858:         return FALSE;
        !           859: 
        !           860:     pseq = (DWORD *)&pjif[cSteps];
        !           861:     pfrm = (PFRAME *)&pseq[cSteps];
        !           862: 
        !           863:     cFrames = 0;
        !           864: 
        !           865:     for( i = 0; i < cSteps; i++ ) {
        !           866:         PSTEP ps;
        !           867: 
        !           868:         ps = GetStep(hwnd, i);
        !           869: 
        !           870:         if( IsValidPS(ps) ) {
        !           871: 
        !           872:             if (ps->pfrmFrame->iFrame == -1) {
        !           873: 
        !           874:                 cbFram += sizeof(RTAG);
        !           875:                 cbFram += PADUP(ps->pfrmFrame->rtag.ckSize);
        !           876: 
        !           877:                 ps->pfrmFrame->iFrame = cFrames;
        !           878:                 pfrm[cFrames++] = ps->pfrmFrame;
        !           879: 
        !           880:             } else
        !           881:                 fSeq = TRUE;
        !           882: 
        !           883:             pseq[i] = ps->pfrmFrame->iFrame;
        !           884: 
        !           885:             if ((pjif[i] = ps->jif) != ganiAcon.anih.jifRate) {
        !           886:                 fRate = TRUE;
        !           887:             }
        !           888:         }
        !           889:     }
        !           890: 
        !           891:     ganiAcon.anih.cbSizeof = sizeof(ganiAcon.anih);
        !           892:     ganiAcon.anih.cFrames = cFrames;
        !           893:     ganiAcon.anih.fl = AF_ICON | (fSeq ? AF_SEQUENCE : 0);
        !           894: 
        !           895:     cbTitle = GetDlgItemTextA(hwnd, DLG_MAIN_TITLE, ganiAcon.azTitle,
        !           896:                             COUNTOF(ganiAcon.azTitle));
        !           897: 
        !           898:     cbAuthor = GetDlgItemTextA(hwnd, DLG_MAIN_AUTHOR, ganiAcon.azCreator,
        !           899:                             COUNTOF(ganiAcon.azCreator));
        !           900: 
        !           901:     /*
        !           902:      * At this point, cbFram == the size required by all the frames,
        !           903:      * add in the rate, seq, anih, and INFO list sizes as well as
        !           904:      * all the other overhead.
        !           905:      */
        !           906: 
        !           907:     cbFram += sizeof(FOURCC);     //fram type
        !           908: 
        !           909:     cbFile = cbFram;
        !           910: 
        !           911:     cbFile +=   sizeof(RTAG) +      //RIFF tag
        !           912:                 sizeof(FOURCC) +    //ACON type
        !           913:                     sizeof(RTAG) +      //anih tag
        !           914:                         PADUP(sizeof(ANIHEADER)) +
        !           915:                     sizeof(RTAG);       //LIST tag (for fram list)
        !           916: 
        !           917: 
        !           918:     if( cbTitle || cbAuthor) {
        !           919:         /*
        !           920:          * Remember, azCreator, and azTitle are ANSI strings!
        !           921:          */
        !           922:         if( cbTitle ) {
        !           923:             cbTitle = PADUP( cbTitle * sizeof(char));
        !           924:             cbINFO +=   sizeof(RTAG) +     //INAM tag
        !           925:                         cbTitle;
        !           926:         }
        !           927: 
        !           928:         if (cbAuthor) {
        !           929:             cbAuthor = PADUP(cbAuthor * sizeof(char));
        !           930:             cbINFO +=   sizeof(RTAG) +     //IART tag
        !           931:                         cbAuthor;
        !           932:         }
        !           933: 
        !           934:         cbINFO +=  sizeof(FOURCC);      //INFO type
        !           935: 
        !           936:         cbFile +=   sizeof(RTAG) +      //LIST tag
        !           937:                     cbINFO;
        !           938:     }
        !           939: 
        !           940: 
        !           941:     if (fSeq) {
        !           942:         cbFile += sizeof(RTAG) +    //seq tag
        !           943:                     PADUP(cSteps * sizeof(DWORD));
        !           944:     }
        !           945: 
        !           946:     if (fRate) {
        !           947:         cbFile += sizeof(RTAG) +    //rate tag
        !           948:                     PADUP(cSteps * sizeof(JIF));
        !           949:     }
        !           950: 
        !           951:     /*
        !           952:      * Now we have all the structures built in memory, it's time to
        !           953:      * write them out in RIFF ACON format!
        !           954:      */
        !           955:     rtag.ckID = FOURCC_RIFF;
        !           956:     rtag.ckSize = cbFile;
        !           957: 
        !           958:     RET_CLOSE_IF_ERR( WriteTag(hf, &rtag), hf );
        !           959: 
        !           960:     RET_CLOSE_IF_ERR( WriteType(hf, FOURCC_ACON), hf );
        !           961: 
        !           962:     if( cbTitle || cbAuthor) {
        !           963:         rtag.ckID = FOURCC_LIST;
        !           964:         rtag.ckSize = cbINFO;
        !           965: 
        !           966:         RET_CLOSE_IF_ERR( WriteTag(hf, &rtag), hf );
        !           967: 
        !           968:         RET_CLOSE_IF_ERR( WriteType(hf, FOURCC_INFO), hf );
        !           969: 
        !           970:         if (cbTitle) {
        !           971:             rtag.ckID = FOURCC_INAM;
        !           972:             rtag.ckSize = cbTitle;
        !           973:             RET_CLOSE_IF_ERR( WriteTagData(hf, &rtag, ganiAcon.azTitle), hf );
        !           974:         }
        !           975: 
        !           976:         if (cbAuthor) {
        !           977:             rtag.ckID = FOURCC_IART;
        !           978:             rtag.ckSize = cbAuthor;
        !           979:             RET_CLOSE_IF_ERR( WriteTagData(hf, &rtag, ganiAcon.azCreator), hf );
        !           980:         }
        !           981:     }
        !           982: 
        !           983:     /* write anih */
        !           984:     rtag.ckID = FOURCC_anih;
        !           985:     rtag.ckSize = sizeof(ganiAcon.anih);
        !           986: 
        !           987:     RET_CLOSE_IF_ERR( WriteTagData(hf, &rtag, &(ganiAcon.anih)), hf );
        !           988: 
        !           989:     /* if rate then write it */
        !           990:     if (fRate) {
        !           991:         rtag.ckID = FOURCC_rate;
        !           992:         rtag.ckSize = cSteps * sizeof(JIF);
        !           993: 
        !           994:         RET_CLOSE_IF_ERR( WriteTagData(hf, &rtag, pjif), hf );
        !           995:     }
        !           996: 
        !           997:     /* if seq, then write it */
        !           998:     if (fSeq) {
        !           999:         rtag.ckID = FOURCC_seq;
        !          1000:         rtag.ckSize = cSteps * sizeof(DWORD);
        !          1001: 
        !          1002:         RET_CLOSE_IF_ERR( WriteTagData(hf, &rtag, pseq), hf );
        !          1003:     }
        !          1004: 
        !          1005:     /* write the fram list */
        !          1006:     rtag.ckID = FOURCC_LIST;
        !          1007:     rtag.ckSize = cbFram;
        !          1008: 
        !          1009:     RET_CLOSE_IF_ERR( WriteTag(hf, &rtag), hf );
        !          1010:     RET_CLOSE_IF_ERR( WriteType(hf, FOURCC_fram), hf );
        !          1011: 
        !          1012:     for( i = 0; i < cFrames; i++ ) {
        !          1013:         RET_CLOSE_IF_ERR( WriteTagData(hf, &(pfrm[i]->rtag), pfrm[i]->abIcon),
        !          1014:                 hf);
        !          1015:     }
        !          1016: 
        !          1017:     /* Close the file */
        !          1018:     CloseHandle(hf);
        !          1019: 
        !          1020:     return TRUE;
        !          1021: }
        !          1022: 
        !          1023: 
        !          1024: /***************************************************************************\
        !          1025: * WriteTag, WriteType, WriteTagData
        !          1026: *
        !          1027: * Some handy functions for writing RIFF files.
        !          1028: *
        !          1029: * History:
        !          1030: *   30-Apr-1993 JonPa   Created them.
        !          1031: \***************************************************************************/
        !          1032: BOOL WriteTag(HANDLE hf, PRTAG prtag) {
        !          1033:     DWORD cbWritten;
        !          1034: 
        !          1035:     return (WriteFile(hf, prtag, sizeof(RTAG), &cbWritten, NULL) &&
        !          1036:             cbWritten == sizeof(RTAG));
        !          1037: }
        !          1038: 
        !          1039: BOOL WriteType(HANDLE hf, FOURCC ckID ) {
        !          1040:     DWORD cbWritten;
        !          1041: 
        !          1042:     return (WriteFile(hf, &ckID, sizeof(FOURCC), &cbWritten, NULL) &&
        !          1043:             cbWritten == sizeof(FOURCC));
        !          1044: }
        !          1045: 
        !          1046: BOOL WriteTagData(HANDLE hf, PRTAG prtag, VOID *pvData ) {
        !          1047:     DWORD cbWritten;
        !          1048:     DWORD cbWrite = PADUP(prtag->ckSize);
        !          1049: 
        !          1050:     return  WriteTag(hf, prtag) && WriteFile(hf, pvData, cbWrite,
        !          1051:             &cbWritten, NULL) && cbWritten == cbWrite;
        !          1052: }
        !          1053: 
        !          1054: 
        !          1055: 
        !          1056: 
        !          1057: /***************************************************************************\
        !          1058: * VOID SaveFile(HWND hwnd, BOOL fPrompt)
        !          1059: *
        !          1060: * Conditionally Prompt the user for a name and then save the file
        !          1061: *
        !          1062: * History:
        !          1063: *   04-May-1993 JonPa   It
        !          1064: \***************************************************************************/
        !          1065: VOID SaveFile(HWND hwnd, BOOL fPrompt) {
        !          1066:     TCHAR szFileTitle[MAX_PATH];
        !          1067:     HANDLE hf;
        !          1068: 
        !          1069:     szFileTitle[0] = TEXT('\0');
        !          1070: 
        !          1071:     if (fPrompt || ganiAcon.szFile[0] == TEXT('\0')) {
        !          1072: tryagain:
        !          1073:         if (!PromptForFile(hwnd, COUNTOF(szFileTitle), szFileTitle,
        !          1074:                 COUNTOF(ganiAcon.szFile), ganiAcon.szFile, gpszAniFilter,
        !          1075:                 NULL, TRUE)) {
        !          1076:             return;
        !          1077:         }
        !          1078:     }
        !          1079: 
        !          1080:     hf = CreateFile( ganiAcon.szFile, GENERIC_WRITE, 0, NULL,
        !          1081:             CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        !          1082: 
        !          1083:     if (hf == INVALID_HANDLE_VALUE) {
        !          1084:         FmtMessageBox(hwnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP, TRUE,
        !          1085:                 MSG_CANTCREATEFILE, ganiAcon.szFile);
        !          1086: 
        !          1087:         goto tryagain;
        !          1088:     }
        !          1089: 
        !          1090:     if( !SaveAniFile(hwnd, hf) ) {
        !          1091:         FmtMessageBox(hwnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP, TRUE,
        !          1092:                 MSG_FILEWRITEERR, ganiAcon.szFile);
        !          1093:         return;
        !          1094:     }
        !          1095: 
        !          1096:     if (szFileTitle[0] != TEXT('\0'))
        !          1097:         SetWindowFileTitle(hwnd, szFileTitle);
        !          1098: 
        !          1099:     ganiAcon.fDirty = FALSE;
        !          1100: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.