The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: digelo on February 12, 2011, 10:43:30 AM

Title: How to Print Form/Client Area with StretchDIBits
Post by: digelo on February 12, 2011, 10:43:30 AM
hi
I need print one of my child windows in my application, i tested some api functions like bitblt and StretchBlt ,in bitblt printed area is very small cuz of different resolutions, i tested StretchBlt but seems like StretchBlt not working with printers cuz when i put my printer DC as destination its return an error about DC, in this way i faced StretchDIBits, but i cant completely understand how can i use it for printing my child windows.
Title: Re: How to Print Form/Client Area with StretchDIBits
Post by: Tedd on February 12, 2011, 02:45:35 PM
First thing to check..

StretchBlt - http://msdn.microsoft.com/en-us/library/dd145120%28VS.85%29.aspx
QuoteNot all devices support the StretchBlt function. For more information, see the GetDeviceCaps.


GetDeviceCaps - http://msdn.microsoft.com/en-us/library/dd144877%28v=VS.85%29.aspx

invoke GetDeviceCaps, hPrnDC,RASTERCAPS
and eax,RC_STRETCHBLT
.IF (eax)
    ;it's supported
.ELSE
    ;it's not supported
.ENDIF



If it's not supported, you might try StretchDIBits (which you can also test in the same manner.)
Title: Re: How to Print Form/Client Area with StretchDIBits
Post by: donkey on February 12, 2011, 09:00:45 PM
I have always found formatting printouts as a bit of a poser. The way I've usually done it is to calculate the DPI ratio of the screen and the target printer (say 96:300 or about 1:3) and then stretch the image in a compatible DC then print the resulting bitmap. I don't really have any postable example code as my only usage is so intertwined in applications that it is too much trouble to remove but these are the steps.

1. capture the window as a bitmap
2. check the dpi of the bitmap
3. display the print dialog
4. check the dpi of the printer in whatever mode the user chooses
5. calculate the ratio
6. create a compatible bitmap (based on the ratio) and DC (with the screen)
7. select the bitmap into the DC
8. StretchBlt the image into the DC using the ratio above
9. select the bitmap out of the DC
10. Print the bitmap (I didn't bother with all the steps here)

Since printing is going to be slow no matter what you do, the extra steps will not have an impact on performace, especially if you do them in an extra thread.

Edgar
Title: Re: How to Print Form/Client Area with StretchDIBits
Post by: digelo on February 14, 2011, 03:44:09 PM
I guess i need more help  :red
Title: Re: How to Print Form/Client Area with StretchDIBits
Post by: dedndave on February 14, 2011, 05:44:40 PM
if you use the forum search tool, you will probably find example code
a good search term might be "CreateCompatibleDC"
Title: Re: How to Print Form/Client Area with StretchDIBits
Post by: digelo on February 15, 2011, 10:32:29 AM
Its what i've done at least its work fine in pdffactory.

PrintStuff  proc
LOCAL _di:DOCINFO
LOCAL p2:PRINTDLG
LOCAL p_dim:POINT
LOCAL p_dim2:POINT
LOCAL psd:PAGESETUPDLG

LOCAL memdc :DWORD
LOCAL hbmp :DWORD
LOCAL bmp :BITMAP


invoke memfill, addr _di,sizeof DOCINFO,0
mov _di.cbSize,sizeof DOCINFO

mov _di.lpszDocName,eax
mov _di.lpszOutput,0
mov _di.lpszDatatype,0
mov _di.fwType,0

invoke memfill, addr p2,sizeof PRINTDLG-4,0
mov p2.lStructSize,sizeof PRINTDLG
mov p2.Flags,PD_RETURNDC or PD_USEDEVMODECOPIESANDCOLLATE
      mov p2.nToPage,1000
      mov p2.nMinPage,1
      mov p2.nMaxPage,1000
     
      invoke PrintDlg,addr p2
      .if eax!=0
      .if p2.hDC==0
      invoke MessageBox,0,CADD("Printer DC is wrong"),0,0
      .endif
     
      invoke GetDeviceCaps,p2.hDC,HORZRES
      mov p_dim.x,eax
      invoke GetDeviceCaps,p2.hDC,VERTRES
      mov p_dim.y,eax
     
     
     
      invoke StartDoc,p2.hDC,addr _di
      .if eax==SP_ERROR
      invoke MessageBox,0,CADD("Cannot start, document"),0,0
      .endif
     
      invoke StartPage,p2.hDC
      .if eax<=0
      invoke MessageBox,0,CADD("Cannot start printer"),0,0
      .endif
     
            ;;;;;;;;;;;;;

   invoke CreateCompatibleDC,p2.hDC
   mov memdc,eax
   invoke CreateCompatibleBitmap,p2.hDC,p_dim.x,p_dim.y
   mov hbmp,eax
   invoke SelectObject,memdc,hbmp

   push eax


   invoke GetObject,hbmp,SIZEOF bmp,ADDR bmp

   invoke StretchBlt,memdc,0,0,bmp.bmWidth,bmp.bmHeight,hDrawDC,0,0,1000,1000,SRCCOPY
   invoke BitBlt,p2.hDC,0,0,bmp.bmWidth,bmp.bmHeight,memdc,0,0,SRCCOPY


    pop eax
    invoke SelectObject,memdc,eax
    invoke DeleteDC,memdc
    invoke DeleteObject,hbmp

;;;

    invoke EndPage,p2.hDC
    invoke EndDoc,p2.hDC
    invoke DeleteDC,p2.hDC
     
      .endif

    ret
PrintStuff endp


here i make hDrawDC:


.if uMsg == WM_CREATE
mov hdc,rv(GetDC,rv(GetDesktopWindow))
mov hDrawDC,rv(CreateCompatibleDC,hdc)
invoke DeleteObject,rv(SelectObject,hDrawDC,rv(CreateCompatibleBitmap,hdc,553,3600))
invoke ReleaseDC,rv(GetDesktopWindow),hdc

invoke Child1PntFnc             ; Child Windows Paint Function