Free Source Code and Program Tips
Simple code to create an EMF or Bitmap file from existed draw code
We often need to create an Enhanced Meta File(EMF) or Bitmap(bmp) from an existed DC draw code. It’s not very difficult but it’s boring to code again and again.
The following is a simple solution, what you need to do is only to implement an IPicDrawer and call DrawEnhMeta or DrawBitmap function.
struct IPicDrawer
{
virtual void GetSize(CSize&) = 0; // It’s the smallest size for EMF
virtual BOOL Draw(CDC*) = 0;
};
BOOL DrawEnhMeta(LPCTSTR lpszFileName, IPicDrawer *pIDrawer)
{
// Draw EMF file, the limitation of DC function refer to MSDN
HDC hDC = ::CreateEnhMetaFile(NULL, lpszFileName, NULL,
_T(“FQ EMF Func\0No Title\0″));
CDC *pDC = CDC::FromHandle(hDC);
if(pDC)
{
CSize sz;
pIDrawer->GetSize(sz);
pDC->FillRect(CRect(0,0,sz.cx,sz.cy), &CBrush(RGB(255,255,255)));
if(pIDrawer->Draw(pDC))
{
HENHMETAFILE hEmf = ::CloseEnhMetaFile(hDC);
if(hEmf)
{
::DeleteEnhMetaFile(hEmf);
return TRUE;
}
else
::DeleteFile(lpszFileName);
}
}
return FALSE;
}
BOOL DrawBitmap(LPCTSTR lpszFileName, IPicDrawer *pIDrawer)
{
// Draw 24 bit true color bitmap file
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
BOOL bRet = FALSE;
if(hFile)
{
CSize sz;
pIDrawer->GetSize(sz);
BITMAPINFO BmpInfo = {0, }; //
BmpInfo.bmiHeader.biWidth = sz.cx;
BmpInfo.bmiHeader.biHeight = sz.cy;
BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfo.bmiHeader.biPlanes = 1;
BmpInfo.bmiHeader.biBitCount = 24; // 24bit
BmpInfo.bmiHeader.biCompression = BI_RGB;
BmpInfo.bmiHeader.biSizeImage = BmpInfo.bmiHeader.biBitCount / 8 *
BmpInfo.bmiHeader.biWidth * BmpInfo.bmiHeader.biHeight;
BITMAPFILEHEADER bmpFileHeader = {0, }; //
bmpFileHeader.bfType = *(WORD*)_T(“BM”);
bmpFileHeader.bfOffBits =
sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpFileHeader.bfOffBits +=
sizeof(DWORD) – (bmpFileHeader.bfOffBits % sizeof(DWORD));
bmpFileHeader.bfSize = bmpFileHeader.bfOffBits + BmpInfo.bmiHeader.biSizeImage;
//write file header and image information
DWORD dwNum = 0;
bRet = ::WriteFile(hFile, &bmpFileHeader, sizeof(BITMAPFILEHEADER),
&dwNum, NULL);
bRet = bRet && ::WriteFile(hFile, &(BmpInfo.bmiHeader), sizeof(BITMAPINFOHEADER),
&dwNum, NULL);
if(bRet)
{
bRet = FALSE;
//create file mapping
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE,
0, bmpFileHeader.bfSize, NULL);
if(hMap)
{
// create bitmap object
void *pBits = NULL;
HBITMAP hBMP = ::CreateDIBSection(NULL, &BmpInfo, DIB_RGB_COLORS,
&pBits, hMap, bmpFileHeader.bfOffBits);
if(hBMP)
{
// draw the specified figure to file
CDC memTmpDC;
memTmpDC.CreateCompatibleDC(NULL);
if(memTmpDC.GetSafeHdc())
{
CBitmap *pbmp;
pbmp = CBitmap::FromHandle(hBMP);
if(pbmp)
{
memTmpDC.SelectObject(pbmp);
memTmpDC.FillRect(CRect(0,0,sz.cx,sz.cy), &CBrush(RGB(255,255,255)));
bRet = pIDrawer->Draw(&memTmpDC);
}
}
::DeleteObject(hBMP);
}
::CloseHandle(hMap);
}
}
::CloseHandle(hFile);
}
if(!bRet)
::DeleteFile(lpszFileName);
return bRet;
}
| Print article | This entry was posted by hamo on December 16, 2006 at 6:04 pm, and is filed under Win32/MFC. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |