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 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