Sign in to follow this  
KiLLeR13iii

How to pass a bitmap from CBitmap to CStatic bitmap box

Recommended Posts

What i`m trying to do is get a portion of the screen to show in a CStatic bitmap box. What I do is:
CBitmap bm1,bm2;

BOOL CL2autoDlg::OnInitDialog()
{
//MFC generated code
..............
// TODO: Add extra initialization here
return TRUE;  // return TRUE  unless you set the focus to a control
}

void CL2autoDlg::CaptureArea(RECT area,CBitmap &bitmap)
{
	HDC hScreenDC;
	if ((hScreenDC = ::GetDC (NULL)) != NULL) 
	{
		HDC hMemDC;

		if ((hMemDC = CreateCompatibleDC (hScreenDC)) != NULL) 
		{
			HBITMAP hBitmap;
					
			if ((hBitmap = CreateCompatibleBitmap (hScreenDC, area.right-area.left, area.bottom-area.top)) != NULL) 
			{
				HBITMAP hDefaultBitmap = (HBITMAP) SelectObject (hMemDC, hBitmap);
				// From screen to memory:
				BitBlt (hMemDC, area.left, area.top, area.right-area.left, area.bottom-area.top, hScreenDC, 0, 0, SRCCOPY);
				SelectObject (hMemDC, hDefaultBitmap);
				SelectObject (hMemDC, hBitmap);
                                bitmap.CreateBitmap(area.right-area.left, area.bottom-area.top,1,24,NULL);
				bitmap.FromHandle(hBitmap);
				SelectObject (hMemDC, hDefaultBitmap);
				DeleteObject (hBitmap);
				}
			DeleteDC (hMemDC);
		}
		::ReleaseDC (NULL, hScreenDC);
	}
}







And try to display bm1 and bm2 in another dialog:
CStatic Pic2;
CStatic Pic1;

BOOL VerifDiag::OnInitDialog()
{
	CDialog::OnInitDialog();
	UpdateMsg();
	Pic1.SetBitmap(HBITMAP(bm1));
	Pic2.SetBitmap(HBITMAP(bm2));
	UpdateData(false);
	return TRUE;
}







What i get is only a gray area where the picture should have been. My guess is that the problem comes from using CBitmap::FromHandle(). MSDN says:
Quote:
If a CBitmap object is not already attached to the handle, a temporary CBitmap object is created and attached. This temporary CBitmap object is valid only until the next time the application has idle time in its event loop, at which time all temporary graphic objects are deleted. Another way of saying this is that the temporary object is only valid during the processing of one window message.
And i don`t know if by calling bm1.CreateBitmap the object is attached to a handle. If this is correct the problem may come from using Pic1.SetBitmap(HBITMAP(bm1)); I caught my head in this :( EDIT: Instead of Pic1.SetBitmap(HBITMAP(bm1)); i wrote:
HBITMAP xx;
xx=HBITMAP(bm1);
and in debugger i get xx 0x12313fd(unused=???) I start pulling my hair off :(( PS: I modified the code a little and moved the bm1.CreateBitmap(...) from OnInitDialog() to bitmap.CreateBitmap(...) now the gray box that appears has the same size as the selected area. Nevermind. Solved using this:
HBITMAP bm1,bm2;

BOOL VerifDiag::OnInitDialog()
{
	CDialog::OnInitDialog();
	UpdateMsg();

	Pic1.SetBitmap(bm1);
	Pic2.SetBitmap(bm2);

	UpdateData(false);
	return TRUE;
}

HBITMAP CL2autoDlg::CaptureArea(RECT area)
{
	HDC         hScrDC, hMemDC;         // screen DC and memory DC     

	int         nX, nY, nX2, nY2;       // coordinates of rectangle to grab     
	int         nWidth, nHeight;        // DIB width and height     
	int         xScrn, yScrn;           // screen resolution      

	HGDIOBJ     hOldBitmap , hBitmap;
		
   hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);     
   hMemDC = CreateCompatibleDC(hScrDC);      // get points of rectangle to grab  
   
   nX = area.left;     
   nY = area.top;     
   nX2 = area.right;     
   nY2 = area.bottom;      // get screen resolution      
   
   xScrn = GetDeviceCaps(hScrDC, HORZRES);     
   yScrn = GetDeviceCaps(hScrDC, VERTRES);      
   
   //make sure bitmap rectangle is visible      
   
   if (nX < 0)         
	  nX = 0;     
   
   if (nY < 0)         
      nY = 0;     
   
   if (nX2 > xScrn)         
      nX2 = xScrn;     
   
   if (nY2 > yScrn)         
      nY2 = yScrn;      

   nWidth = nX2 - nX;     
   nHeight = nY2 - nY;      
   
   // create a bitmap compatible with the screen DC     
   
   hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);      
   
   // select new bitmap into memory DC     
   
   hOldBitmap =   SelectObject (hMemDC, hBitmap);      
   
   // bitblt screen DC to memory DC     
   
   BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);     
   
   // select old bitmap back into memory DC and get handle to     
   // bitmap of the screen          
   
   hBitmap = SelectObject(hMemDC, hOldBitmap);      
   
   // clean up      
   
   DeleteDC(hScrDC);     
   DeleteDC(hMemDC);      
   
   // return handle to the bitmap      
   
   return (HBITMAP)hBitmap; 

}

void CL2autoDlg::OnBnClickedButton1()
{
	bm1=CaptureArea(area1);
	bm2=CaptureArea(area2);
}


[Edited by - jpetrie on July 20, 2009 9:59:26 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this