Click here to Skip to main content
15,886,067 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a dialog and Tab Control on it. I need draw a picture in the definite rectangle on a page of the Tab Control. So I declare an object of a class that is responsible for bitmap work for example as CDIBitmap m_bmpBackground. Bitmap file is loaded with:

BOOL CDIBitmap :: Load( CFile* pFile ) {
    ASSERT( pFile );
    BOOL fReturn = TRUE;
    try {
        delete [] (BYTE*)m_pInfo;
        delete [] m_pPixels;
        m_pInfo = 0;
        m_pPixels = 0;
        DWORD       dwStart = pFile->GetPosition();
        //
        // Check to make sure we have a bitmap. The first two bytes must
        // be 'B' and 'M'.
        BITMAPFILEHEADER fileHeader;
        pFile->Read(&fileHeader, sizeof(fileHeader));
        if( fileHeader.bfType != 0x4D42 )
            throw TEXT("Error:Unexpected file type, not a DIB\n");

        BITMAPINFOHEADER infoHeader;
        pFile->Read( &infoHeader, sizeof(infoHeader) );
        if( infoHeader.biSize != sizeof(infoHeader) )
            throw TEXT("Error:OS2 PM BMP Format not supported\n");

        // Store the sizes of the DIB structures
        int cPaletteEntries = GetPalEntries( infoHeader );
        int cColorTable = 256 * sizeof(RGBQUAD);
        int cInfo = sizeof(BITMAPINFOHEADER) + cColorTable;
        int cPixels = fileHeader.bfSize - fileHeader.bfOffBits;
        //
        // Allocate space for a new bitmap info header, and copy
        // the info header that was loaded from the file. Read the
        // the file and store the results in the color table.
        m_pInfo = (BITMAPINFO*)new BYTE[cInfo];
        memcpy( m_pInfo, &infoHeader, sizeof(BITMAPINFOHEADER) );
        pFile->Read( ((BYTE*)m_pInfo) + sizeof(BITMAPINFOHEADER),
                     cColorTable );
        //
        // Allocate space for the pixel area, and load the pixel
        // info from the file.
        m_pPixels = new BYTE[cPixels];
        pFile->Seek(dwStart + fileHeader.bfOffBits, CFile::begin);
        pFile->Read( m_pPixels, cPixels );
		CreatePalette();
		m_bIsPadded = TRUE;
#ifdef _DEBUG
    } catch( TCHAR * psz ) {
		TRACE( psz );
#else
    } catch( TCHAR * ) {
#endif
        fReturn = FALSE;
    }
    return fReturn;
}


Then I call Invalidate() function and get into OnEraseBkgnd where a picture is actually being drawn:

BOOL CAtmNcr::OnEraseBkgnd(CDC* pDC) 
{
	if(m_bmpBackground.GetPixelPtr() != 0) 
	{
		CRect rc;
		
		m_myWnd.GetWindowRect(rc);
		ScreenToClient( &rc );
		int x = 0, y = 0;

		// center the bitmap
		/*
		CDialog::OnEraseBkgnd(pDC);
		x = (rc.Width() - m_bmpBackground.GetWidth()) / 2;
		y = (rc.Height() - m_bmpBackground.GetHeight()) / 2;
		m_bmpBackground.DrawDIB(pDC, x, y);
		*/

		// stretch
		m_bmpBackground.DrawDIB(pDC, rc.left, rc.top, rc.Width(), rc.Height());
	} 
	else
		// no bitmap set. behave like a normal dialog
		return CDialog::OnEraseBkgnd(pDC);

	return true;
}


DrawDIB is defined as follows:

// DrawDib uses StretchDIBits to display the bitmap.
void CDIBitmap :: DrawDIB( CDC* pDC, int x, int y, int width, int height ) {
    ASSERT( pDC );
    HDC     hdc = pDC->GetSafeHdc();

    if( m_pInfo )
        StretchDIBits( hdc,
                       x,
                       y+GetHeight(),
                       width,
                       -height,
                       0,
                       0,
                       GetWidth(),
                       GetHeight(),
                       GetPixelPtr(),
                       GetHeaderPtr(),
                       DIB_RGB_COLORS,
                       SRCCOPY );
	
}


The loaded picture is definitely drawn in the rectangle and you see it but untill OnEraseBkgnd is left. How come? If you apply the same code to parent dialog window then it works perfectly.
Posted
Updated 6-Nov-10 1:04am
v2

I guess your image is being drawn, but erased on WM_PAINT. Try blitting the image on WM_PAINT - a good idea if you're drawing on the whole parent window (your tab ctl). Or else, i suggest you keep a static control of the size & pos you want & draw on that.

Also make sure you're drawing on the page control/window if you're maintaining them and not the tab control itself because the actual tab control will be behind them.
 
Share this answer
 
Thank you, strogg. You're right. WM_PAINT erased my drawn picture as I really used static control to get size of a rectangle before drawing and the static control was put over my picture in the last. So I hide static control when its dimensions are defined and only then a picture is drawn. I appreciate your help and thank you for your time.
 
Share this answer
 
Comments
strogg 11-Nov-10 0:35am    
Thanks man. Also take a look at the extended window style WM_EX_TRANSPARENT (info in CreateWindowEx()). You might find it interesting

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900