Hi All,
I found this thread in the forum whilst looking for help on creating a bitmap of an OpenCascade view so that I could send it to the Windows clipboard. I contacted Andreas directly to see if he had come up with a solution since posting his query. He very kindly sent a solution to me which worked perfectly and he also suggested that we post a solution to the forum for future reference.
Here is the solution by Andreas for rendering to a bitmap (with thanks to Zafir Anjum for the conversion to DIB from "Converting DDB to DIB" at http://www.codeguru.com/bitmap/ddb_to_dib.shtml)
Many thanks to Andreas for coming up with this solution.
Best regards,
Neil
How to render to a bitmap:
//get HWND of the View-Window
Handle(Aspect_Window) anAspectWindow = myView->Window();
Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast(anAspectWindow);
HWND hWindow = (HWND)aWNTWindow->HWindow();
//get size of client area
RECT WindowClientRect;
::GetClientRect(hWindow,&WindowClientRect);
int BitmapWidth=WindowClientRect.right;
int BitmapHeight=WindowClientRect.bottom;
//get or create DeviceContexts
HDC hDCWindow=::GetDC(hWindow);
HDC hDCMem=CreateCompatibleDC(hDCWindow); //MemoryDC
//create MemoryBitmap for MemoryDC
HBITMAP hMemBmp=CreateCompatibleBitmap(hDCWindow,BitmapWidth,BitmapHeight);
SelectObject(hDCMem,hMemBmp);
SelectObject(hDCWindow,(HBITMAP)aWNTWindow->HPixmap());
//copy Bits from HPixmap() to hMemBmp
BitBlt(hDCMem,0,0,BitmapWidth,BitmapHeight,hDCWindow,0,0,SRCCOPY);
//from now on converting to DIB !!!
//create logical palette if neccesary
CPalette Palette;
if (GetDeviceCaps(hDCWindow,RASTERCAPS) & RC_PALETTE)
{
UINT nSize=sizeof(LOGPALETTE)+(sizeof(PALETTEENTRY)*256);
LOGPALETTE *pLP=(LOGPALETTE*)new BYTE[nSize];
pLP->palVersion=0x300;
pLP->palNumEntries=GetSystemPaletteEntries(hDCWindow,0,255,pLP->palPalEntry);
//create palette
Palette.CreatePalette(pLP);
delete[]pLP;
}
//otherwise use DEFAULT_PALETTE
HPALETTE hPalette;
CPalette* pPalette=&Palette;
hPalette=(HPALETTE)pPalette->GetSafeHandle();
if (hPalette==NULL)
hPalette=(HPALETTE)GetStockObject(DEFAULT_PALETTE);
BITMAP Bmp;
BITMAPINFOHEADER BmInfoHeader;
LPBITMAPINFOHEADER lpBmInfoHeader;
DWORD dwLen;
HANDLE hDIB; // Handle the new DIB
HANDLE handle;
HDC hDC;
//make from HBITMAP hMemBmp a BITMAP Bmp
GetObject(hMemBmp,sizeof(Bmp),(LPSTR)&Bmp);
//define Bitmapinfoheader
BmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
BmInfoHeader.biWidth = Bmp.bmWidth;
BmInfoHeader.biHeight = Bmp.bmHeight;
BmInfoHeader.biPlanes = 1;
BmInfoHeader.biBitCount = Bmp.bmPlanes* Bmp.bmBitsPixel;
BmInfoHeader.biCompression = BI_RGB;
BmInfoHeader.biSizeImage = Bmp.bmHeight*((Bmp.bmWidth+3) & ~3); //0;
BmInfoHeader.biXPelsPerMeter= 0;
BmInfoHeader.biYPelsPerMeter= 0;
BmInfoHeader.biClrUsed = 0;
BmInfoHeader.biClrImportant = 0;
//calculate size of Infoheader and Colortable
int nColors = (1 << BmInfoHeader.biBitCount);
if(nColors>256)
nColors=0;
dwLen=BmInfoHeader.biSize+nColors*sizeof(RGBQUAD);
hDC =::GetDC(NULL);
hPalette=SelectPalette(hDC,hPalette,FALSE);
RealizePalette(hDC);
//allocate memory for BitmapinfoHeader and Colortable
hDIB=GlobalAlloc(GMEM_FIXED,dwLen);
lpBmInfoHeader=(LPBITMAPINFOHEADER)hDIB;
*lpBmInfoHeader=BmInfoHeader;
//Getting size of biSizeImage
GetDIBits(hDC,hMemBmp,0L,(DWORD)BmInfoHeader.biHeight,(LPBYTE)NULL,(LPBITMAPINFO)lpBmInfoHeader,(DWORD)DIB_RGB_COLORS);
BmInfoHeader=*lpBmInfoHeader;
if(BmInfoHeader.biSizeImage==0){
BmInfoHeader.biSizeImage=((((BmInfoHeader.biWidth*BmInfoHeader.biBitCount)+31)&~31)/8)*BmInfoHeader.biHeight;
}
//enlarge buffer
dwLen += BmInfoHeader.biSizeImage;
if(handle=GlobalReAlloc(hDIB,dwLen,GMEM_MOVEABLE))
hDIB=handle;
else{
GlobalFree(hDIB);
SelectPalette(hDC,hPalette,FALSE);
::ReleaseDC(NULL,hDC);
}
lpBmInfoHeader=(LPBITMAPINFOHEADER)hDIB;
//CREATION of the DIB
GetDIBits(hDC,hMemBmp,0L,(DWORD)BmInfoHeader.biHeight,(LPBYTE)lpBmInfoHeader+(BmInfoHeader.biSize+nColors
*sizeof(RGBQUAD)),(LPBITMAPINFO)lpBmInfoHeader,(DWORD)DIB_RGB_COLORS);
SelectPalette(hDC,hPalette,FALSE);
::ReleaseDC(NULL,hDC);
BITMAPINFOHEADER* dib;
dib=(BITMAPINFOHEADER*)hDIB;
Having rendered to a DIB it is very easy to send this to the clipboards with:
// Send the DIB to the clipboard
if (OpenClipboard())
{
BeginWaitCursor();
EmptyClipboard();
SetClipboardData (CF_DIB, hDIB );
CloseClipboard();
EndWaitCursor();
}