emfdc.cpp

来自「Windows 图形编程 书籍」· C++ 代码 · 共 918 行 · 第 1/2 页

CPP
918
字号

		case EMR_BITBLT:
			{
				EMRBITBLT  * bitblt = (EMRBITBLT *) emr;

				if ( bitblt->cbBitsSrc==0 ) // no bitmap
					fmt.Format("PatBlt(hDC,%d,%d,%d,%d,", & bitblt->xDest);
				else
				{
					fmt.Format("BitBlt(hDC,%d,%d,%d,%d,", & bitblt->xDest);

				//	assert(false);
					fmt.Write("hMemDC");
				
					fmt.Format(",%d,%d,", & bitblt->xSrc);
				}

				fmt.Write(Lookup(bitblt->dwRop, Dic_ROP3));
				fmt.Write(");");
			}
			break;

		case EMR_STRETCHBLT:
			{
				EMRSTRETCHBLT * cmd = (EMRSTRETCHBLT *) emr;

				if ( cmd->cbBitsSrc==0 ) // no bitmap
					fmt.Format("PatBlt(hDC,%d,%d,%d,%d,", & cmd->xDest);
				else
				{
					TCHAR format[64];

					fmt.AddDIB( cmd, 
					        cmd->offBmiSrc,  cmd->cbBmiSrc,
				            cmd->offBitsSrc, cmd->cbBitsSrc,
							format, false);
				
					fmt.Newline();
					fmt.Format("StretchDIBits(hDC, %d,%d", & cmd->xDest);
					fmt.Format(",%d,%d",                   & cmd->cxDest);
					fmt.Format(", %d,%d,",				   & cmd->xSrc);

					if ( ! fmt.IsOpen() )
					{
						fmt.Format("%d,%d, pBits, pBMI",	   & cmd->cxSrc);
						fmt.Write(format);
					}
					else
						fmt.Format("%d,%d, #b, #B",			   & cmd->cxSrc);
					
					fmt.Format(", %L,", & cmd->iUsageSrc, Dic_DIBColor);
				}
				
				fmt.Write(Lookup(cmd->dwRop, Dic_ROP3));
				fmt.Write(");");
			}
			break;

		case EMR_EXTSELECTCLIPRGN:
			{
				EMREXTSELECTCLIPRGN * extselectcliprgn = (EMREXTSELECTCLIPRGN *) emr;

				if ( extselectcliprgn->cbRgnData == 0 )
					fmt.Write("SelectClipRgn(hDC, NULL);");
				else
				{
					fmt.AddRegion(extselectcliprgn->cbRgnData, (const RGNDATA *) & extselectcliprgn->RgnData);
					
					fmt.Newline();
					fmt.Format("ExtSelectClipRgn(hDC, hRegion, %L);", & extselectcliprgn->iMode, Dic_RegionOper);

					fmt.Newline();
					fmt.Write("DeleteObject(hRegion);");
				}
			}
			break;

