Announcement

Collapse
No announcement yet.

Printing contents of window hdc

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Printing contents of window hdc

    I have loaded an image onto my main window using gdiplus, and have written over the image by drawing to the window's hdc.
    Now how can I print all that out showing both the image and the drawing done to the hdc ?
    Jim Seekamp

  • #2
    You need to have a copy of the window in a Bitmap to work with (or at least the Bits in a buffer).

    The appropriate API to use to draw a Bitmap (actually its bits) to a printer is:

    StretchDIBits

    Do not use BitBlt or StretchBlt !

    Printer drivers do no support all GDI functions.
    StretchDIBits is the defacto standard for drawing to printer DC's and most (if not all) printer drivers should support it).
    Chris Boss
    Computer Workshop
    Developer of "EZGUI"
    http://cwsof.com
    http://twitter.com/EZGUIProGuy

    Comment


    • #3
      Jim,

      Look at... http://www.powerbasic.com/support/fo...ML/001514.html

      I'm sure it can be adopted to print a dynamically created DIB.

      Oh!.. and download this .... PrintBMP.zip http://www.powerbasic.com/files/pub/pbwin/misc/

      HTH
      Regards,
      Jules
      Last edited by Jules Marchildon; 1 Feb 2008, 07:22 PM.
      Best regards
      Jules
      www.rpmarchildon.com

      Comment


      • #4
        Thanks guys!
        Jim Seekamp

        Comment


        • #5
          Sorry, I haven't been able to get back to this until now...
          I'm saving the window to a bitmap and I have a handle to the bitmap, but is there some kind of shortcut for saving the bitmap to a .bmp file??

          Code:
                       hdcgr&=getdc(hwnd&)
          
                       getclientrect hwnd&,strc
          
                       bmlength&=(strc.nright-strc.nleft)+1
                       bmheight&=(strc.nbottom-strc.ntop)+1
                       hbitmap&=createcompatiblebitmap(hdcgr&,bmlength&,bmheight&)
          Jim Seekamp

          Comment


          • #6
            Courtesy of...
            Code:
            'Brad D Byrne, Member
            'posted May 25, 2004 03:39 AM
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            #COMPILE EXE
            #INCLUDE "WIN32API.INC"
            GLOBAL hDlg&,hLoadDlg&, hMemDC&,hMemBmp& ,hMemDC2&,hMemBmp2&
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               $BmpFile = "C:\MyBmp.Bmp"
            
               '====================================================
               FUNCTION CreateTrueColorBmpFile (FileBmp AS STRING, hWnd AS LONG, rc AS RECT) AS LONG
                  LOCAL f AS LONG, hDC AS LONG, hMemDC AS LONG
                  LOCAL hMemBmp AS LONG, bm AS BITMAP, bmi AS BITMAPINFO
                  LOCAL lpBITMAPFILEHEADER AS BITMAPFILEHEADER, lpBITMAPINFOHEADER AS BITMAPINFOHEADER
            
                  hDC = GetDC(hWnd): hMemDC = CreateCompatibleDC (hDC)
            
                  bmi.bmiHeader.biSize = SIZEOF(bmi.bmiHeader)
                  bmi.bmiHeader.biWidth = (rc.nRight - rc.nLeft)
                  bmi.bmiHeader.biHeight = (rc.nBottom - rc.nTop)
                  bmi.bmiHeader.biPlanes = 1
                  bmi.bmiHeader.biBitCount = 24
                  bmi.bmiHeader.biCompression = %BI_RGB
                  hMemBmp = CreateDIBSection(hMemDC, bmi, %DIB_RGB_COLORS, 0, 0, 0)
                  GlobalLock hMemBmp
                  SelectObject hMemDC, hMemBmp
                  GetObject hMemBmp, SIZEOF(bm), bm
                  BitBlt hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, rc.nLeft, rc.nTop, %SRCCOPY
            
                  lpBITMAPFILEHEADER.bfType = CVI("BM")
                  lpBITMAPFILEHEADER.bfSize = LEN(lpBITMAPFILEHEADER) + LEN(lpBITMAPINFOHEADER) + _
                     bm.bmWidthBytes * bm.bmHeight
                  lpBITMAPFILEHEADER.bfOffBits = 54
                  lpBITMAPINFOHEADER.biSize = 40
                  lpBITMAPINFOHEADER.biWidth = bm.bmWidth
                  lpBITMAPINFOHEADER.biHeight = bm.bmHeight
                  lpBITMAPINFOHEADER.biPlanes = 1
                  lpBITMAPINFOHEADER.biBitCount = 24
                  lpBITMAPINFOHEADER.biSizeImage = bm.bmWidthBytes * bm.bmHeight
            
                  f = FREEFILE: OPEN FileBmp FOR OUTPUT AS #f
                  PRINT #f, lpBITMAPFILEHEADER lpBITMAPINFOHEADER _
                      PEEK$(bm.bmBits, bm.bmWidthBytes * bm.bmHeight);: CLOSE #f
            
                  ReleaseDC hWnd, hDC: DeleteDC hMemDC: GlobalUnlock hMemBmp: DeleteObject hMemBmp
               END FUNCTION
            
            CALLBACK FUNCTION Load_proc()
            LOCAL hDC&
            
            SELECT CASE CBMSG
                CASE %WM_INITDIALOG
                LOCAL xx&,yy& ,Bm2 AS BITMAP ,rc AS rect
            
                hdc= GetDc(CBHNDL)
                hMemDC2&= CreateCompatibleDC(hdc&)
                hMemBmp2&= CreateCompatibleBitmap(hdc&,1,1)
            
                hMemBmp2& = LoadImage(GetModuleHandle (BYVAL 0), $BmpFile, %IMAGE_BITMAP,0,0,%LR_LOADFROMFILE)
               ' hDC& = GetDC(CBHNDL)
               ' hMemDC2&= CreateCompatibleDC(hDC&)
                SelectObject hMemDC2&, hMemBmp2&
                releaseDC CBHNDL,hDC&
                GetObject hMemBmp2&, SIZEOF(bm2),bm2
            
                DIALOG PIXELS hLoadDlg&, bm2.bmWidth,bm2.bmHeight TO UNITS xx&,yy&
                DIALOG SET SIZE hLoadDlg&,xx&+20,yy&+42
                setwindowText hLoadDlg&,$BmpFile
                InvalidateRect CBHNDL,BYVAL %NULL, 1
                DeleteObject hMemBmp2&
            
            CASE %WM_PAINT
                 LOCAL ps AS PAINTSTRUCT
                 GetObject hMemBmp2&, SIZEOF(bm2),bm2
                    hDC& = BeginPaint(CBHNDL,ps)
                        BitBlt hDC&,10,32,bm2.bmWidth,bm2.bmHeight,hMemDC2&,0,0,%srccopy
                    EndPaint CBHNDL, ps
                 FUNCTION=%TRUE
            CASE %WM_DESTROY
                 DeleteDC hMemDC2&
                 DeleteObject hMemBmp2
                 PostQuitMessage 0
                    EXIT FUNCTION
            END SELECT
            END FUNCTION
            
            CALLBACK FUNCTION SrcProc&() AS LONG
            LOCAL hBrush&
                SELECT CASE CBMSG   '----------- start message handler ----------
            CASE %WM_PAINT
                LOCAL ps AS PAINTSTRUCT
                hDC& = BeginPaint(CBHNDL,ps)
                CreateSolidBrush RGB(255,255,0)  TO hBrush&
                SelectObject hDC&, hBrush&
                DeleteObject hBrush&
                    ELLIPSE hDC&,10,10,100,200
                CreateHatchBrush %HS_DIAGCROSS, RGB(255,255,0)  TO hBrush&
                SelectObject hDC&, hBrush&
                DeleteObject hBrush&
                    ELLIPSE hDC&,110,10,300,150
                EndPaint CBHNDL,ps
            FUNCTION=%TRUE
                    CASE %WM_DESTROY
                         PostQuitMessage 0
                    EXIT FUNCTION
                END SELECT          '-----------  end message handler  ----------
            END FUNCTION ' (DlgProc&)
            
            '_________________________________________________________________________________________
            CALLBACK FUNCTION  CaptureProc&()
            LOCAL hdc&
            STATIC rc AS rect
            SELECT CASE CBMSG
            CASE %WM_COMMAND
                SELECT CASE CBCTL
                CASE 100
                SelectObject hMemDC&, hMemBmp&
                DeleteObject hMemBmp&
                GetWindowRect hDlg&, rc
                BitBlt hMemDC&,1,1,rc.nright-rc.nleft,rc.nbottom-rc.ntop,GetDC(%HWND_DESKTOP),rc.nleft,rc.ntop ,%SRCCOPY
                RedrawWindow CBHNDL, BYVAL %NULL, BYVAL %NULL, %RDW_ERASE OR %RDW_INVALIDATE
            
                MSGBOX "Also copying the dialog screen to file with root name:  " + $BmpFile
                CreateTrueColorBmpFile $BmpFile, GetDesktopWindow, rc
            
                CASE 200
                DIALOG NEW 0, "Load Image Viewer",100,100, 190, 190, %ws_thickframe OR %ws_sysmenu, TO hLoadDlg&
                DIALOG SHOW MODELESS hLoadDlg&, CALL Load_proc()
            
            
                END SELECT
            CASE %WM_PAINT
                LOCAL ps AS PAINTSTRUCT
                hDC& = BeginPaint(CBHNDL,ps)
                BitBlt hdc&,10,80,rc.nright-rc.nleft,rc.nbottom-rc.ntop,hMemDC&,1,1 ,%SRCCOPY
                EndPaint CBHNDL,ps
            FUNCTION=%TRUE
            CASE %WM_DESTROY
                 DeleteDC hMemDC&
                 PostQuitMessage 0
            FUNCTION = %TRUE
            END SELECT
            END FUNCTION   '(CaptureProc&)
            
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            FUNCTION PBMAIN
                LOCAL  hBrush&, Msg AS tagMsg
                LOCAL hdc&
            
                hDC& = GetDC(%HWND_DESKTOP)
                hMemDC&= CreateCompatibleDC(hdc&)
                hMemBmp&= CreateCompatibleBitmap(hdc&,550,450)
            
                DIALOG NEW %HWND_DESKTOP, "ReSize Me!!",50,50,210,130, _
                                          %WS_overlappedwindow,TO hDlg&
                DIALOG SHOW MODELESS hDlg&, CALL SrcProc&()
            
                DIALOG NEW 0, "Capture Bmp of Dialog",300,50, 250, 250, %ws_thickframe OR %ws_sysmenu , TO hSPad&
                CONTROL ADD BUTTON, hSPad&, 100, "Capture", 10, 5, 40, 14, _
                          %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP,
            
                            CONTROL ADD BUTTON, hSPad&, 200, "Show File", 55, 5, 50, 14, _
                          %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP,
            
                DIALOG SHOW MODELESS hSPad&, CALL CaptureProc&()
            
              WHILE GetMessage(Msg, %NULL, 0, 0)    '----------- start message loop ----------
                TranslateMessage Msg
                DispatchMessage Msg
              WEND                  '-----------  end message loop  ----------
            END FUNCTION ' (PBMAIN)
            Best regards
            Jules
            www.rpmarchildon.com

            Comment


            • #7
              PrintWindow

              Anyone used PrintWindow before?
              Apparently it is part of WinXP, but I'd never heard of it before.
              Unfortunately, it doesn't seem to work!
              The following code should work according to Microsoft documentation:

              Code:
                   dim ztext as asciiz*256
                   dim lppd as printdlgapi
                   dim docu as docinfo
              
                   lppd.lstructsize=len(printdlgapi)
                   lppd.flags=%pd_returndc or %pd_printsetup
              
                   if printdlg(lppd)=0 then
                     function=0
                     exit function
                   end if
              
                   hprinter&=lppd.hdc
              
                   ztext="Screenshot"
                   docu.cbsize=sizeof(docu)
                   docu.lpszdocname=varptr(ztext)
                   docu.lpszoutput=%null
                   startdoc hprinter&,docu
                   startpage hprinter&
              
                   'style&=%prf_children or %prf_client or %prf_owned '_
                   '       'or %prf_erasebkgnd
                   '
                   'sendmessage hwnd&,%wm_print,hprinter&,style&
              
                   printwindow hwnd&,hprinter&,%null  ''%pw_clientonly
              
                   endpage hprinter&
                   enddoc hprinter&
                   deletedc hprinter&
              Jim Seekamp

              Comment


              • #8
                Not tested, but sounds like you need to create a bitmap and select it into the DC...

                Code:
                '------------------------------------------------------------------------------
                '
                '------------------------------------------------------------------------------
                FUNCTION printWindowAPI(BYVAL hWnd AS DWORD) AS LONG
                
                    DIM ztext AS ASCIIZ*256
                    DIM lppd  AS printdlgapi
                    DIM docu  AS docinfo
                    DIM PrinterName AS ASCIIZ * 256
                    DIM hPrinterDC AS DWORD
                
                    LOCAL rc AS RECT
                    LOCAL hDC AS DWORD
                    LOCAL hDIB AS DWORD, hOldDIB AS DWORD
                    DIM bmi AS BITMAPINFO
                    
                    lppd.lstructsize = LEN(printdlgapi)
                    lppd.flags = %pd_returndc OR %pd_printsetup
                
                    IF printdlg(lppd)=0 THEN
                        FUNCTION=0
                        EXIT FUNCTION
                    END IF
                
                    hDC = GetWindowDC(hWnd)
                    
                    GetWindowRect hWnd, rc
                   
                    hPrinterDC = lppd.hdc
                
                    bmi.bmiHeader.biSize        = SIZEOF( bmi.bmiHeader )
                    bmi.bmiHeader.biWidth       = ( rc.nRight - rc.nLeft )
                    bmi.bmiHeader.biHeight      = ( rc.nBottom - rc.nTop )
                    bmi.bmiHeader.biPlanes      = 1
                    bmi.bmiHeader.biBitCount    = 24
                    bmi.bmiHeader.biCompression = %BI_RGB
                
                    hDIB = CreateDIBSection( hDC, bmi, %DIB_RGB_COLORS, 0, 0, 0 )
                    hOldDIB = SelectObject( hPrinterDC, hDIB )
                    
                    ztext            = "Screenshot"
                    docu.cbsize      = SIZEOF(docu)
                    docu.lpszdocname = VARPTR(ztext)
                    docu.lpszoutput  = %null
                
                    startdoc hPrinterDC,docu
                    startpage hPrinterDC
                
                        lrt& = printwindow(hWnd, hPrinterDC, %NULL)  ''%pw_clientonly
                    
                    endpage  hPrinterDC
                    enddoc   hPrinterDC
                   
                    SelectObject hPrinterDC, hOldDIB
                    ReleaseDC hWnd, hDC
                    DeleteDC hPrinterDC
                    
                END FUNCTION
                Last edited by Jules Marchildon; 11 Feb 2008, 10:15 PM.
                Best regards
                Jules
                www.rpmarchildon.com

                Comment


                • #9
                  Thanks Jules,
                  But that code doesn't work either!!
                  Last edited by Jim Seekamp; 12 Feb 2008, 09:27 AM.
                  Jim Seekamp

                  Comment


                  • #10
                    Ended up with....

                    For anyone who cares; these are the two functions I ended up with: one to create a screenshot and the other to print out the bitmap file.

                    Code:
                    function getwindowscreenshot(byval hwnd&,byval namefile$) as long
                    
                         dim rc as rect
                         dim bm as bitmap
                         dim bmi as bitmapinfo
                         dim bmfhd as bitmapfileheader
                         dim bminfhd as bitmapinfoheader
                    
                         getclientrect hwnd&,rc
                    
                         hdc&=getdc(hwnd&)
                         hmemdc&=createcompatibledc(hdc&)
                    
                         bmi.bmiheader.bisize=sizeof(bmi.bmiheader)
                         bmi.bmiheader.biwidth=(rc.nright-rc.nleft)
                         bmi.bmiheader.biheight=(rc.nbottom-rc.ntop)
                         bmi.bmiheader.biplanes=1
                         bmi.bmiheader.bibitcount=24
                         bmi.bmiheader.bicompression=%bi_rgb
                    
                         hmembmp&=createdibsection(hmemdc&,bmi,%dib_rgb_colors,0,0,0)
                         globallock hmembmp&
                         selectobject hmemdc&,hmembmp&
                         getobject hmembmp&,sizeof(bm),bm
                         bitblt hmemdc&,0,0,bm.bmwidth,bm.bmheight,hdc&,rc.nleft,rc.ntop,%srccopy
                    
                         bmfhd.bftype=cvi("BM")
                         bmfhd.bfsize=len(bmfhd)+len(bminfhd) _
                                     +(bm.bmwidthbytes*bm.bmheight)
                    
                         bmfhd.bfoffbits=54
                         bminfhd.bisize=40
                         bminfhd.biwidth=bm.bmwidth
                         bminfhd.biheight=bm.bmheight
                         bminfhd.biplanes=1
                         bminfhd.bibitcount=24
                         bminfhd.bisizeimage=bm.bmwidthbytes*bm.bmheight
                    
                         ff&=freefile
                         open namefile$ for output as #ff&
                         print #ff&,bmfhd;
                         print #ff&,bminfhd;
                         print #ff&,peek$(bm.bmbits,bm.bmwidthbytes*bm.bmheight);
                         close #ff&
                    
                         releasedc hwnd&,hdc&
                         deletedc hmemdc&
                         globalunlock hmembmp&
                         deleteobject hmembmp&
                    
                         function=1
                    end function
                    
                    function printbmp(byval hwnd&,byval bmpfilename$) as long
                    
                         title$="Print Job"
                    
                         xprint attach choose,title$
                    
                         orient&=2  ''landscape
                         xprint set orientation orient&
                    
                         xprint get size to prwidth&,prheight&
                    
                         ff&=freefile
                         open bmpfilename$ for binary as #ff& base=0
                         seek #ff&,18
                         get$ #ff&,8,b$
                         close #ff&
                    
                         bmwidth&=cvl(left$(b$,4))
                         bmheight&=cvl(right$(b$,4))
                         graphic bitmap load bmpfilename$,nwidth&,nheight& to hbmp&
                    
                         x&=prwidth&-10
                         y&=bmheight&*(x&/bmwidth&)
                    
                         xprint stretch hbmp&,0, _
                                        (0,0)-(bmwidth&,bmheight&) to (5,5)-(x&,y&), _
                                        %mix_copysrc
                    
                         xprint close
                         graphic bitmap end
                    
                         function=1
                    end function
                    Jim Seekamp

                    Comment


                    • #11
                      I think printWindow() is just a snapshot of the window, it doesn't render. So I believe you still need to render it on the Printer DC. Not sure if a DIB is necessary, or could use a standard bitmap.

                      Could you test this? I'm without a printer... Thx.

                      Code:
                      '------------------------------------------------------------------------------
                      '
                      '------------------------------------------------------------------------------
                      FUNCTION printWindowAPI(BYVAL hWnd AS DWORD) AS LONG
                      
                          DIM ztext AS ASCIIZ*256
                          DIM lppd  AS printdlgapi
                          DIM docu  AS docinfo
                          DIM PrinterName AS ASCIIZ * 256
                          DIM hPrinterDC AS DWORD
                      
                          LOCAL rc AS RECT, nWidth AS LONG, nHeight AS LONG
                          LOCAL hDC AS DWORD
                          LOCAL hDIB AS DWORD, hOldDIB AS DWORD
                          DIM bmi AS BITMAPINFO
                      
                          lppd.lstructsize = LEN(printdlgapi)
                          lppd.flags = %pd_returndc OR %pd_printsetup
                      
                          IF printdlg(lppd)=0 THEN
                              FUNCTION=0
                              EXIT FUNCTION
                          END IF
                      
                          hDC = GetWindowDC(hWnd)
                      
                          GetWindowRect hWnd, rc
                          nWidth  =  ( rc.nRight  - rc.nLeft )
                          nHeight =  ( rc.nBottom - rc.nTop  )
                          
                          bmi.bmiHeader.biSize        = SIZEOF( bmi.bmiHeader )
                          bmi.bmiHeader.biWidth       = nWidth
                          bmi.bmiHeader.biHeight      = nHeight
                          bmi.bmiHeader.biPlanes      = 1
                          bmi.bmiHeader.biBitCount    = 24
                          bmi.bmiHeader.biCompression = %BI_RGB
                      
                          hDIB = CreateDIBSection( hDC, bmi, %DIB_RGB_COLORS, 0, 0, 0 )
                          hOldDIB = SelectObject( hDC, hDIB )
                      
                          lrt& = printwindow(hWnd, hDC, %NULL)  ''%pw_clientonly
                          
                          hPrinterDC = lppd.hdc
                          
                          ztext            = "Screenshot"
                          docu.cbsize      = SIZEOF(docu)
                          docu.lpszdocname = VARPTR(ztext)
                          docu.lpszoutput  = %null
                      
                          startdoc hPrinterDC,docu
                          startpage hPrinterDC
                      
                              bitblt hPrinterDC,0,0,nWidth,nHeight,hDC,0,0,%srccopy
                              
                          endpage  hPrinterDC
                          enddoc   hPrinterDC
                      
                          SelectObject hPrinterDC, hOldDIB
                          ReleaseDC hWnd, hDC
                          DeleteDC hPrinterDC
                      
                      END FUNCTION
                      Best regards
                      Jules
                      www.rpmarchildon.com

                      Comment


                      • #12
                        Jules, your code works but the printout is small (only takes up about 1/8 of the page)
                        Jim Seekamp

                        Comment


                        • #13
                          WindowToPrinter, which I wrote a while back

                          Jim, I wrote this a couple years ago, and put it in the PB forum
                          that included tutorials, info for DOS BASIC to PB, etc.

                          When PB changed their forums it seems they no longer included
                          that forum, so searching for it did not reveal anything.

                          http://industrologic.com/basic/
                          go to PowerBasic Demo Programs and Routines
                          "WindowToPrinter.bas"
                          Gary Peek, Industrologic, Inc.

                          Comment

                          Working...
                          X