Windows 增强型图元文件笔与 Windows 图元文件

发布于 2024-12-25 12:10:07 字数 271 浏览 2 评论 0原文

我正在开发一个具有庞大图元文件数据库(旧的 win3.0 格式)的系统,我需要将其转换为增强型图元文件。我确实转换了整个数据库,并设法将文件播放到显示器上,除了一件事:

  • 旧图元文件使用当前的笔/画笔将文件播放到显示器上。 屏幕。

  • 另一方面,增强型图元文件需要笔“保存”
    在文件内部,我没有设法在运行时更改它。

我需要一种在运行时更改增强型图元文件笔的方法,以便根据运行的应用程序可以在不同的笔中播放一个图元文件。

I'm working on a system that have huge database of metafiles (the old win3.0 format), and I need to convert that to Enhanced Metafile. I did convert the whole database, and manage to play the files to the display as it should be, except one thing:

  • The old metafiles use the current pen/brush to play the file to the
    screen.

  • On the other hand the enhanced metafiles need the pen to be "save"
    inside the file, and I didn't manage to change it in runtime.

I need a way to change the enhanced metafile pen, in runtime, so one metafile can be played in different pens depending on the application running.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

装迷糊 2025-01-01 12:10:07

我找到了办法。

感谢灰狼 http://www.cplusplus.com/user/z05DSL3A/

遵循解决方案(由GreyWolf编写):
我有一个类(某处)将 EMF 作为灰度处理,因为我记得您必须提供一个回调函数,可以动态地将颜色值替换为适当的灰度级。我会看看是否能找到代码(但直到周末才能找到......只要我记得)。

您可以尝试的另一件事是使用通用 Postscript 驱动器(来自 Adob​​e)。

-== 编辑 ===

要使用下面的代码,创建一个 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;
    }
};

I found a way.

Thanks to Grey Wolf http://www.cplusplus.com/user/z05DSL3A/

Follow the solution (written by GreyWolf):
I have a class (somewhere) than handles EMFs as grey scales, as I remember you have to supply a callback function can on the fly replace the colour values with appropriate grey levels. I'll see if I can find the code (but it will not be until the weekend...as long as I remember).

Another thing you could try is using a generic postscript drive (from Adobe).

-== Edit ==-

To use the code below create a CGrayEMF object and call its EnumEMF() method. I don't think that it converts embedded bitmaps, but that should be able to be added.

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;
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文