/*		case EMR_SMALLTEXTOUT:
			{
				EMRSMALLTEXTOUT * smalltextout = (EMRSMALLTEXTOUT *) emr;

				fmt.Format("ExtTextOutA(hDC, %d,%d,",
							& smalltextout->ptlReference.x);

				fmt.WriteDec(smalltextout->fOptions & 0xFC00);
				fmt.Write(",NULL,");
				fmt.WriteString(smalltextout->Text, smalltextout->nChars, false);
				fmt.Write(",");
				fmt.WriteDec(smalltextout->nChars);
				fmt.Write(",NULL);");
			}
			break;
*/			
		case EMR_EXTTEXTOUTA:
		case EMR_EXTTEXTOUTW:
			{
				EMREXTTEXTOUTW * cmd = (EMREXTTEXTOUTW *) emr;

				if ( (cmd->emrtext.offDx!=0) && (cmd->emrtext.nChars!=0) )
				{
					fmt.Format("const int Dx_%m[]=", NULL);
					fmt.WriteArray(Offset(emr, cmd->emrtext.offDx), cmd->emrtext.nChars, sizeof(long));
					fmt.Put(';');

					fmt.Newline();
				}

				if (cmd->emrtext.fOptions & ( ETO_CLIPPED | ETO_OPAQUE) )
				{
					fmt.Format("const RECT Rect_%n={%d,%d,%d,%d};", & cmd->emrtext.rcl);
					fmt.Newline();
				}

				if (emr->iType == EMR_EXTTEXTOUTA)
					fmt.Write("ExtTextOutA");
				else
					fmt.Write("ExtTextOutW");
				
				fmt.Format("(hDC, %d,%d,", & cmd->emrtext.ptlReference);
				
				if ( cmd->emrtext.fOptions == 0)
					fmt.Put('0');
				else
					fmt.Write(cmd->emrtext.fOptions, Dic_ExtTextOption);
				
				fmt.Put(',');
				
				if (cmd->emrtext.fOptions & (ETO_CLIPPED | ETO_OPAQUE) )
					fmt.Format("& Rect_%n,", NULL);
				else
					fmt.Write("NULL,");

				if (emr->iType == EMR_EXTTEXTOUTW)
					fmt.Put('L');

				if (emr->iType == EMR_EXTTEXTOUTA)
					fmt.WriteString(Offset(emr, cmd->emrtext.offString), cmd->emrtext.nChars, false);
				else
					fmt.WriteString(Offset(emr, cmd->emrtext.offString), cmd->emrtext.nChars, true);

				fmt.Write(",");
				fmt.WriteDec(cmd->emrtext.nChars);

				if ( (cmd->emrtext.offDx!=0) && (cmd->emrtext.nChars!=0) )
					fmt.Format(",Dx_%m);", NULL);
				else
					fmt.Write(",NULL);");
			}
			break;

		case EMR_POLYPOLYGON16:
		case EMR_POLYPOLYLINE16:
		case EMR_POLYPOLYGON:
		case EMR_POLYPOLYLINE:
			{
				EMRPOLYPOLYGON * polypolygon = ( EMRPOLYPOLYGON *) emr;

				fmt.Format("static const int Count_%n[]=", 0);
				fmt.WriteArray( polypolygon->aPolyCounts, polypolygon->nPolys, sizeof(polypolygon->aPolyCounts[0]));
				fmt.Put(';');

				fmt.Newline();
				fmt.Format("static const int Vertex_%m[]=", 0);

				switch ( emr->iType )
				{
					case EMR_POLYPOLYGON16:
					case EMR_POLYPOLYLINE16:
						fmt.WriteArray(& polypolygon->aPolyCounts[polypolygon->nPolys], polypolygon->cptl * 2, sizeof(short));
						break;

					case EMR_POLYPOLYGON:
					case EMR_POLYPOLYLINE:
						fmt.WriteArray(& polypolygon->aPolyCounts[polypolygon->nPolys], polypolygon->cptl * 2, sizeof(long));
						break;
				}
				
				fmt.Put(';');

				fmt.Newline();
	
				switch ( emr->iType )
				{
					case EMR_POLYPOLYGON16:
					case EMR_POLYPOLYGON:
						fmt.Write("PolyPolygon");
						break;

					case EMR_POLYPOLYLINE16:
					case EMR_POLYPOLYLINE:
						fmt.Write("PolyPolyline");
						break;
				}
				fmt.Format("(hDC, (const POINT *) Vertex_%m, Count_%n, %d);", & polypolygon->nPolys);
			}
			break;

		case EMR_STRETCHDIBITS:
			{
				EMRSTRETCHDIBITS * cmd = (EMRSTRETCHDIBITS *) emr;

				TCHAR format[64];

				fmt.Newline();

				bool newdib = fmt.AddDIB( cmd, 
									cmd->offBmiSrc,  cmd->cbBmiSrc,
									cmd->offBitsSrc, cmd->cbBitsSrc,
									format, false);
				
				if ( ! fmt.IsOpen() )
				{
					fmt.Newline();
					fmt.Format("StretchDIBits(hDC, %d,%d", & cmd->xDest);
					fmt.Format(",%d,%d",                   & cmd->cxDest);

					fmt.Format(", %d,%d,%d,%d, pBits, pBMI",    & cmd->xSrc);
					fmt.Write(format);
				}
				else
				{
					if ( newdib )
					{
						fmt.Write("// ");
						fmt.Write(format);
						fmt.Newline();
					}

					TCHAR temp[32];
					wsprintf(temp, "Dib_%d.", fmt.m_curPackedDIB+1);
					fmt.Write(temp);

					fmt.Format("StretchDIBits(hDC, %d,%d", & cmd->xDest);
					fmt.Format(",%d,%d",                   & cmd->cxDest);
					fmt.Format(", %d,%d,%d,%d",			   & cmd->xSrc);
				}

				fmt.Format(", %L", & cmd->iUsageSrc, Dic_DIBColor);
				fmt.Format(", %L);", & cmd->dwRop,    Dic_ROP3);
			}
			break;

		case EMR_CREATEMONOBRUSH:
			{
				EMRCREATEMONOBRUSH * cmd = (EMRCREATEMONOBRUSH *) emr;

				assert( (cmd->offBmi + cmd->cbBmi) == cmd->offBits);

				fmt.Format("const unsigned long DIB_%n[]=", NULL);
				fmt.WriteArray(Offset(cmd, cmd->offBmi), (cmd->cbBmi + cmd->cbBits)/sizeof(long), sizeof(long), false);
				fmt.Put(';');
				
				fmt.Newline();
				fmt.Format("#o=CreateDIBPatternBrushPt((const BITMAPINFO *) DIB_%n,%L);", & cmd->ihBrush, Dic_DIBColor);
			}
			break;

		case EMR_EXTCREATEPEN:
			{
				EMREXTCREATEPEN * cmd = (EMREXTCREATEPEN *) emr;

				fmt.Format("static const LOGBRUSH LogBrush_%m = #R;", & cmd->elp.elpBrushStyle);
				
				fmt.Newline();
				fmt.Format("#o=ExtCreatePen(", & cmd->ihPen);

				assert(cmd->cbBmi == 0);
				assert(cmd->cbBits == 0);

				fmt.Write(Lookup(cmd->elp.elpPenStyle, Dic_PenStyle));
				fmt.Put(',');
				fmt.WriteDec(cmd->elp.elpWidth);
				
				fmt.Format(",& LogBrush_%m,%d,NULL);", & cmd->elp.elpNumEntries);
			}
			break;

		default:			
			fmt.Format("// Unknown record [%d]", & emr->iType);
	}

	return fmt.m_buffer;
}


