CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    May 2002
    Posts
    1,798

    Getting a bitmap to redraw

    This problem has been recounted numerous times on the Internet, but I have been unable to figure out how to fix it given my particular code.

    I have a dialog based app with a CStatic (picture) image container and use the following code to open a bitmap.

    Code:
    void CpoofDlg::OnBnClickedOpen()
    {
    	CString m_csPathname, m_csFilename;
    
    	const wchar_t fileDialogFilter[] = 
    	_T("Bitmap Files(*.bmp)|*.bmp||");
    	const wchar_t fileDialogExt[] = _T("bmp");
    
    	CFileDialog fileDialog(TRUE, 
    		fileDialogExt, NULL,
    		OFN_FILEMUSTEXIST, fileDialogFilter);
    
    	if (fileDialog.DoModal() == IDOK)
        {
    
    		CWaitCursor wait;
    
    		m_csPathname = fileDialog.GetPathName();
    		m_csFilename = fileDialog.GetFileName();
    		SetWindowText(m_csFilename);
    
    	}
    
    	CWaitCursor wait;
    
    	// Load the Image File
    	HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, m_csPathname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    
    	// Create a Bitmap Object and Attach It to the Object
    	CBitmap bmp;  
    	bmp.Attach(hBmp);
    
    	// Create a Memory DC and Select the BMP to It
    	// You also need to store the old BMP pointer:
    	CClientDC dc(&m_cImage);
    	CDC bmDC;
    	bmDC.CreateCompatibleDC(&dc);
    	CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
    
    	// Get the BMP Height and Width
    	// Obtain this from CBitmap's GetBitmap function.
    	BITMAP  bi;  
    	int bufsize = bmp.GetBitmap(&bi);    
    	_RPT1(0, "bufsize =: %d\n", bufsize);
    	
    	//====== try to capture the bmp bits in a buffer
    	// DWORD bmp.GetBitmapBits(DWORD dwCount, LPVOID lpBits)const;
    	// get the bitmap height - if negative
    	// Pixel array (bitmap data)The pixel array is a block of m_nSize-bit DWORDs, that describes the image pixel by pixel. 
    	// Normally pixels are stored "upside-down" with respect to normal image raster scan order, starting in the lower 
    	// left corner, going from left to right, and then row by row from the bottom to the top of the image.[1]
    	// Unless BITMAPCOREHEADER is used, uncompressed Windows bitmaps also can be stored from the top to bottom, when 
    	// the Image Height value is negative.
    
    	DWORD dwCount = bi.bmWidth * bi.bmHeight * 4;  // should be the actual required buff size
    	byte * lpBits = new byte[dwCount];
    	DWORD dw = bmp.GetBitmapBits(dwCount, lpBits);
    
    	delete [] lpBits;  lpBits = NULL;
    
    	dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);
    
    	bmDC.SelectObject(pOldbmp);
    
    }// OnBnClickedOpen()
    This code works just fine for the given bitmap (omm1.bmp, 288 x 288 pixels), but if the bitmap is partially covered by moving the dialog partially off screen, or if the dialog is minimized, then restored, the image disappears (fails to repaint). Any suggestions as to how to remedy this would be greatly appreciated.

    I have appended a demo to illustrate the problem.
    mpliam

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Getting a bitmap to redraw

    Good gracious, what are you doing!?!?

    To set the bitmap for a static, simply send it a STM_SETIMAGE message, with the bitmap handle cast to an LPARAM.

    IIRC, you are responsible for ownership of the bitmap, perhaps as a member variable of the class. I could be wrong.

    In any event, the code above could not possible work across minimization etc., since you are not allowing the static control to paint itself, from the static's OnPaint handler. But by far STM_SETIMAGE is simpler.

  3. #3
    Join Date
    May 2002
    Posts
    1,798

    Re: Getting a bitmap to redraw

    Thankyou for your kind and thoughtful response.

    I made the CBitmap bmp a member variable. Then using this code, IT WORKS!!
    Code:
    	// Load the Image File
    	HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, m_csPathname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    
    	//SendMessage(STM_SETIMAGE, (WPARAM) IDC_STATIC_IMAGE, (LPARAM)hBmp);  // this doesn't work
    	m_cImage.SendMessage(STM_SETIMAGE, 0, (LPARAM)hBmp);
    Thanks for a much simpler approach.
    Last edited by Mike Pliam; June 29th, 2012 at 10:00 PM.
    mpliam

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Getting a bitmap to redraw

    Quote Originally Posted by Mike Pliam View Post
    Code:
    	m_cImage.SendMessage(STM_SETIMAGE, 0, (LPARAM)hBmp);
    Well, but why not trust MFC?
    There is also since almost two decades CStatic::SetBitmap method! So why not just use it:
    Code:
    	m_cImage.SetBitmap(hBmp);
    Victor Nijegorodov

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured