Learning bitmap operation of MFC

1. Notes

1.1 concept of bitmap

BITMAP is a file format that directly stores the image data of the display bit by bit without compression. BITMAP is mainly divided into device dependent BITMAP (DDB) and device independent BITMAP (DIB). DIB is left in the file with the extension bmp. DDB, also known as GDI BITMAP, is an MFC internal BITMAP format, which is described by the BITMAP structure.

Obviously, the DIB BITMAP imported into MFC project will be converted into DDB BITMAP and transferred to BITMAP structure.

1.2 bitmap operation function

1.2.1 create a memory device context function compatible with the specified device context

Function prototype:

virtual BOOL CDC::CreateCompatibleDC(CDC* pDC);

pDC is the pointer to display the device context. If the call is successful, it returns non-zero, otherwise it returns zero.

1.2.2 import bitmap function

Function prototype:

BOOL CBitmap::LoadBitmap(LPCTSTR lpszResourceName);
BOOL CBitmap::LoadBitmap(UNIT nIDResource);

lpszResourceName refers to a NULL terminated string containing the name of the bitmap resource. nIDResource is the ID number of the bitmap resource. If the call is successful, it returns non-zero, otherwise it returns zero.

1.2.3 get bitmap information function

Function prototype:

int CBitmap::GetBitmap(BITMAP* pBitmap);

BITMAP defines the width, height, color format and byte data of the logical BITMAP. If the call is successful, it returns non-zero, otherwise it returns zero.

1.2.4 bit block transfer function

Function prototype:

BOOL CDC::BitBlt(int x,int y,int nWidth,int nHeight,
    CDC* pSrcDC,int xSrc,int ySrc,DWORD dwRop);

(x,y) is the coordinate with the smallest coordinate value in the specified target rectangle area, also known as the logical coordinate in the upper left corner. nWidth and nHeight are the width and height of the target rectangle and the source bitmap respectively (that is, (x+nWidth,y+nHeight) reaches the other end point on the diagonal of the target rectangle), (xSrc,ySrc) is the logical coordinate in the upper left corner of the source bitmap, and dwRop is the raster opcode, The most commonly used raster opcode is SRCCOPY, which means that the source bitmap is copied directly to the target device context. If the call is successful, it returns non-zero, otherwise it returns zero.

1.2.5 stretch bitmap function

If the size of the destination rectangle and the source bitmap are inconsistent, you need to use the stretch bitmap function.

Function prototype:

BOOL CDC::StretchBlt(int x,int y,int nWidth,int nHeight,
    CDC* pSrcDC,int xSrc,int ySrc,int nSrcWidth,int nSrcHeight,
    DWORD dwRop);

nSrcWidth and nSrcHeight are the width and height of the source bitmap. Other parameters have the same meaning as BitBlt. If the call is successful, it returns non-zero, otherwise it returns zero.

2. Use exercise

2.1 display a bitmap in the customer area.

void CExample1View::OnDraw(CDC* pDC)
{
	CExample1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: add drawing code for native data here
	CRect rect;
	GetClientRect(rect);

	CDC memDC;
	memDC.CreateCompatibleDC(pDC);//Create a device context compatible with the display device context
	CBitmap newBitmap, * pOldBitmap;
	newBitmap.LoadBitmapW(IDB_BITMAP1);//Load bitmap
	pOldBitmap = memDC.SelectObject(&newBitmap);//Import bitmap and save old bitmap
	pDC->BitBlt(0, 0, rect.Width(), rect.Height(),//Copy bitmap to display device context
		&memDC, 0, 0, SRCCOPY);

	memDC.SelectObject(pOldBitmap);//Recover device context
	newBitmap.DeleteObject();//Delete used bitmaps
	memDC.DeleteDC();//Delete used device context
}

2.2 use a custom coordinate system to display a bitmap, and stretch the bitmap to fill the client area.

void CExample1View::OnDraw(CDC* pDC)
{
	CExample1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: add drawing code for native data here
	CRect rect;
	GetClientRect(rect);
	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowExt(rect.Width(), rect.Height());
	pDC->SetViewportExt(rect.Width(), -rect.Height());
	pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
	rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);

	CDC memDC;
	memDC.CreateCompatibleDC(pDC);//Create a device context compatible with the display device context

	CBitmap newBitmap, * pOldBitmap;
	newBitmap.LoadBitmapW(IDB_BITMAP1);//Load bitmap

	BITMAP bmp;
	newBitmap.GetBitmap(&bmp);//Get bitmap information

	pOldBitmap = memDC.SelectObject(&newBitmap);//Import bitmap and save old bitmap

	memDC.SetMapMode(MM_ANISOTROPIC);//Build the device context of the imported bitmap
	memDC.SetWindowExt(bmp.bmWidth, bmp.bmHeight);//Make it consistent with the coordinate system of the display device context
	memDC.SetViewportExt(bmp.bmWidth, -bmp.bmHeight);
	memDC.SetViewportOrg(bmp.bmWidth / 2, bmp.bmHeight / 2);
        
        //Copy bitmap to display device context
	pDC->StretchBlt(-rect.Width() / 2, -rect.Height() / 2, //Equivalent to rect left,rect. top
		rect.Width(), rect.Height(),
		&memDC, -bmp.bmWidth / 2, -bmp.bmHeight / 2, 
		bmp.bmWidth, bmp.bmHeight, SRCCOPY);
	memDC.SelectObject(pOldBitmap);//Recover device context
	newBitmap.DeleteObject();//Delete used bitmaps
	memDC.DeleteDC();//Delete used device context
}

The implementation effect is that the bitmap fills the whole client area, and the bitmap changes with the change of window size.

Keywords: MFC

Added by maxelcat on Sat, 01 Jan 2022 20:29:07 +0200