DRAWICON.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:20k
源码类别:

Windows编程

开发平台:

Visual C++

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