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. BitBlt does not work in print preview

BitBlt does not work in print preview

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsperformancehelptutorialquestion
13 Posts 3 Posters 0 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.
  • T Offline
    T Offline
    theCPkid
    wrote on last edited by
    #1

    I am trying to draw something into memory DC and then copy it to screen or printer DC. I get the correct output drawing on screen or when directly taking the print out on printer. BUt while viewing print preview, it does not show any output.

    CMyView::OnDraw(CDC* pDC)
    {
    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
    return;

    CRect rcClient;
    
    if (pDC->IsPrinting()) 
    {
        rcClient = m\_rcPrintRect; //obtained from CPrintInfo
    }
    else
    {
        GetClientRect(&rcClient);
    }    
    
    CBitmap bmp;
    CDC memDC;
    
    memDC.CreateCompatibleDC(pDC);
    bmp.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
    memDC.SelectObject(&bmp);
    
    memDC.DrawText(L"Hello", &rcClient, DT\_CENTER | DT\_VCENTER);
    pDC->BitBlt(0,0,rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
    
    bmp.DeleteObject();
    memDC.DeleteDC();
    
    return;
    

    }

    I suspect something is wrong with creating compatible DC. pDC represents printer dc but the display is on screen. How to remove this problem? :sigh:

    M R 2 Replies Last reply
    0
    • T theCPkid

      I am trying to draw something into memory DC and then copy it to screen or printer DC. I get the correct output drawing on screen or when directly taking the print out on printer. BUt while viewing print preview, it does not show any output.

      CMyView::OnDraw(CDC* pDC)
      {
      CTestDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      if (!pDoc)
      return;

      CRect rcClient;
      
      if (pDC->IsPrinting()) 
      {
          rcClient = m\_rcPrintRect; //obtained from CPrintInfo
      }
      else
      {
          GetClientRect(&rcClient);
      }    
      
      CBitmap bmp;
      CDC memDC;
      
      memDC.CreateCompatibleDC(pDC);
      bmp.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
      memDC.SelectObject(&bmp);
      
      memDC.DrawText(L"Hello", &rcClient, DT\_CENTER | DT\_VCENTER);
      pDC->BitBlt(0,0,rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
      
      bmp.DeleteObject();
      memDC.DeleteDC();
      
      return;
      

      }

      I suspect something is wrong with creating compatible DC. pDC represents printer dc but the display is on screen. How to remove this problem? :sigh:

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #2

      What is the value of rcClient when it fails? I'm not seeing anything wrong with your DC creation... Mark

      Mark Salsbery Microsoft MVP - Visual C++ :java:

      T 1 Reply Last reply
      0
      • M Mark Salsbery

        What is the value of rcClient when it fails? I'm not seeing anything wrong with your DC creation... Mark

        Mark Salsbery Microsoft MVP - Visual C++ :java:

        T Offline
        T Offline
        theCPkid
        wrote on last edited by
        #3

        I checked it in debug mode. the program does not fail in print preview. BitBlt also completes successfully. only I do not get any output. I can initialize rcClient to (0,0,0,0) but that does not make a difference. Thanks.

        M 1 Reply Last reply
        0
        • T theCPkid

          I checked it in debug mode. the program does not fail in print preview. BitBlt also completes successfully. only I do not get any output. I can initialize rcClient to (0,0,0,0) but that does not make a difference. Thanks.

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          ok....and the answer to my question is? :) From the debugger, what is the left/top/right/bottom values of the rect?????

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          T 1 Reply Last reply
          0
          • M Mark Salsbery

            ok....and the answer to my question is? :) From the debugger, what is the left/top/right/bottom values of the rect?????

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            T Offline
            T Offline
            theCPkid
            wrote on last edited by
            #5

            oh sorry... in print preview, top=0, bottom=6400, left = 0, right=4900 (size of A4 sheet in pixels @600 dpi) in print, height= 6300, widht=4800...(because of different margin settings?)

            the fruits of your success will be in direct ratio to the honesty and sincerity of your own efforts in keeping your own records, doing your own thinking and, reaching your own conclusions. ..surviving in autumn..in love with spring..

            M 1 Reply Last reply
            0
            • T theCPkid

              oh sorry... in print preview, top=0, bottom=6400, left = 0, right=4900 (size of A4 sheet in pixels @600 dpi) in print, height= 6300, widht=4800...(because of different margin settings?)

              the fruits of your success will be in direct ratio to the honesty and sincerity of your own efforts in keeping your own records, doing your own thinking and, reaching your own conclusions. ..surviving in autumn..in love with spring..

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #6

              Arghh I'm drawing a blank here LOL What happens if you do pDC->MoveTo(rcClient.left, rcClient.top); pDC->LineTo(rcClient.right, rcClient.bottom); Do you get a diagonal line? Also is the bitmap creation succeeding?

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              T 1 Reply Last reply
              0
              • M Mark Salsbery

                Arghh I'm drawing a blank here LOL What happens if you do pDC->MoveTo(rcClient.left, rcClient.top); pDC->LineTo(rcClient.right, rcClient.bottom); Do you get a diagonal line? Also is the bitmap creation succeeding?

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                T Offline
                T Offline
                theCPkid
                wrote on last edited by
                #7

                Yes, I get a diagonal line. In fact. there's no problem with drawing directly on print preview dc. I am using memory dc in my code only to avoid flickering (perhaps it was obvious) The following code draws properly in print preview... by using DIB. But it's heavily slowing down my system. perhaps, I need to create DIB section in more elegant way. DDB provided by create compatible bitmap perhaps does not work. :doh:

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

                CRect rcClient;
                
                if (pDC->IsPrinting()) 
                {
                    rcClient = m\_rcPrintRect;
                }
                else
                {
                    GetClientRect(&rcClient);
                }    
                
                HBITMAP bmp;
                BYTE\* drawingSurfaceBits;
                BITMAPINFOHEADER            BMIH;
                BMIH.biSize = sizeof(BITMAPINFOHEADER);
                BMIH.biBitCount = 24;
                BMIH.biPlanes = 1;
                BMIH.biCompression = BI\_RGB;
                BMIH.biWidth = rcClient.Width();
                BMIH.biHeight = rcClient.Height();
                BMIH.biSizeImage = ((((BMIH.biWidth \* BMIH.biBitCount) + 31) & ~31) >> 3) \* BMIH.biHeight;
                bmp = CreateDIBSection(pDC->GetSafeHdc(), (CONST BITMAPINFO\*)&BMIH, DIB\_RGB\_COLORS, (void\*\*)&drawingSurfaceBits, NULL, 0);
                if((bmp == NULL) || (drawingSurfaceBits == NULL))
                {
                    AfxMessageBox(L"Bitmap not created", MB\_OK | MB\_ICONSTOP);
                    return;
                }
                
                memDC.CreateCompatibleDC(pDC);
                memDC.SelectObject(bmp);
                
                 memDC.DrawText(L"Hello", &rcClient, DT\_CENTER | DT\_VCENTER);
                 pDC->BitBlt(0,0,rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
                
                return;
                

                }

                Also, in print preview mode, the quality of picture shown on screen is extremely poor. I am perhaps using only rgb etc. I need to study bitmapinfoheader further. Thanks for the precious help. :)

                modified on Thursday, September 18, 2008 1:07 PM

                M 1 Reply Last reply
                0
                • T theCPkid

                  Yes, I get a diagonal line. In fact. there's no problem with drawing directly on print preview dc. I am using memory dc in my code only to avoid flickering (perhaps it was obvious) The following code draws properly in print preview... by using DIB. But it's heavily slowing down my system. perhaps, I need to create DIB section in more elegant way. DDB provided by create compatible bitmap perhaps does not work. :doh:

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

                  CRect rcClient;
                  
                  if (pDC->IsPrinting()) 
                  {
                      rcClient = m\_rcPrintRect;
                  }
                  else
                  {
                      GetClientRect(&rcClient);
                  }    
                  
                  HBITMAP bmp;
                  BYTE\* drawingSurfaceBits;
                  BITMAPINFOHEADER            BMIH;
                  BMIH.biSize = sizeof(BITMAPINFOHEADER);
                  BMIH.biBitCount = 24;
                  BMIH.biPlanes = 1;
                  BMIH.biCompression = BI\_RGB;
                  BMIH.biWidth = rcClient.Width();
                  BMIH.biHeight = rcClient.Height();
                  BMIH.biSizeImage = ((((BMIH.biWidth \* BMIH.biBitCount) + 31) & ~31) >> 3) \* BMIH.biHeight;
                  bmp = CreateDIBSection(pDC->GetSafeHdc(), (CONST BITMAPINFO\*)&BMIH, DIB\_RGB\_COLORS, (void\*\*)&drawingSurfaceBits, NULL, 0);
                  if((bmp == NULL) || (drawingSurfaceBits == NULL))
                  {
                      AfxMessageBox(L"Bitmap not created", MB\_OK | MB\_ICONSTOP);
                      return;
                  }
                  
                  memDC.CreateCompatibleDC(pDC);
                  memDC.SelectObject(bmp);
                  
                   memDC.DrawText(L"Hello", &rcClient, DT\_CENTER | DT\_VCENTER);
                   pDC->BitBlt(0,0,rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
                  
                  return;
                  

                  }

                  Also, in print preview mode, the quality of picture shown on screen is extremely poor. I am perhaps using only rgb etc. I need to study bitmapinfoheader further. Thanks for the precious help. :)

                  modified on Thursday, September 18, 2008 1:07 PM

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #8

                  Creating that big bitmap on every draw is going to be a little slow. I would only (re)create it when the size changes.

                  theCPkid wrote:

                  (CONST BITMAPINFO*)&BMIH

                  Bad cast!!!!! No bueno! You need to pass a pointer to a BITMAPINFO, not a pointer to a BITMAPINFOHEADER. The cast just hides the error from the compiler :) Try

                  BITMAPINFO bmi;
                  memset(&bmi, 0, sizeof(BITMAPINFO));
                  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                  bmi.bmiHeader.biWidth = rcClient.Width();
                  bmi.bmiHeader.biHeight = rcClient.Height();
                  bmi.bmiHeader.biPlanes = 1;
                  bmi.bmiHeader.biBitCount = 24;
                  bmi.bmiHeader.biCompression = BI_RGB;
                  bmi.bmiHeader.biSizeImage = ((((bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount) + 31) & ~31) >> 3) * bmi.bmiHeader.biHeight;
                  //bmi.bmiHeader.biXPelsPerMeter = 0;
                  //bmi.bmiHeader.biYPelsPerMeter = 0;
                  //bmi.bmiHeader.biClrUsed = 0;
                  //bmi.bmiHeader.biClrImportant = 0;

                  bmp = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&drawingSurfaceBits, NULL, 0);

                  I'm not sure what's going on with the rendering quality....I'll ponder that and let you know if I think of something...(maybe the code fix above will do better?) Mark

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  T 1 Reply Last reply
                  0
                  • T theCPkid

                    I am trying to draw something into memory DC and then copy it to screen or printer DC. I get the correct output drawing on screen or when directly taking the print out on printer. BUt while viewing print preview, it does not show any output.

                    CMyView::OnDraw(CDC* pDC)
                    {
                    CTestDoc* pDoc = GetDocument();
                    ASSERT_VALID(pDoc);
                    if (!pDoc)
                    return;

                    CRect rcClient;
                    
                    if (pDC->IsPrinting()) 
                    {
                        rcClient = m\_rcPrintRect; //obtained from CPrintInfo
                    }
                    else
                    {
                        GetClientRect(&rcClient);
                    }    
                    
                    CBitmap bmp;
                    CDC memDC;
                    
                    memDC.CreateCompatibleDC(pDC);
                    bmp.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
                    memDC.SelectObject(&bmp);
                    
                    memDC.DrawText(L"Hello", &rcClient, DT\_CENTER | DT\_VCENTER);
                    pDC->BitBlt(0,0,rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
                    
                    bmp.DeleteObject();
                    memDC.DeleteDC();
                    
                    return;
                    

                    }

                    I suspect something is wrong with creating compatible DC. pDC represents printer dc but the display is on screen. How to remove this problem? :sigh:

                    R Offline
                    R Offline
                    Roger Allen
                    wrote on last edited by
                    #9

                    The issues you may be seeing could be down to what raster operations are supported by the DC types in question. If you had been saying it shows in preview and not on the printer I would definately have said this, but you have it reversed which makes me intrigued (and I have even come out of CP semi-retirment to answer :omg:) The first thing I would say is drop BitBlt altogether. its not guaranteed to be compatible with both display DCs and printer DCs. Your best option would be to switch to StretchDIBits, from memory this is compatible with all DC types. Another thing that could be causing you problems is that your creating a DC compatible with a preview DC, this means you will have all the world transforms which map from print to preview display probably active on your memory DC. Try creating your comapatible DC directtly from the screen by passing NULL instead of pDC. If that fixes the issues then I would say its down to the preview DC supporting all the world transforms and your in effect drawing of the edge of the comaptible bitmap.

                    If you vote me down, my score will only get lower

                    T 1 Reply Last reply
                    0
                    • R Roger Allen

                      The issues you may be seeing could be down to what raster operations are supported by the DC types in question. If you had been saying it shows in preview and not on the printer I would definately have said this, but you have it reversed which makes me intrigued (and I have even come out of CP semi-retirment to answer :omg:) The first thing I would say is drop BitBlt altogether. its not guaranteed to be compatible with both display DCs and printer DCs. Your best option would be to switch to StretchDIBits, from memory this is compatible with all DC types. Another thing that could be causing you problems is that your creating a DC compatible with a preview DC, this means you will have all the world transforms which map from print to preview display probably active on your memory DC. Try creating your comapatible DC directtly from the screen by passing NULL instead of pDC. If that fixes the issues then I would say its down to the preview DC supporting all the world transforms and your in effect drawing of the edge of the comaptible bitmap.

                      If you vote me down, my score will only get lower

                      T Offline
                      T Offline
                      theCPkid
                      wrote on last edited by
                      #10

                      Roger Allen wrote:

                      but you have it reversed which makes me intrigued (and I have even come out of CP semi-retirment to answer )

                      Special thx for that.

                      Roger Allen wrote:

                      The first thing I would say is drop BitBlt altogether. its not guaranteed to be compatible with both display DCs and printer DCs. Your best option would be to switch to StretchDIBits, from memory this is compatible with all DC types.

                      yeah...as noted earlier, creating a DIB bitmap removes the problem with print preview but the application becomes very slow. Also, the image quality becomes very poor. You can see red, blue, green lines over the whole image.

                      Roger Allen wrote:

                      Try creating your comapatible DC directtly from the screen by passing NULL instead of pDC. If that fixes the issues then I would say its down to the preview DC supporting all the world transforms and your in effect drawing of the edge of the comaptible bitmap.

                      No, I tried that earlier...creating a dc for monitor in print preview mode does not work. Anyway, what I did last night is to check whether the DC is of type CPreviewDC. If it is, then I directly draw on that dc instead of creating a memory dc for it. otherwise I create a memory DC in case of print and normal view mode. It works correctly. Also, I am thinking of creating a smaller fixed size bitmap on which to draw and then StretchBlt it on whatever the size of actual DC. This will save me from creating a bitmap every time inside OnDraw as well as painting on larger DC. As of now, the applicaion is taking large CPU power and I am trying to find out various tools for profiling that can help me find bad code. X| Thanks for your suggestion.

                      1 Reply Last reply
                      0
                      • M Mark Salsbery

                        Creating that big bitmap on every draw is going to be a little slow. I would only (re)create it when the size changes.

                        theCPkid wrote:

                        (CONST BITMAPINFO*)&BMIH

                        Bad cast!!!!! No bueno! You need to pass a pointer to a BITMAPINFO, not a pointer to a BITMAPINFOHEADER. The cast just hides the error from the compiler :) Try

                        BITMAPINFO bmi;
                        memset(&bmi, 0, sizeof(BITMAPINFO));
                        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                        bmi.bmiHeader.biWidth = rcClient.Width();
                        bmi.bmiHeader.biHeight = rcClient.Height();
                        bmi.bmiHeader.biPlanes = 1;
                        bmi.bmiHeader.biBitCount = 24;
                        bmi.bmiHeader.biCompression = BI_RGB;
                        bmi.bmiHeader.biSizeImage = ((((bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount) + 31) & ~31) >> 3) * bmi.bmiHeader.biHeight;
                        //bmi.bmiHeader.biXPelsPerMeter = 0;
                        //bmi.bmiHeader.biYPelsPerMeter = 0;
                        //bmi.bmiHeader.biClrUsed = 0;
                        //bmi.bmiHeader.biClrImportant = 0;

                        bmp = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&drawingSurfaceBits, NULL, 0);

                        I'm not sure what's going on with the rendering quality....I'll ponder that and let you know if I think of something...(maybe the code fix above will do better?) Mark

                        Mark Salsbery Microsoft MVP - Visual C++ :java:

                        T Offline
                        T Offline
                        theCPkid
                        wrote on last edited by
                        #11

                        Does not make any difference on rendering quality and the quality is very poor. So, I am not using it in my code as of now. Thanks.

                        M 1 Reply Last reply
                        0
                        • T theCPkid

                          Does not make any difference on rendering quality and the quality is very poor. So, I am not using it in my code as of now. Thanks.

                          M Offline
                          M Offline
                          Mark Salsbery
                          wrote on last edited by
                          #12

                          It's not your code or my code causing poor quality...either way should work. Rendering some text in a 6400x4900 offscreen buffer then squishing it down to fit a window is going to look bad. The only way to make it look 100% correct is to make your bitmap the exact size it will be rendered on the screen.

                          Mark Salsbery Microsoft MVP - Visual C++ :java:

                          T 1 Reply Last reply
                          0
                          • M Mark Salsbery

                            It's not your code or my code causing poor quality...either way should work. Rendering some text in a 6400x4900 offscreen buffer then squishing it down to fit a window is going to look bad. The only way to make it look 100% correct is to make your bitmap the exact size it will be rendered on the screen.

                            Mark Salsbery Microsoft MVP - Visual C++ :java:

                            T Offline
                            T Offline
                            theCPkid
                            wrote on last edited by
                            #13

                            oh! I got your point. I did not think about it earlier. Thanks again.

                            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