Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. MFC. How to display a bitmap or a .png file

MFC. How to display a bitmap or a .png file

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsc++performancetutoriallearning
32 Posts 6 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B BigSteve O

    Thank You. Appreciate it.

    C Offline
    C Offline
    charlieg
    wrote on last edited by
    #21

    Okay, you have an error in your code: // Copy the bits from the memory DC into the current dc pDC->BitBlt(20, 10, 436, 364, &MemDCLady, 0, 0, SRCCOPY); is the culprit. Recall that you've set your coordinate system to low English which fixes the bassackwardness of drawing. If you trace your board generation, you will see that your Y values go from 0 to negative values. Looking at the above line, you are drawing off the top of your view window. Change the 364 to -364 and you'll see your image. Of course, *I've* never done that :)

    Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

    1 Reply Last reply
    0
    • B BigSteve O

      Thank You. Appreciate it.

      C Offline
      C Offline
      charlieg
      wrote on last edited by
      #22

      See my other reply.

      Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

      1 Reply Last reply
      0
      • CPalliniC CPallini

        That's rather strange. Do you use the same DC for the board and bitmap?

        "In testa che avete, Signor di Ceprano?" -- Rigoletto

        B Offline
        B Offline
        BigSteve O
        wrote on last edited by
        #23

        Yes, I do.

        L 1 Reply Last reply
        0
        • B BigSteve O

          Yes, I do.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #24

          Post the complete contents of both your [WM_PAINT](https://learn.microsoft.com/en-us/windows/win32/gdi/wm-paint) and [WM_ERASEBKGND](https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd). I can help but I need to see both.

          B 1 Reply Last reply
          0
          • L Lost User

            Post the complete contents of both your [WM_PAINT](https://learn.microsoft.com/en-us/windows/win32/gdi/wm-paint) and [WM_ERASEBKGND](https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd). I can help but I need to see both.

            B Offline
            B Offline
            BigSteve O
            wrote on last edited by
            #25

            Here is my onDraw()

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

            // TODO: add draw code for native data here
            // Draw the empty board....
            drawImage(pDC, 100, 100);
            drawEmptyBoard(pDC);
            

            }

            Here is the drawImage(...)

            void CMyChessTestView::drawImage(CDC* pDC, int x, int y)
            {

            // load IDB\_BITMAP1 from our resources
            CBitmap bmp;
            if (bmp.LoadBitmap(IDB\_LADYPIC))
            {
            	// Get the size of the bitmap
            	BITMAP bmpInfo;
            	bmp.GetBitmap(&bmpInfo);
            
            	// Create an in-memory DC compatible with the
            	// display DC we're using to paint
            	CDC dcMemory;
            	
            	dcMemory.CreateCompatibleDC(pDC);
            
            	// Select the bitmap into the in-memory DC
            	CBitmap \*pOldBitmap = dcMemory.SelectObject(&bmp);
            
            	// Find a centerpoint for the bitmap in the client area
            	CRect rect;
            	GetClientRect(&rect);
            	int nX = rect.left + (rect.Width() - bmpInfo.bmWidth) / 2;
            	int nY = rect.top + (rect.Height() - bmpInfo.bmHeight) / 2;
            
            	// Copy the bits from the in-memory DC into the on-
            	// screen DC to actually do the painting. Use the centerpoint
            	// we computed for the target offset.
            	pDC->BitBlt(nX, nY, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory,
            		0, 0, SRCCOPY);
            
            	dcMemory.SelectObject(pOldBitmap);
            }
            else
            {
            	TRACE0("ERROR: Where's IDB\_LADYPIC?\\n");
            }
            

            }

            Here is the drawEmptyBoard()

            void CMyChessTestView::drawEmptyBoard(CDC* pDC)
            {
            CMyChessTestDoc* pBC = GetDocument();
            ASSERT_VALID(pBC);
            if (!pBC)
            return;
            //drawImage(pDC, 80, 80);
            pDC->SetMapMode(MM_LOENGLISH);
            pDC->SetWindowExt(800, 800);
            //pDC->SetViewportOrg(testrec.Width(), testrec.Height());

            for (int i = 0; i < 8; i++)
            {
            	for (int j = 0; j < 8; j++)
            	{
            		COLORREF color = pBC->getSquare(i, j);
            		CBrush brush(color);
            		int x1 = (j \* 70) + 35;
            		int y1 = (i \* -70) - 35;
            		int x2 = x1 + 70;
            		int y2 = y1 - 70;
            		CRect rect(x1, y1, x2, y2);
            		pDC->FillRect(rect, &brush);
            		//pDC->Rectangle(rect);
            	}
            }
            // Now draw the borders
            for (int x = 35; x <= 595; x += 70)
            {
            	pDC->MoveTo(x, -35);
            	pDC->LineTo(x, -595);
            }
            for (int y = -35; y >= -595; y -= 70)
            {
            	pDC->MoveTo(35, y);
            	pDC->LineTo(595, y);
            }
            
            L 1 Reply Last reply
            0
            • B BigSteve O

              Here is my onDraw()

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

              // TODO: add draw code for native data here
              // Draw the empty board....
              drawImage(pDC, 100, 100);
              drawEmptyBoard(pDC);
              

              }

              Here is the drawImage(...)

              void CMyChessTestView::drawImage(CDC* pDC, int x, int y)
              {

              // load IDB\_BITMAP1 from our resources
              CBitmap bmp;
              if (bmp.LoadBitmap(IDB\_LADYPIC))
              {
              	// Get the size of the bitmap
              	BITMAP bmpInfo;
              	bmp.GetBitmap(&bmpInfo);
              
              	// Create an in-memory DC compatible with the
              	// display DC we're using to paint
              	CDC dcMemory;
              	
              	dcMemory.CreateCompatibleDC(pDC);
              
              	// Select the bitmap into the in-memory DC
              	CBitmap \*pOldBitmap = dcMemory.SelectObject(&bmp);
              
              	// Find a centerpoint for the bitmap in the client area
              	CRect rect;
              	GetClientRect(&rect);
              	int nX = rect.left + (rect.Width() - bmpInfo.bmWidth) / 2;
              	int nY = rect.top + (rect.Height() - bmpInfo.bmHeight) / 2;
              
              	// Copy the bits from the in-memory DC into the on-
              	// screen DC to actually do the painting. Use the centerpoint
              	// we computed for the target offset.
              	pDC->BitBlt(nX, nY, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory,
              		0, 0, SRCCOPY);
              
              	dcMemory.SelectObject(pOldBitmap);
              }
              else
              {
              	TRACE0("ERROR: Where's IDB\_LADYPIC?\\n");
              }
              

              }

              Here is the drawEmptyBoard()

              void CMyChessTestView::drawEmptyBoard(CDC* pDC)
              {
              CMyChessTestDoc* pBC = GetDocument();
              ASSERT_VALID(pBC);
              if (!pBC)
              return;
              //drawImage(pDC, 80, 80);
              pDC->SetMapMode(MM_LOENGLISH);
              pDC->SetWindowExt(800, 800);
              //pDC->SetViewportOrg(testrec.Width(), testrec.Height());

              for (int i = 0; i < 8; i++)
              {
              	for (int j = 0; j < 8; j++)
              	{
              		COLORREF color = pBC->getSquare(i, j);
              		CBrush brush(color);
              		int x1 = (j \* 70) + 35;
              		int y1 = (i \* -70) - 35;
              		int x2 = x1 + 70;
              		int y2 = y1 - 70;
              		CRect rect(x1, y1, x2, y2);
              		pDC->FillRect(rect, &brush);
              		//pDC->Rectangle(rect);
              	}
              }
              // Now draw the borders
              for (int x = 35; x <= 595; x += 70)
              {
              	pDC->MoveTo(x, -35);
              	pDC->LineTo(x, -595);
              }
              for (int y = -35; y >= -595; y -= 70)
              {
              	pDC->MoveTo(35, y);
              	pDC->LineTo(595, y);
              }
              
              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #26

              Really? You draw the chess piece first and then draw the chess board on top of it?

              B 1 Reply Last reply
              0
              • L Lost User

                Really? You draw the chess piece first and then draw the chess board on top of it?

                B Offline
                B Offline
                BigSteve O
                wrote on last edited by
                #27

                No, It serves to demonstrate that if I draw the board first, the pieces will not show up, and that by drawing the piece first and then the board, all shows up.

                V CPalliniC 2 Replies Last reply
                0
                • B BigSteve O

                  No, It serves to demonstrate that if I draw the board first, the pieces will not show up, and that by drawing the piece first and then the board, all shows up.

                  V Offline
                  V Offline
                  Victor Nijegorodov
                  wrote on last edited by
                  #28

                  BigSteve-O wrote:

                  if I draw the board first, the pieces will not show up, and that by drawing the piece first and then the board, all shows up.

                  Then why do you try to draw first the board? :confused:

                  1 Reply Last reply
                  0
                  • B BigSteve O

                    No, It serves to demonstrate that if I draw the board first, the pieces will not show up, and that by drawing the piece first and then the board, all shows up.

                    CPalliniC Offline
                    CPalliniC Offline
                    CPallini
                    wrote on last edited by
                    #29

                    OK, I was able to reproduce your issue, and with a bit of luck, to fix it. The problem arises when you change the DC mapping mode. Now while I am not an expert of mapping modes, this code displays the bitmap over the empty board: Inside OnDraw (is actually OnPaint in my test app)

                    //..
                    drawEmptyBoard(&dc);
                    drawImage(&dc, 105, -105); // note the negative y
                    //..

                    While drawImage becomes

                    /*..*/::drawImage(CDC* pDC, int x, int y)
                    {
                    CBitmap bmp;
                    if (bmp.LoadBitmap(IDB_LADYPIC))
                    {
                    BITMAP bmpInfo;
                    bmp.GetBitmap(&bmpInfo);

                    	CDC dcMemory;
                    
                    	dcMemory.CreateCompatibleDC(pDC);
                    	dcMemory.SetMapMode(pDC->GetMapMode()); // as weird as it looks, the map mode is not the same, after CreateCompatibleDC
                    
                    	// Select the bitmap into the in-memory DC
                    	CBitmap\* pOldBitmap = dcMemory.SelectObject(&bmp);
                    
                    	pDC->StretchBlt(x, y, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory,0, 0, bmpInfo.bmWidth, -bmpInfo.bmHeight, SRCCOPY); // note the negative height of the bitmap
                    
                    	dcMemory.SelectObject(pOldBitmap);
                    }
                    

                    }

                    To make things more explicit, I would move the SetMapMode call out of drawEmptyBoard.

                    "In testa che avete, Signor di Ceprano?" -- Rigoletto

                    In testa che avete, signor di Ceprano?

                    B 1 Reply Last reply
                    0
                    • CPalliniC CPallini

                      OK, I was able to reproduce your issue, and with a bit of luck, to fix it. The problem arises when you change the DC mapping mode. Now while I am not an expert of mapping modes, this code displays the bitmap over the empty board: Inside OnDraw (is actually OnPaint in my test app)

                      //..
                      drawEmptyBoard(&dc);
                      drawImage(&dc, 105, -105); // note the negative y
                      //..

                      While drawImage becomes

                      /*..*/::drawImage(CDC* pDC, int x, int y)
                      {
                      CBitmap bmp;
                      if (bmp.LoadBitmap(IDB_LADYPIC))
                      {
                      BITMAP bmpInfo;
                      bmp.GetBitmap(&bmpInfo);

                      	CDC dcMemory;
                      
                      	dcMemory.CreateCompatibleDC(pDC);
                      	dcMemory.SetMapMode(pDC->GetMapMode()); // as weird as it looks, the map mode is not the same, after CreateCompatibleDC
                      
                      	// Select the bitmap into the in-memory DC
                      	CBitmap\* pOldBitmap = dcMemory.SelectObject(&bmp);
                      
                      	pDC->StretchBlt(x, y, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory,0, 0, bmpInfo.bmWidth, -bmpInfo.bmHeight, SRCCOPY); // note the negative height of the bitmap
                      
                      	dcMemory.SelectObject(pOldBitmap);
                      }
                      

                      }

                      To make things more explicit, I would move the SetMapMode call out of drawEmptyBoard.

                      "In testa che avete, Signor di Ceprano?" -- Rigoletto

                      B Offline
                      B Offline
                      BigSteve O
                      wrote on last edited by
                      #30

                      Thank you so much for your suggestions. It is much appreciated! I am going to try it soon.

                      CPalliniC 1 Reply Last reply
                      0
                      • B BigSteve O

                        Thank you so much for your suggestions. It is much appreciated! I am going to try it soon.

                        CPalliniC Offline
                        CPalliniC Offline
                        CPallini
                        wrote on last edited by
                        #31

                        You are welcome.

                        "In testa che avete, Signor di Ceprano?" -- Rigoletto

                        In testa che avete, signor di Ceprano?

                        1 Reply Last reply
                        0
                        • B BigSteve O

                          Good Morning. In my view class in the onDraw() function, I am drawing the board and filling in the squares as follows:

                          pDC->SetMapMode(MM\_LOENGLISH);
                          pDC->SetWindowExt(800, 800);
                          //pDC->SetViewportOrg(testrec.Width(), testrec.Height());
                          
                          for (int i = 0; i < 8; i++)
                          {
                          	for (int j = 0; j < 8; j++)
                          	{
                          		COLORREF color = pBC->getSquare(i, j);
                          		CBrush brush(color);
                          		int x1 = (j \* 70) + 35;
                          		int y1 = (i \* -70) - 35;
                          		int x2 = x1 + 70;
                          		int y2 = y1 - 70;
                          		CRect rect(x1, y1, x2, y2);
                          		pDC->FillRect(rect, &brush);
                          	}
                          }
                          // Now draw the borders
                          for (int x = 35; x <= 595; x += 70)
                          {
                          	pDC->MoveTo(x, -35);
                          	pDC->LineTo(x, -595);
                          }
                          for (int y = -35; y >= -595; y -= 70)
                          {
                          	pDC->MoveTo(35, y);
                          	pDC->LineTo(595, y);
                          }
                          

                          This all works well, and I have my board coming up.

                          Now I want to draw the chess pieces on the board, and have written some code, just to load 1 bitgmap and display it on the screen. However, nothing gets drawn to the screen. (All I see is just the chessboard)

                          This is the test code to display my bitmap on the screen:

                          void CMyChessTestView::drawImage(CDC* pDC, int x, int y)
                          {

                          CPaintDC dc(this); // device context for painting
                          
                          // TODO: Add your message handler code here
                          CBitmap BmpLady;
                          CDC MemDCLady;
                          
                          // Load the bitmap from the resource
                          BmpLady.LoadBitmap(IDB\_BISHOP\_WHITE);
                          // Create a memory device compatible with the above CPaintDC variable
                          MemDCLady.CreateCompatibleDC(/\*&dc\*/pDC);
                          // Select the new bitmap
                          CBitmap \*BmpPrevious = MemDCLady.SelectObject(&BmpLady);
                          
                          // Copy the bits from the memory DC into the current dc
                          pDC->BitBlt(20, 10, 436, 364, &MemDCLady, 0, 0, SRCCOPY);
                          
                          // Restore the old bitmap
                          pDC->SelectObject(BmpPrevious);
                          // Do not call CView::OnPaint() for painting messages
                          

                          The bitmap is not drwan to the screen. I have tried using both the CPaintDC dc or the pDC* but to no avail. I cannot get the bitmap to display. Any suggestions will be greatly appreciated.

                          C Offline
                          C Offline
                          charlieg
                          wrote on last edited by
                          #32

                          it would be polite to let us know if things are working now...

                          Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups