I am working on an application which is using emf for buffer drawing. I am trying to save this emf to a bitmap image file using BitBlt. But no drawings are saved to bitmap. I know I can use PlayEnhMetaFile() but I have to use BitBlt or GDI/GDI+ calls for this. As there will be some other drawing calls to emf after saving it to bitmap. Sample code.
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" have complete drawing. while "StateImage_EMFDC.bmp" is complete green image which should have drawing on it.