我正在开发一个拥有庞大的元文件数据库(旧的 win3.0 格式)的系统,我需要将其转换为增强的元文件。我确实转换了整个数据库,并设法将文件按原样播放到显示器上,除了一件事:
旧的元文件使用当前的笔/画笔将文件播放到屏幕上。
另一方面,增强的元文件需要将笔“保存”
在文件中,而我没有设法在运行时更改它。
我需要一种在运行时更改增强的图元文件笔的方法,因此可以根据运行的应用程序在不同的笔中播放一个图元文件。
我正在开发一个拥有庞大的元文件数据库(旧的 win3.0 格式)的系统,我需要将其转换为增强的元文件。我确实转换了整个数据库,并设法将文件按原样播放到显示器上,除了一件事:
旧的元文件使用当前的笔/画笔将文件播放到屏幕上。
另一方面,增强的元文件需要将笔“保存”
在文件中,而我没有设法在运行时更改它。
我需要一种在运行时更改增强的图元文件笔的方法,因此可以根据运行的应用程序在不同的笔中播放一个图元文件。
我找到了一个方法。
感谢灰狼http://www.cplusplus.com/user/z05DSL3A/
遵循解决方案(由 GreyWolf 编写):我有一个类(在某处),它可以将 EMF 处理为灰度,因为我记得您必须提供一个回调函数,可以动态地将颜色值替换为适当的灰度级。我会看看能不能找到代码(但要到周末……只要我记得)。
您可以尝试的另一件事是使用通用 postscript 驱动器(来自 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;
}
};