Annotation of mstools/ole20/samples/ole2ui/drawicon.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * DRAWICON.C 
                      3:  *
                      4:  * Functions to handle creation of metafiles with icons and labels
                      5:  * as well as functions to draw such metafiles with or without the label.
                      6:  *
                      7:  * The metafile is created with a comment that marks the records containing
                      8:  * the label code.  Drawing the metafile enumerates the records, draws
                      9:  * all records up to that point, then decides to either skip the label
                     10:  * or draw it.
                     11:  *
                     12:  * Copyright (c)1992 Microsoft Corporation, All Right Reserved
                     13:  */
                     14: 
                     15: #define STRICT  1
                     16: #include "ole2ui.h"
                     17: #include "common.h"
                     18: #include "utility.h"
                     19: #include "geticon.h"
                     20: 
                     21: /*
                     22:  * Strings for metafile comments.  KEEP THESE IN SYNC WITH THE
                     23:  * STRINGS IN GETICON.C.
                     24:  */
                     25: 
                     26: static char szIconOnly[]="IconOnly";        //Where to stop to exclude label.
                     27: 
                     28: 
                     29: 
                     30: 
                     31: /*
                     32:  * OleUIMetafilePictIconFree
                     33:  *
                     34:  * Purpose:
                     35:  *  Deletes the metafile contained in a METAFILEPICT structure and
                     36:  *  frees the memory for the structure itself.
                     37:  *
                     38:  * Parameters:
                     39:  *  hMetaPict       HGLOBAL metafilepict structure created in
                     40:  *                  OleUIMetafilePictFromIconAndLabel
                     41:  *
                     42:  * Return Value:
                     43:  *  None
                     44:  */
                     45: 
                     46: STDAPI_(void) OleUIMetafilePictIconFree(HGLOBAL hMetaPict)
                     47:     {
                     48:     LPMETAFILEPICT      pMF;
                     49: 
                     50:     if (NULL==hMetaPict)
                     51:         return;
                     52: 
                     53:     pMF=(LPMETAFILEPICT)GlobalLock(hMetaPict);
                     54: 
                     55:     if (NULL!=pMF)
                     56:         {
                     57:         if (NULL!=pMF->hMF)
                     58:             DeleteMetaFile(pMF->hMF);
                     59:         }
                     60: 
                     61:     GlobalUnlock(hMetaPict);
                     62:     GlobalFree(hMetaPict);
                     63:     return;
                     64:     }
                     65: 
                     66: 
                     67: 
                     68: 
                     69: 
                     70: 
                     71: 
                     72: 
                     73: /*
                     74:  * OleUIMetafilePictIconDraw
                     75:  *
                     76:  * Purpose:
                     77:  *  Draws the metafile from OleUIMetafilePictFromIconAndLabel, either with
                     78:  *  the label or without.
                     79:  *
                     80:  * Parameters:
                     81:  *  hDC             HDC on which to draw.
                     82:  *  pRect           LPRECT in which to draw the metafile.
                     83:  *  hMetaPict       HGLOBAL to the METAFILEPICT from
                     84:  *                  OleUIMetafilePictFromIconAndLabel
                     85:  *  fIconOnly       BOOL specifying to draw the label or not.
                     86:  *
                     87:  * Return Value:
                     88:  *  BOOL            TRUE if the function is successful, FALSE if the
                     89:  *                  given metafilepict is invalid.
                     90:  */
                     91: 
                     92: STDAPI_(BOOL) OleUIMetafilePictIconDraw(HDC hDC, LPRECT pRect, HGLOBAL hMetaPict
                     93:                                       , BOOL fIconOnly)
                     94:     {
                     95:     LPMETAFILEPICT  pMF;
                     96:     DRAWINFO        di;
                     97:     int             cx, cy;
                     98:     SIZE            size;
                     99:     POINT           point;
                    100: 
                    101:     if (NULL==hMetaPict)
                    102:         return FALSE;
                    103: 
                    104:     pMF=GlobalLock(hMetaPict);
                    105: 
                    106:     if (NULL==pMF)
                    107:         return FALSE;
                    108: 
                    109:     di.Rect = *pRect;
                    110:     di.fIconOnly = fIconOnly;
                    111: 
                    112:     //Transform to back to pixels
                    113:     cx=XformWidthInHimetricToPixels(hDC, pMF->xExt);
                    114:     cy=XformHeightInHimetricToPixels(hDC, pMF->yExt);
                    115: 
                    116:     SetMapMode(hDC, pMF->mm);
                    117:     SetViewportOrgEx(hDC, (pRect->right - cx) / 2, 0, &point);
                    118: 
                    119:     SetViewportExtEx(hDC, min ((pRect->right - cx) / 2 + cx, cx), cy, &size);
                    120: 
                    121:     if (fIconOnly)
                    122:         {
                    123:         // Since we've used the __export keyword on the
                    124:         // EnumMetafileIconDraw proc, we do not need to use
                    125:         // MakeProcInstance
                    126:         EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileIconDraw
                    127:             , (LPARAM)(LPDRAWINFO)&di);
                    128:         }
                    129:     else
                    130:        PlayMetaFile(hDC, pMF->hMF);
                    131: 
                    132:     GlobalUnlock(hMetaPict);
                    133:     return TRUE;
                    134:     }
                    135: 
                    136: 
                    137: 
                    138: 
                    139: /*
                    140:  * EnumMetafileIconDraw
                    141:  *
                    142:  * Purpose:
                    143:  *  EnumMetaFile callback function that draws either the icon only or
                    144:  *  the icon and label depending on given flags.
                    145:  *
                    146:  * Parameters:
                    147:  *  hDC             HDC into which the metafile should be played.
                    148:  *  phTable         HANDLETABLE FAR * providing handles selected into the DC.
                    149:  *  pMFR            METARECORD FAR * giving the enumerated record.
                    150:  *  lParam          LPARAM flags passed in EnumMetaFile.
                    151:  *
                    152:  * Return Value:
                    153:  *  int             0 to stop enumeration, 1 to continue.
                    154:  */
                    155: 
                    156: int CALLBACK EXPORT EnumMetafileIconDraw(HDC hDC, HANDLETABLE FAR *phTable
                    157:     , METARECORD FAR *pMFR, int cObj, LPARAM lParam)
                    158:     {
                    159:     LPDRAWINFO lpdi = (LPDRAWINFO)lParam;
                    160: 
                    161:     /*
                    162:      * We play everything blindly except for DIBBITBLT (or DIBSTRETCHBLT)
                    163:      * and ESCAPE with MFCOMMENT.  For the BitBlts we change the x,y to
                    164:      * draw at (0,0) instead of wherever it was written to draw.  The
                    165:      * comment tells us there to stop if we don't want to draw the label.
                    166:      */
                    167: 
                    168:     //If we're playing icon only, stop enumeration at the comment.
                    169:     if (lpdi->fIconOnly)
                    170:         {
                    171:         if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0])
                    172:             {
                    173:             if (0==lstrcmpi(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
                    174:                 return 0;
                    175:             }
                    176: 
                    177:         /*
                    178:          * Check for the records in which we want to munge the coordinates.
                    179:          * destX is offset 6 for BitBlt, offset 9 for StretchBlt, either of
                    180:          * which may appear in the metafile.
                    181:          */
                    182:         if (META_DIBBITBLT==pMFR->rdFunction)
                    183:             pMFR->rdParm[6]=0;
                    184: 
                    185:         if (META_DIBSTRETCHBLT==pMFR->rdFunction)
                    186:               pMFR->rdParm[9] = 0;
                    187: 
                    188:         }
                    189: 
                    190: 
                    191:     PlayMetaFileRecord(hDC, phTable, pMFR, cObj);
                    192:     return 1;
                    193:     }
                    194: 
                    195: 
                    196: 
                    197: 
                    198: 
                    199: /*
                    200:  * OleUIMetafilePictExtractLabel
                    201:  *
                    202:  * Purpose:
                    203:  *  Retrieves the label string from metafile representation of an icon.
                    204:  *
                    205:  * Parameters:
                    206:  *  hMetaPict       HGLOBAL to the METAFILEPICT containing the metafile.
                    207:  *  lpszLabel       LPSTR in which to store the label.
                    208:  *  cchLabel        UINT length of lpszLabel.
                    209:  *  lpWrapIndex     DWORD index of first character in last line. Can be NULL
                    210:  *                  if calling function doesn't care about word wrap.
                    211:  *
                    212:  * Return Value:
                    213:  *  UINT            Number of characters copied.
                    214:  */
                    215: STDAPI_(UINT) OleUIMetafilePictExtractLabel(HGLOBAL hMetaPict, LPSTR lpszLabel
                    216:                                           , UINT cchLabel, LPDWORD lpWrapIndex)
                    217:     {
                    218:     LPMETAFILEPICT  pMF;
                    219:     LABELEXTRACT    le;
                    220:     HDC             hDC;
                    221: 
                    222:     /*
                    223:      * We extract the label by getting a screen DC and walking the metafile
                    224:      * records until we see the ExtTextOut record we put there.  That
                    225:      * record will have the string embedded in it which we then copy out.
                    226:      */
                    227: 
                    228:     if (NULL==hMetaPict || NULL==lpszLabel || 0==cchLabel)
                    229:         return FALSE;
                    230: 
                    231:     pMF=GlobalLock(hMetaPict);
                    232: 
                    233:     if (NULL==pMF)
                    234:         return FALSE;
                    235: 
                    236:     le.lpsz=lpszLabel;
                    237:     le.u.cch=cchLabel;
                    238:     le.Index=0;
                    239:     le.fFoundIconOnly=FALSE;
                    240:     le.fFoundSource=FALSE;  //Unused for this function.
                    241:     le.fFoundIndex=FALSE;   //Unused for this function.
                    242:     le.PrevIndex = 0;
                    243: 
                    244:     //Use a screen DC so we have something valid to pass in.
                    245:     hDC=GetDC(NULL);
                    246: 
                    247:     // Since we've used the EXPORT keyword on the
                    248:     // EnumMetafileExtractLabel proc, we do not need to use
                    249:     // MakeProcInstance
                    250: 
                    251:     EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractLabel, (LONG)(LPLABELEXTRACT)&le);
                    252: 
                    253:     ReleaseDC(NULL, hDC);
                    254: 
                    255:     GlobalUnlock(hMetaPict);
                    256: 
                    257:     //Tell where we wrapped (if calling function cares)
                    258:     if (NULL != lpWrapIndex)
                    259:        *lpWrapIndex = le.PrevIndex;
                    260: 
                    261:     //Return amount of text copied
                    262:     return le.u.cch;
                    263:     }
                    264: 
                    265: 
                    266: 
                    267: 
                    268: 
                    269: /*
                    270:  * EnumMetafileExtractLabel
                    271:  *
                    272:  * Purpose:
                    273:  *  EnumMetaFile callback function that walks a metafile looking for
                    274:  *  ExtTextOut, then concatenates the text from each one into a buffer 
                    275:  *  in lParam.
                    276:  *
                    277:  * Parameters:
                    278:  *  hDC             HDC into which the metafile should be played.
                    279:  *  phTable         HANDLETABLE FAR * providing handles selected into the DC.
                    280:  *  pMFR            METARECORD FAR * giving the enumerated record.
                    281:  *  pLE             LPLABELEXTRACT providing the destination buffer and length.
                    282:  *
                    283:  * Return Value:
                    284:  *  int             0 to stop enumeration, 1 to continue.
                    285:  */
                    286: 
                    287: int CALLBACK EXPORT EnumMetafileExtractLabel(HDC hDC, HANDLETABLE FAR *phTable
                    288:     , METARECORD FAR *pMFR, int cObj, LPLABELEXTRACT pLE)
                    289:     {
                    290: 
                    291:     /*
                    292:      * We don't allow anything to happen until we see "IconOnly"
                    293:      * in an MFCOMMENT that is used to enable everything else.
                    294:      */
                    295:     if (!pLE->fFoundIconOnly)
                    296:         {
                    297:         if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0])
                    298:             {
                    299:             if (0==lstrcmpi(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
                    300:                 pLE->fFoundIconOnly=TRUE;
                    301:             }
                    302: 
                    303:         return 1;
                    304:         }
                    305: 
                    306:     //Enumerate all records looking for META_EXTTEXTOUT - there can be more
                    307:     //than one.
                    308:     if (META_EXTTEXTOUT==pMFR->rdFunction)
                    309:         {
                    310:         UINT        cchMax;
                    311:         LPSTR       lpszTemp;
                    312: 
                    313:         /*
                    314:          * If ExtTextOut has NULL fuOptions, then the rectangle is omitted
                    315:          * from the record, and the string starts at rdParm[4].  If
                    316:          * fuOptions is non-NULL, then the string starts at rdParm[8] 
                    317:          * (since the rectange takes up four WORDs in the array).  In
                    318:          * both cases, the string continues for (rdParm[2]+1) >> 1
                    319:          * words.  We just cast a pointer to rdParm[8] to an LPSTR and
                    320:          * lstrcpyn into the buffer we were given.
                    321:          *
                    322:          * Note that we use element 8 in rdParm instead of 4 because we
                    323:          * passed ETO_CLIPPED in for the options on ExtTextOut--docs say 
                    324:          * [4] which is rect doesn't exist if we passed zero there.
                    325:          *
                    326:          */
                    327: 
                    328:         cchMax=min(pLE->u.cch - pLE->Index, (UINT)pMFR->rdParm[2]);
                    329:         lpszTemp = pLE->lpsz + pLE->Index;
                    330:         
                    331:         lstrcpyn(lpszTemp, (LPSTR)&(pMFR->rdParm[8]), cchMax + 1);
                    332: //        lstrcpyn(lpszTemp, (LPSTR)&(pMFR->rdParm[4]), cchMax + 1);
                    333: 
                    334:         pLE->PrevIndex = pLE->Index;
                    335: 
                    336:         pLE->Index += cchMax;
                    337:         }
                    338: 
                    339:     return 1;
                    340:     }
                    341: 
                    342: 
                    343: 
                    344: 
                    345: 
                    346: /*
                    347:  * OleUIMetafilePictExtractIcon
                    348:  *
                    349:  * Purpose:
                    350:  *  Retrieves the icon from metafile into which DrawIcon was done before.
                    351:  *
                    352:  * Parameters:
                    353:  *  hMetaPict       HGLOBAL to the METAFILEPICT containing the metafile.
                    354:  *
                    355:  * Return Value:
                    356:  *  HICON           Icon recreated from the data in the metafile.
                    357:  */
                    358: STDAPI_(HICON) OleUIMetafilePictExtractIcon(HGLOBAL hMetaPict)
                    359:     {
                    360:     LPMETAFILEPICT  pMF;
                    361:     HDC             hDC;
                    362:     ICONEXTRACT     ie;
                    363: 
                    364:     /*
                    365:      * We extract the label by getting a screen DC and walking the metafile
                    366:      * records until we see the ExtTextOut record we put there.  That
                    367:      * record will have the string embedded in it which we then copy out.
                    368:      */
                    369: 
                    370:     if (NULL==hMetaPict)
                    371:         return NULL;
                    372: 
                    373:     pMF=GlobalLock(hMetaPict);
                    374: 
                    375:     if (NULL==pMF)
                    376:         return FALSE;
                    377: 
                    378:     //Use a screen DC so we have something valid to pass in.
                    379:     hDC=GetDC(NULL);
                    380:     ie.fAND=TRUE;
                    381: 
                    382:     // We get information back in the ICONEXTRACT structure.
                    383:     // (Since we've used the EXPORT keyword on the
                    384:     // EnumMetafileExtractLabel proc, we do not need to use
                    385:     // MakeProcInstance)
                    386:     EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIcon, (LONG)(LPICONEXTRACT)&ie);
                    387: 
                    388:     ReleaseDC(NULL, hDC);
                    389:     GlobalUnlock(hMetaPict);
                    390: 
                    391:     return ie.hIcon;
                    392:     }
                    393: 
                    394: 
                    395: 
                    396: 
                    397: 
                    398: /*
                    399:  * EnumMetafileExtractIcon
                    400:  *
                    401:  * Purpose:
                    402:  *  EnumMetaFile callback function that walks a metafile looking for
                    403:  *  StretchBlt (3.1) and BitBlt (3.0) records.  We expect to see two
                    404:  *  of them, the first being the AND mask and the second being the XOR
                    405:  *  data.  We
                    406:  *  ExtTextOut, then copies the text into a buffer in lParam.
                    407:  *
                    408:  * Parameters:
                    409:  *  hDC             HDC into which the metafile should be played.
                    410:  *  phTable         HANDLETABLE FAR * providing handles selected into the DC.
                    411:  *  pMFR            METARECORD FAR * giving the enumerated record.
                    412:  *  pIE             LPICONEXTRACT providing the destination buffer and length.
                    413:  *
                    414:  * Return Value:
                    415:  *  int             0 to stop enumeration, 1 to continue.
                    416:  */
                    417: 
                    418: int CALLBACK EXPORT EnumMetafileExtractIcon(HDC hDC, HANDLETABLE FAR *phTable
                    419:     , METARECORD FAR *pMFR, int cObj, LPICONEXTRACT pIE)
                    420:     {
                    421:     LPBITMAPINFO        lpBI;
                    422:     LPBITMAPINFOHEADER  lpBH;
                    423:     LPBYTE              lpbSrc;
                    424:     LPBYTE              lpbDst;
                    425:     UINT                uWidth, uHeight;
                    426:     DWORD               cb;
                    427:     HGLOBAL             hMem;
                    428:     BITMAP              bm;
                    429:     HBITMAP             hBmp;
                    430:     int                 cxIcon, cyIcon;
                    431: 
                    432: 
                    433:     //Continue enumeration if we don't see the records we want.
                    434:     if (META_DIBBITBLT!=pMFR->rdFunction && META_DIBSTRETCHBLT!=pMFR->rdFunction)
                    435:         return 1;
                    436: 
                    437:     /*
                    438:      * Windows 3.0 DrawIcon uses META_DIBBITBLT in whereas 3.1 uses
                    439:      * META_DIBSTRETCHBLT so we have to handle each case separately.
                    440:      */
                    441: 
                    442:     if (META_DIBBITBLT==pMFR->rdFunction)       //Win3.0
                    443:         {
                    444:         //Get dimensions and the BITMAPINFO struct.
                    445:         uHeight=pMFR->rdParm[1];
                    446:         uWidth =pMFR->rdParm[2];
                    447:         lpBI=(LPBITMAPINFO)&(pMFR->rdParm[8]);
                    448:         }
                    449: 
                    450:     if (META_DIBSTRETCHBLT==pMFR->rdFunction)   //Win3.1
                    451:         {
                    452:         //Get dimensions and the BITMAPINFO struct.
                    453:         uHeight=pMFR->rdParm[2];
                    454:         uWidth =pMFR->rdParm[3];
                    455:         lpBI=(LPBITMAPINFO)&(pMFR->rdParm[10]);
                    456:         }
                    457: 
                    458:     lpBH=(LPBITMAPINFOHEADER)&(lpBI->bmiHeader);
                    459: 
                    460:     //Pointer to the bits which follows the BITMAPINFO structure.
                    461:     lpbSrc=(LPBYTE)lpBI+sizeof(BITMAPINFOHEADER);
                    462: 
                    463:     //Add the length of the color table.
                    464:     if (0!=lpBH->biClrUsed)
                    465:         lpbSrc+=(DWORD)(lpBH->biClrUsed*sizeof(RGBQUAD));
                    466:     else
                    467:         {
                    468:         //1 << bc gives 2, 16, 256 for 1, 4, or 256 colors
                    469:         lpbSrc+=(DWORD)((1 << (lpBH->biBitCount))*sizeof(RGBQUAD));
                    470:         }
                    471: 
                    472: 
                    473:     /*
                    474:      * All the bits we have in lpbSrc are device-independent, so we
                    475:      * need to change them over to be device-dependent using SetDIBits.
                    476:      * Once we have a bitmap with the device-dependent bits, we can
                    477:      * GetBitmapBits to have buffers with the real data.
                    478:      *
                    479:      * For each pass we have to allocate memory for the bits.  We save
                    480:      * the memory for the mask between passes.
                    481:      */
                    482: 
                    483:     //Use CreateBitmap for ANY monochrome bitmaps
                    484:     if (pIE->fAND || 1==lpBH->biBitCount || lpBH->biBitCount > 8)
                    485:         hBmp=CreateBitmap((UINT)lpBH->biWidth, (UINT)lpBH->biHeight, 1, 1, NULL);
                    486:     else if (lpBH->biBitCount <= 8)
                    487:         hBmp=CreateCompatibleBitmap(hDC, (UINT)lpBH->biWidth, (UINT)lpBH->biHeight);
                    488: 
                    489:     if (!hBmp || !SetDIBits(hDC, hBmp, 0, (UINT)lpBH->biHeight, (LPVOID)lpbSrc, lpBI, DIB_RGB_COLORS))
                    490:         {
                    491:         if (!pIE->fAND)
                    492:             GlobalFree(pIE->hMemAND);
                    493: 
                    494:         DeleteObject(hBmp);
                    495:         return 0;
                    496:         }
                    497: 
                    498:     //Allocate memory and get the DDBits into it.
                    499:     GetObject(hBmp, sizeof(bm), &bm);
                    500: 
                    501:     cb=bm.bmHeight*bm.bmWidthBytes * bm.bmPlanes; 
                    502: 
                    503: //    if (cb % 4 != 0)        // dword align
                    504: //      cb += 4 - (cb % 4);
                    505: 
                    506:     hMem=GlobalAlloc(GHND, cb);
                    507: 
                    508:     if (NULL==hMem)
                    509:         {
                    510:         if (NULL!=pIE->hMemAND)
                    511:             GlobalFree(pIE->hMemAND);
                    512: 
                    513:         DeleteObject(hBmp);
                    514:         return 0;
                    515:         }
                    516: 
                    517:     lpbDst=(LPBYTE)GlobalLock(hMem);
                    518:     GetBitmapBits(hBmp, cb, (LPVOID)lpbDst);
                    519: 
                    520:     DeleteObject(hBmp);
                    521:     GlobalUnlock(hMem);
                    522: 
                    523: 
                    524:     /*
                    525:      * If this is the first pass (pIE->fAND==TRUE) then save the memory
                    526:      * of the AND bits for the next pass.
                    527:      */
                    528:     if (pIE->fAND)
                    529:         {
                    530:         pIE->fAND=FALSE;
                    531:         pIE->hMemAND=hMem;
                    532: 
                    533:         //Continue enumeration looking for the next blt record.
                    534:         return 1;
                    535:         }
                    536:     else
                    537:         {
                    538:         //Get the AND pointer again.
                    539:         lpbSrc=(LPBYTE)GlobalLock(pIE->hMemAND);
                    540: 
                    541:         /*
                    542:          * Create the icon now that we have all the data.  lpbDst already
                    543:          * points to the XOR bits.
                    544:          */
                    545:         cxIcon = GetSystemMetrics(SM_CXICON);
                    546:         cyIcon = GetSystemMetrics(SM_CYICON);
                    547: 
                    548:         pIE->hIcon=CreateIcon(ghInst, 
                    549:                               uWidth, 
                    550:                               uHeight,
                    551:                               (BYTE)bm.bmPlanes, 
                    552:                               (BYTE)bm.bmBitsPixel,
                    553:                               (LPVOID)lpbSrc, 
                    554:                               (LPVOID)lpbDst);
                    555: 
                    556:         GlobalUnlock(pIE->hMemAND);
                    557:         GlobalFree(pIE->hMemAND);
                    558:         GlobalFree(hMem);
                    559: 
                    560:         //We're done so we can stop.
                    561:         return 0;
                    562:         }
                    563:     }
                    564: 
                    565: 
                    566: 
                    567: 
                    568: 
                    569: /*
                    570:  * OleUIMetafilePictExtractIconSource
                    571:  *
                    572:  * Purpose:
                    573:  *  Retrieves the filename and index of the icon source from a metafile
                    574:  *  created with OleUIMetafilePictFromIconAndLabel.
                    575:  *
                    576:  * Parameters:
                    577:  *  hMetaPict       HGLOBAL to the METAFILEPICT containing the metafile.
                    578:  *  lpszSource      LPSTR in which to store the source filename.  This
                    579:  *                  buffer should be OLEUI_CCHPATHMAX characters.
                    580:  *  piIcon          UINT FAR * in which to store the icon's index
                    581:  *                  within lpszSource
                    582:  *
                    583:  * Return Value:
                    584:  *  BOOL            TRUE if the records were found, FALSE otherwise.
                    585:  */
                    586: STDAPI_(BOOL) OleUIMetafilePictExtractIconSource(HGLOBAL hMetaPict
                    587:     , LPSTR lpszSource, UINT FAR *piIcon)
                    588:     {
                    589:     LPMETAFILEPICT  pMF;
                    590:     LABELEXTRACT    le;
                    591:     HDC             hDC;
                    592: 
                    593:     /*
                    594:      * We will walk the metafile looking for the two comment records
                    595:      * following the IconOnly comment.  The flags fFoundIconOnly and
                    596:      * fFoundSource indicate if we have found IconOnly and if we have
                    597:      * found the source comment already.
                    598:      */
                    599: 
                    600:     if (NULL==hMetaPict || NULL==lpszSource || NULL==piIcon)
                    601:         return FALSE;
                    602: 
                    603:     pMF=GlobalLock(hMetaPict);
                    604: 
                    605:     if (NULL==pMF)
                    606:         return FALSE;
                    607: 
                    608:     le.lpsz=lpszSource;
                    609:     le.fFoundIconOnly=FALSE;
                    610:     le.fFoundSource=FALSE;
                    611:     le.fFoundIndex=FALSE;
                    612: 
                    613:     //Use a screen DC so we have something valid to pass in.
                    614:     hDC=GetDC(NULL);
                    615: 
                    616:     EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIconSource, (LONG)(LPLABELEXTRACT)&le);
                    617: 
                    618:     ReleaseDC(NULL, hDC);
                    619:     GlobalUnlock(hMetaPict);
                    620: 
                    621:     //Copy the icon index to the caller's variable.
                    622:     *piIcon=le.u.iIcon;
                    623: 
                    624:     //Check that we found everything.
                    625:     return (le.fFoundIconOnly && le.fFoundSource && le.fFoundIndex);
                    626:     }
                    627: 
                    628: 
                    629: 
                    630: 
                    631: 
                    632: /*
                    633:  * EnumMetafileExtractIconSource
                    634:  *
                    635:  * Purpose:
                    636:  *  EnumMetaFile callback function that walks a metafile skipping the first
                    637:  *  comment record, extracting the source filename from the second, and
                    638:  *  the index of the icon in the third.
                    639:  *
                    640:  * Parameters:
                    641:  *  hDC             HDC into which the metafile should be played.
                    642:  *  phTable         HANDLETABLE FAR * providing handles selected into the DC.
                    643:  *  pMFR            METARECORD FAR * giving the enumerated record.
                    644:  *  pLE             LPLABELEXTRACT providing the destination buffer and
                    645:  *                  area to store the icon index.
                    646:  *
                    647:  * Return Value:
                    648:  *  int             0 to stop enumeration, 1 to continue.
                    649:  */
                    650: 
                    651: int CALLBACK EXPORT EnumMetafileExtractIconSource(HDC hDC, HANDLETABLE FAR *phTable
                    652:     , METARECORD FAR *pMFR, int cObj, LPLABELEXTRACT pLE)
                    653:     {
                    654:     LPSTR       psz;
                    655: 
                    656:     /*
                    657:      * We don't allow anything to happen until we see "IconOnly"
                    658:      * in an MFCOMMENT that is used to enable everything else.
                    659:      */
                    660:     if (!pLE->fFoundIconOnly)
                    661:         {
                    662:         if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0])
                    663:             {
                    664:             if (0==lstrcmpi(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
                    665:                 pLE->fFoundIconOnly=TRUE;
                    666:             }
                    667: 
                    668:         return 1;
                    669:         }
                    670: 
                    671:     //Now see if we find the source string.
                    672:     if (!pLE->fFoundSource)
                    673:         {
                    674:         if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0])
                    675:             {
                    676:             lstrcpyn(pLE->lpsz, (LPSTR)&pMFR->rdParm[2], OLEUI_CCHPATHMAX);
                    677:             pLE->lpsz[OLEUI_CCHPATHMAX-1] = '\0';
                    678:             pLE->fFoundSource=TRUE;
                    679:             }
                    680: 
                    681:         return 1;
                    682:         }
                    683: 
                    684:     //Next comment will be the icon index.
                    685:     if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0])
                    686:         {
                    687:         /*
                    688:          * This string contains the icon index in string form,
                    689:          * so we need to convert back to a UINT.  After we see this
                    690:          * we can stop the enumeration.  The comment will have
                    691:          * a null terminator because we made sure to save it.
                    692:          */
                    693:         psz=(LPSTR)&pMFR->rdParm[2];
                    694:         pLE->u.iIcon=0;
                    695: 
                    696:         //Do Ye Olde atoi
                    697:         while (*psz)
                    698:             pLE->u.iIcon=(10*pLE->u.iIcon)+((*psz++)-'0');
                    699: 
                    700:         pLE->fFoundIndex=TRUE;
                    701:         return 0;
                    702:         }
                    703: 
                    704:     return 1;
                    705:     }

unix.superglobalmegacorp.com

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