// Decompile from an EMF file
bool KEmfDC::DeCompile(const TCHAR * outfile, const char * FileName, 
				  KTreeView * pTree, HENHMETAFILE & hEmf)
{
	if ( ! Open(FileName) )
		return false;
	
	return DeCompileBuffer(outfile, m_View, pTree, hEmf);
}


// Decompile from an EMF object
bool KEmfDC::DeCompile(const TCHAR * outfile, HENHMETAFILE hEmf, KTreeView * pTree)
{
	int size = GetEnhMetaFileBits(hEmf, 0, NULL);

	if ( size<=0 )
		return false;

	BYTE * pBits = new BYTE[size];

	HCURSOR hOld = SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)));

	GetEnhMetaFileBits(hEmf, size, pBits);
	bool rslt = DeCompileBuffer(outfile, pBits, pTree, hEmf);

	DestroyCursor(SetCursor(hOld));

	delete [] pBits;

	return rslt;
}


bool IsEMFHeader(const void * buffer)
{
	try
	{
		const ENHMETAHEADER * header = (const ENHMETAHEADER *) buffer;

		return ( (header->iType      == EMR_HEADER) && 
			     (header->nVersion   == 0x10000)    &&
			     (header->dSignature == ENHMETA_SIGNATURE) );
	}
	catch (...)
	{
		return false;
	}

	return false;
}


