|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.