enumerating enhanced metafile

how do I look at individual records in an enhanced metafile?  I want to run a check to look at just text in the metafile.  Lets say when I press a buton the metafiles records will be displayed inside of a listbox control.  Each records parameters needs to be displayed.  I am only interested in text occurances in the metafile.  I am working with Enhanced metafiles int the win32 environment.  I am using winnt and VS 6
LVL 2
simongodAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

migelCommented:
Hi!
hmm
EnumEnhMetafile(...)
you need to test EMR_EXTTEXTOUTA(W) in the ENHMETARECORD passed to the your callback function. I wrote some test task to you.
0
simongodAuthor Commented:
Anyone else have any suggestions?
0
dsandfordCommented:
migel is right - you need to enumerate the metafile using the EnumEnhMetaFile() function (search for this in MSDN index).  Call as follows:

int
  result = EnumEnhMetaFile(NULL, hEnhMetaFile, (ENHMFENUMPROC)MetaEnumProc, &m_ListCtrl, NULL);

Parameter 1 is a pointer to a HDC to allow the callback function (MetaEnumProc) to use PlayEnhMetaFileRecord() to draw the record.  This is not needed in this case.

Parameter 2 is a HENHMETAFILE handle to your metafile in memory.

Parameter 3 is the ENHMFENUMPROC, which is a callback function.  This function is called for every record in the metafile, and will look something as follows.  I apologise for any errors, as I am at home, not at my desk.  Any problems, comment tomorrow and I will look it up at work.

int CALLBACK MetaEnumProc(HDC hDC, HANDLETABLE FAR *lpHTable, ENHMETARECORD FAR *lpEMFR, int nObj, LPARAM lpData)
{
  CListCtrl
    *pCtrl = (CListCtrl*)lpData;
// lpData is parameter 4 passed to the EnumEnhMetaFile() function above.

  switch(lpEMFR->iType)
  {
    case EMR_EXTTEXTOUTA:
    case EMR_EXTTEXTOUTW:
      // These both use the same structure
      EMREXTTEXTOUTA
        *pRec = (EMREXTTEXTOUTA*) lpEMFR;

      // Get data from the record
      break;
    case EMR_POLYTEXTOUTA:
    case EMR_POLYTEXTOUTW:
      // These both use the same structure
      EMRPOLYTEXTOUTA
        *pRec = (EMRPOLYTEXTOUTA*) lpEMFR;
      // Get the data from the record
      // and add it to the CListCtrl
      // using pCtrl pointer.

      break;
    case default:
      // It is a record we are not interested in
      break;
  }

    return 1;
// return 1 to continue enumeration.
// 0 will cancel enumeration.
}

The format of the above structures is in MSDN (search for EMR), but I have included some information here.

typedef struct tagEMREXTTEXTOUTA
{
    EMR     emr;
// EMR just contains the size and type of the record.  Ignore.
    RECTL   rclBounds;
// The bounding box of the text, in device units.
    DWORD   iGraphicsMode;
// Graphics mode - GM_COMPATIBLE or GM_ADVANCED
    FLOAT   exScale;
    FLOAT   eyScale;
// If GM_COMPATIBLE, scaling factor from page units to .01mm units.
    EMRTEXT emrtext;
// Structure containing information about the text.
} EMREXTTEXTOUTA, *PEMREXTTEXTOUTA,
  EMREXTTEXTOUTW, *PEMREXTTEXTOUTW;

typedef struct tagEMRPOLYTEXTOUTA
{
    EMR     emr;
    RECTL   rclBounds;
    DWORD   iGraphicsMode;
    FLOAT   exScale;
    FLOAT   eyScale;
    LONG    cStrings;
// Number of EMRTEXT structures.
    EMRTEXT aemrtext[1];
} EMRPOLYTEXTOUTA, *PEMRPOLYTEXTOUTA,
  EMRPOLYTEXTOUTW, *PEMRPOLYTEXTOUTW;

EMRTEXT contains the actual text information, which is as follows:

typedef struct tagEMRTEXT
{
    POINTL ptlReference;
// logical coordinates used to position the string.
    DWORD  nChars;
// Number of chars in string
    DWORD  offString;
// Offset to string from the lpEMFR pointer passed in to the enumerator function above.
    DWORD  fOptions;
// Value specifying how to use the application-defined rectangle. This member can be a combination of the ETO_CLIPPED and ETO_OPAQUE values.
    RECTL  rcl;
// Rectangle used as above
    DWORD  offDx;
// Offset to intercharacter spacing array.  This array contains an entry for each character, and determines how each character is spaced from it's neighbour.
} EMRTEXT, *PEMRTEXT;
 
Look here (http://msdn.microsoft.com/library/psdk/gdi/metafile_7ulv.htm) for information on metafiles, and (http://msdn.microsoft.com/library/psdk/gdi/metafile_5hkj.htm) for information on the structures described above.

Good luck!
Daz
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
simongodAuthor Commented:
I am giving you the points because you ANSWERED the question you really didn't help me migel helped me through email I just forgot that this question was asked so I forgot to give him the points
0
dsandfordCommented:
Thanks VERY much - nothing like a bit of gratitude.  Remind me to avoid your questions in future.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.