extern HINSTANCE hModule;

// main entry for decompiling from a memory buffer
bool KEmfDC::DeCompileBuffer(const TCHAR * outfilename, const void * buffer, KTreeView * pTree, HENHMETAFILE & hEmf)
{
	const EMR * emr = (const EMR *) buffer;
	
	// if not normal EMF file
	while ( ! IsEMFHeader(emr) )
	{
		if ( IsEMFHeader(emr+1) )
		{
			emr ++;

			if ( hEmf==NULL )
				hEmf = SetEnhMetaFileBits(emr[-1].nSize, (const BYTE *) emr);
			
			break;
		}
		else
			emr = (const EMR *) ( ( const char * ) emr + emr->nSize );
	}

	const ENHMETAHEADER * pHeader = (const ENHMETAHEADER *) emr;
	
	if ( pTree==NULL )
	{
		fmt.Open(outfilename);

		HRSRC hRsc = FindResource(hModule, MAKEINTRESOURCE(IDR_PRE), RT_RCDATA);
		
		if ( hRsc )
		{
			HGLOBAL hResData  = LoadResource(hModule, hRsc);
			const char * pPgm = (const char *) LockResource(hResData);

			fmt.Write(pPgm);
		}

		fmt.Indent(1);
		fmt.Newline(); fmt.Write("HGDIOBJ hObj["); fmt.WriteDec((long) pHeader->nHandles); fmt.Write("] = { NULL };");
		fmt.Newline();
	}
	m_nSeq = 1;

	bool bOptimize = false;

	// enumuerate all EMF records
	while ( (emr->iType>=EMR_MIN) && (emr->iType<=EMR_MAX) )
	{
		bool rslt = true;

		if ( bOptimize )
		{
			const EMR * next = (const EMR *) ( ( const char * ) emr + emr->nSize );

			if ( next->iType == emr->iType )
				switch ( emr->iType )
				{
					case EMR_SETWINDOWORGEX:
					case EMR_SETWINDOWEXTEX:
					case EMR_SETVIEWPORTORGEX:
					case EMR_SETVIEWPORTEXTEX:
					case EMR_SETTEXTCOLOR:
					case EMR_SETBKCOLOR:
					case EMR_SETBRUSHORGEX:
					case EMR_SELECTCLIPPATH:
					case EMR_SETTEXTALIGN:
	    
					case EMR_SETBKMODE:
					case EMR_SETARCDIRECTION:
					case EMR_SETPOLYFILLMODE:
					case EMR_SETMAPMODE:
					case EMR_SETSTRETCHBLTMODE:
					case EMR_SETMAPPERFLAGS:
					case EMR_SETICMMODE:
					case EMR_SETROP2:

					case EMR_SETMITERLIMIT:
					case EMR_SETWORLDTRANSFORM:
					case EMR_MOVETOEX:
						fmt.Write("/* */");
						break;
				
					default:
						rslt = Decode(emr, pTree);
				}
			else 
				rslt = Decode(emr, pTree);
		}
		else
			rslt = Decode(emr, pTree);
		
		if (! rslt ) 
			break;

		if ( emr->iType== EMR_EOF )
			break;

		emr = (const EMR *) ( ( const char * ) emr + emr->nSize );
	}
	
	if ( pTree==NULL )
	{
		fmt.Indent(-1);

		HRSRC hRsc = FindResource(hModule, MAKEINTRESOURCE(IDR_POST), RT_RCDATA);
		
		if ( hRsc )
		{
			HGLOBAL hResData  = LoadResource(hModule, hRsc);
			const char * pPgm = (const char *) LockResource(hResData);

			fmt.Write(pPgm);
		}

		fmt.Close();
	}
	
	return true;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?