Перо расширенного метафайла Windows против метафайла Windows - PullRequest
0 голосов
/ 09 января 2012

Я работаю в системе с огромной базой метафайлов (старый формат win3.0), и мне нужно преобразовать ее в расширенный метафайл. Я преобразовал всю базу данных и смог воспроизвести файлы на дисплее, как и должно быть, кроме одного:

  • Старые метафайлы используют текущую ручку / кисть для воспроизведения файла на экран.

  • С другой стороны, расширенные метафайлы требуют, чтобы перо было «сохранено»
    внутри файла, и мне не удалось изменить его во время выполнения.

Мне нужен способ изменения улучшенного пера метафайла во время выполнения, чтобы один метафайл можно было воспроизводить в разных перьях в зависимости от запущенного приложения.

1 Ответ

0 голосов
/ 10 января 2012

Я нашел способ.

Благодаря Серому Волку http://www.cplusplus.com/user/z05DSL3A/

Следуйте решению (написанному GreyWolf): У меня есть класс (где-то), который обрабатывает ЭДС как градации серого, так как я помню, что вы должны предоставить функцию обратного вызова, которая может на лету заменить значения цвета соответствующими уровнями серого. Я посмотрю, смогу ли я найти код (но это не будет до выходных ... пока я помню).

Еще одна вещь, которую вы можете попробовать, - использовать универсальный постскрипт-диск (от Adobe).

- == Редактировать == -

Чтобы использовать приведенный ниже код, создайте объект CGrayEMF и вызовите его метод EnumEMF (). Я не думаю, что он конвертирует встроенные растровые изображения, но это можно добавить.

class CEnumEMF
{
    // virtual function to process every EMF record, return 0 to terminate
    virtual int ProcessRecord(HDC hDC, HANDLETABLE * pHTable, const ENHMETARECORD * pEMFR, int nObj)
    {
        return 0;
    }

    // static callback function, dispatch to virtual function ProcessRecord
    static int CALLBACK EMFProc(HDC hDC, HANDLETABLE * pHTable, 
        const ENHMETARECORD * pEMFR, int nObj, LPARAM lpData)
    {
        CEnumEMF * pObj = (CEnumEMF *) lpData;

        if ( IsBadWritePtr(pObj, sizeof(CEnumEMF)) )
        {
            assert(false);
            return 0;
        }

        return pObj->ProcessRecord(hDC, pHTable, pEMFR, nObj);
    }

public:

    BOOL EnumEMF(HDC hDC, HENHMETAFILE hemf, const RECT * lpRect)
    {
        return ::EnumEnhMetaFile(hDC, hemf, EMFProc, this, lpRect);
    }
};

inline void MaptoGray(COLORREF & cr)
{
    if ( (cr & 0xFF000000) != PALETTEINDEX(0) ) // not paletteindex
    {
        BYTE gray = ( GetRValue(cr) * 77 + GetGValue(cr) * 150 + GetBValue(cr) * 29 + 128 ) / 256;

        cr = (cr & 0xFF000000) | RGB(gray, gray, gray);
    }
}


class CGrayEMF : public CEnumEMF
{
    // virtual function to process every EMF record, return 0 to terminate
    virtual int ProcessRecord(HDC hDC, HANDLETABLE * pHTable, const ENHMETARECORD * pEMFR, int nObj)
    {
        int rslt;

        switch ( pEMFR->iType )
        {
            case EMR_CREATEBRUSHINDIRECT:
                {
                    EMRCREATEBRUSHINDIRECT cbi;

                    cbi = * (const EMRCREATEBRUSHINDIRECT *) pEMFR;
                    MaptoGray(cbi.lb.lbColor);

                    rslt = PlayEnhMetaFileRecord(hDC, pHTable, (const ENHMETARECORD *) & cbi, nObj);
                }
                break;

            case EMR_CREATEPEN:
                {
                    EMRCREATEPEN cp;

                    cp = * (const EMRCREATEPEN *) pEMFR;
                    MaptoGray(cp.lopn.lopnColor);

                    rslt = PlayEnhMetaFileRecord(hDC, pHTable, (const ENHMETARECORD *) & cp, nObj);
                }
                break;

            case EMR_SETTEXTCOLOR:
            case EMR_SETBKCOLOR:
                {
                    EMRSETTEXTCOLOR stc;

                    stc = * (const EMRSETTEXTCOLOR *) pEMFR;
                    MaptoGray(stc.crColor);

                    rslt = PlayEnhMetaFileRecord(hDC, pHTable, (const ENHMETARECORD *) & stc, nObj);
                }
                break;

            case EMR_RESERVED_105:
            case EMR_RESERVED_106:
            case EMR_RESERVED_107:
            case EMR_RESERVED_108:
            case EMR_RESERVED_109:
            case EMR_RESERVED_110:
            case EMR_RESERVED_119:
            case EMR_RESERVED_120:
                rslt = PlayEnhMetaFileRecord(hDC, pHTable, pEMFR, nObj);
                break;

            default:
                rslt = PlayEnhMetaFileRecord(hDC, pHTable, pEMFR, nObj);
        }

        return rslt;
    }
};
...