Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

729 lines
20 KiB

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