使用增强型元文件DC作为源DC

时间:2016-07-26 05:59:13

标签: mfc gdi+ gdi bitblt

我正在使用emf进行缓冲区绘制的应用程序。我试图使用BitBlt将此emf保存到位图图像文件。但没有图形保存到位图。我知道我可以使用PlayEnhMetaFile(),但我必须使用BitBlt或GDI / GDI +调用。因为将emf保存到位图后会有一些其他的绘图调用。 示例代码。

void CTestGUIApplicationView::OnDraw(CDC* pDC)
{
CRect oRect(0, 0, 640, 434);
HDC hdc = pDC->GetSafeHdc();
//Meta file creation
int iWidthMM = GetDeviceCaps(hdc, HORZSIZE);
int iHeightMM = GetDeviceCaps(hdc, VERTSIZE);
int iWidthPels = GetDeviceCaps(hdc, HORZRES);
int iHeightPels = GetDeviceCaps(hdc, VERTRES);
CRect rect;
rect.left = (oRect.left * iWidthMM * 100) / iWidthPels;
rect.top = (oRect.top * iHeightMM * 100) / iHeightPels;
rect.right = (oRect.right * iWidthMM * 100) / iWidthPels;
rect.bottom = (oRect.bottom * iHeightMM * 100) / iHeightPels;

HDC hMetaDC = CreateEnhMetaFile(hdc, NULL, &rect, NULL);
CDC *pMetaDC = CDC::FromHandle(hMetaDC);

//Drawing on meta file DC.
RECT drawingRect;
CPen penBlue, pen2, pen3, pen4;
penBlue.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(0, 0, 255));
pen2.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(0, 255, 255));
pen3.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(255, 0, 255));
pen4.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(128, 0, 56));
auto pOldPen = pMetaDC->SelectObject(&penBlue);

pMetaDC->Arc(oRect,
    CPoint(oRect.right, oRect.CenterPoint().y),
    CPoint(oRect.CenterPoint().x, oRect.right));
pMetaDC->SelectObject(&pen2);
pMetaDC->Ellipse(oRect.left + 50, oRect.top + 25, oRect.Width(), oRect.Height());

//copy meta file to DC.
CopyToBitMap(_T("StateImage_EMFDC.bmp"), pMetaDC, oRect);

//some other drawing calls on meta file DC.
pMetaDC->SelectObject(&pen3);
pMetaDC->Ellipse(oRect.left + oRect.Width() / 2, oRect.top + oRect.Height() / 2, oRect.Width(), oRect.Height());
pMetaDC->SelectObject(pOldPen); pOldPen = NULL;

//Copy meta file to window DC.
HENHMETAFILE hMeta = CloseEnhMetaFile(pMetaDC->GetSafeHdc());
if (hMeta != NULL)
{
    //save meta file to disk to view its contents.
    HENHMETAFILE hMeta2 = CopyEnhMetaFile(hMeta, _T("test.emf"));
    DeleteEnhMetaFile(hMeta2);
    PlayEnhMetaFile(hdc, hMeta, oRect);
    DeleteEnhMetaFile(hMeta);
}
//some other drawing on Window DC.
pOldPen = pDC->SelectObject(&pen4);
pDC->Ellipse(oRect.left + 25, oRect.top + 50, oRect.Width() - 30, oRect.Height() - 60);
pDC->SelectObject(pOldPen);
CopyToBitMap(_T("StateImage_WindowDC.bmp"), pDC, oRect);
}
//Routine to copy data from DC to bitmap.
void CTestGUIApplicationView::CopyToBitMap(CString filePath, CDC* pDC, CRect & windRect)
{
//creating bitmap 
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDC, windRect.Width(), windRect.Height());
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *oldBMP = memDC.SelectObject(&bitmap);
memDC.FillSolidRect(windRect, RGB(0, 255, 0));
BOOL result = BitBlt(memDC.GetSafeHdc(), 0, 0, windRect.Width() , windRect.Height(), pDC->GetSafeHdc(), 0, 0, SRCCOPY);
memDC.SelectObject(oldBMP);
//Saving bitmap to disk.
CImage image;
image.Attach(bitmap);
image.Save(filePath, Gdiplus::ImageFormatBMP);
image.Detach();
image.Destroy();
bitmap.DeleteObject();
}

" StateImage_WindowDC.bmp"有完整的绘图。而" StateImage_EMFDC.bmp"是完整的绿色图像,应该有它。

1 个答案:

答案 0 :(得分:0)

图元文件DC不像常规DC,它不会在位图上绘制;它仅用于记录绘图说明。来自Microsoft's "Enhanced Metafile Creation" page

  

当CreateEnhMetaFile成功时,它返回一个标识特殊元文件设备上下文的句柄。元文件设备上下文的独特之处在于它与文件而不是与输出设备相关联。当系统处理接收元文件设备上下文句柄的GDI函数时,它将GDI函数转换为增强元文件记录,并将记录追加到增强型图元文件的末尾。

您说您无法调用PlayEnhMetaFile,因为在捕获后您想要附加到图元文件中的其他绘图命令。在这种情况下,我可以看到两个选项:

  1. 与图元文件DC并行绘制到常规DC。
  2. 使用GetEnhMetaFileBitsSetEnhMetaFileBits制作可与PlayEnhMetaFile一起使用的图元文件的副本