How to Decipher EMR_SELECTOBJECT Records in Enhanced Meta File

Last reviewed: January 10, 1996
Article ID: Q142319
The information in this article applies to:
  • Microsoft Win32 Software Development Kit (SDK) versions 3.5, 3.51, 4.0

SUMMARY

The EMR_SELECTOBJECT record in an enhanced metafile can indicate that the object to be selected is a stock object. It does so by setting the high order bit in the handle. This article shows how to decipher those records to get a handle to the stock object.

MORE INFORMATION

If an EMR_SELECTOBJECT record is encountered while enumerating the records in an enhanced metafile, the dParm member of the ENHMETARECORD parameter is normally an index into the handle table of the object to be selected.

However, if the high order bit of dParm[0] is set, the remaining bits indicate the index that can be used with GetStockObject() to obtain a handle to the object of interest.

For example, consider the following enumeration callback function:

int CALLBACK EnumEnhMetafileProc( HDC hDC,
                                  HANDLETABLE *lpHTable,
                                  ENHMETARECORD *lpEMFR,
                                  int nObj, LPARAM lpData )
{
    DWORD    dwIndex;
    HGDIOBJ  hObj;

    // Which record type is this record?
    switch( lpEMFR->iType )
    {
        case EMR_SELECTOBJECT: // It's a SelectObject() record
            // Is the high order bit set?
            if( lpEMFR->dParm[0] & 0x80000000 )
            {
                // High order bit is set - its a stock object
                // Strip the high bit to get the index
                dwIndex = lpEMFR->dParm[0] & 0x7fffffff;
                // Pass the index to GetStockObject()
                hObj = GetStockObject( dwIndex );
                // Select the object into the DC
                SelectObject( hDC, hObj );
            }
            else
            {
                // High order bit wasn't set - not a stock object
                SelectObject( hDC,
                          lpHTable->objectHandle[lpEMFR->dParm[0]] );
            }
        break;
        default:
            // Process other records
            PlayEnhMetaFileRecord( hDC, lpHTable, lpEMFR, nObj );
        break;
    }
    // Return non-zero to continue enumeration
    return 1;
}

Note that this information is important only if the application needs to decipher the record. Simply passing the EMR_SELECTOBJECT record to PlayEnhMetaFileRecord() is valid independent of whether or not the object of interest is a stock object.

In Windows 95, optimizations built into the operating system can result in a stock object record being recorded into the metafile even when a specific non-stock object is requested. This can happen, for example, when an application requests a solid brush of color RGB(128,128,128). The operating system recognizes this as the GRAY_BRUSH stock object and enters the stock object record into the metafile accordingly.


Additional reference words: Windows 95 4.00 3.50 Enumerate EnumEnhMetaFile
EnhMetaFileProc missing EMR_CREATEBRUSHINDIRECT
KBCategory: kbgraphic kbhowto
KBSubcategory: GdiMeta


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: January 10, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.