Printing using Win32 API

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
vdecampo
Posts: 2982
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Printing using Win32 API

Postby vdecampo » Sep 12, 2007 4:20

I've put together a quick and dirty sample of printing using the Win32 API. Basically we get a DC to the default printer and then draw some text to it. We could also draw to the DC with GDI commands so there is really no limit to what you can output.

Code: Select all

' Win32 API Printing
' by Vincent DeCampo 09/12/2007
'
#Include "windows.bi"
#Include "win/wingdi.bi"

Function Parse(inText As ZString Ptr) As String
Dim pSep As Integer
Dim Temp As String

   pSep = InStr(1,inText[0],",")
   If pSep > 0 Then
      Temp = Left(inText[0],pSep-1)
      inText[0] = Mid(inText[0],pSep+1)
      Return Temp      
   EndIf
      
End Function

Sub GetPrinterSettings(lpPrintInfo As zString Ptr, Size As Integer, _
     lpPrintDevice As zString Ptr, lpPrintDriver As zString Ptr, PrintPort As zString Ptr)
   
   GetProfileString("windows", "device", "", lpPrintInfo, size)
   Print lpPrintInfo[0]
      
   lpPrintDevice[0] = Parse(lpPrintInfo)
   lpPrintDriver[0] = Parse(lpPrintInfo)
   PrintPort[0] = lpPrintInfo[0]
   
   Print lpPrintDevice[0]
   Print lpPrintDriver[0]
   Print PrintPort[0]

End Sub

'*****************************
'           PROGRAM START
'*****************************
Dim hdcPrn As HDC
Dim DocInfo As DOCINFO
Dim Temp As zString * 255
Dim PDevice As zString * 255
Dim PDriver As zString * 255
Dim PPort As zString * 255
Dim r As RECT
Dim TextToPrint As ZString * 255

   GetPrinterSettings(@Temp, 80, @PDevice, @PDriver, @PPort)
   hdcPrn = CreateDC(PDriver, PDevice, PPort, NULL)
   
   if hdcPrn > 0 then

      DocInfo.cbSize = sizeof(DocInfo)
      DocInfo.lpszDocName = @"Test"
      DocInfo.lpszOutput = NULL
      StartDoc(hdcPrn, @DocInfo)
      StartPage(hdcPrn)
      
      'left and top CANNOT be changed
      r.left = 0
      r.top = 0
      r.right = GetDeviceCaps (hdcPrn,PHYSICALWIDTH)
      r.bottom = GetDeviceCaps (hdcPrn, PHYSICALHEIGHT)
      
      Print r.right
      Print r.bottom
      
      TextToPrint = "Printing using straight Win32 API calls"
      
      'Print a basic text line
      ' But we could draw on this dc with GDI
      ' or Blt complete pictures.
      TextOut (hdcPrn,100,100,@TextToPrint, Len(TextToPrint))
      
      EndPage(hdcPrn)
      EndDoc(hdcPrn)
      DeleteDC(hdcPrn)

   End IF

   Print "Print Job Sent to Printer. Press any key..."   
   Sleep



Cheers!
-Vince
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Sep 12, 2007 4:59

It works under Windows 2000, but I see problem with your CreateDC call. For Windows 9x: “If lpszDevice specifies a particular device, you must use NULL for lpszDriver.” And according to my tests under Windows 2000 and XP, lpszDriver can be set to NULL without affecting the function. And for lpszOutput: “This parameter is ignored and should be set to NULL. It is provided only for compatibility with 16-bit Windows.”
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Postby KristopherWindsor » Sep 12, 2007 5:54

Is this for that QB/N54 thread? ;-)

BTW, Could you please explain, if you are printing with the WinAPI without using GDI, how is it different from using GDI? I'm new to this. :-)
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Sep 12, 2007 13:27

The code is using GDI, for the DC and printer control functions, but you could also use the GDI to directly draw on the printer DC. For an example, replace the TextOut function call with this:

Code: Select all

r.right = 800
r.bottom = 800
for i as integer = 1 to 20
  DrawEdge(hdcPrn, @r, EDGE_SUNKEN, BF_RECT)
  r.left += 20
  r.top += 20
  r.right -= 20
  r.bottom -= 20
next
Antoni
Posts: 1393
Joined: May 27, 2005 15:40
Location: Barcelona, Spain

Postby Antoni » Sep 12, 2007 16:51

I have been playing with it too :)

Code: Select all

#Include "windows.bi"
#Include "win/winspool.bi"
'missing in FB 0.18 winspool.bi, the CVS version is ok
Declare Function Getdefaultprinter Alias "GetDefaultPrinterA"(ByVal As  lptstr,ByVal as LPDWORD)As integer

Dim Shared As HDC hPrinterDC


Sub AbortError(a As String)
Print a
If hprinterdc Then DeleteDC( hPrinterDC )
Sleep
End
End sub

Dim As DOCINFO di
Dim As ZString *60 printername
Dim n As Integer=SizeOf(printername)
If Getdefaultprinter(@printername,@n)=0 Then AbortError "Can't get the default printer"


di.cbSize = sizeof( DOCINFO )
di.lpszDocName = Strptr( "Print  Test" )


hPrinterDC = CreateDC( null, @printerName, null, null )
If hprinterdc=0 Then AbortError "cant't create Print dc"
If StartDoc( hPrinterDC, @di ) = SP_ERROR Then AbortError "cant open doc"
If StartPage( hPrinterDC ) <= 0 Then AbortError "cant open page"

TextOut hprinterdc,0,0,"Hello, World!",13

EndPage hprinterdc
EndDoc hprinterdc
DeleteDC hprinterdc
END
vdecampo
Posts: 2982
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Postby vdecampo » Sep 13, 2007 11:28

[quote="KristopherWindsor"]Is this for that QB/N54 thread? ;-)

What thread? ;-)
Antoni
Posts: 1393
Joined: May 27, 2005 15:40
Location: Barcelona, Spain

Postby Antoni » Sep 13, 2007 11:48

Unexistant :))) thread notwithstanding, a Windoes printing lib would be very useful.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Postby KristopherWindsor » Sep 13, 2007 17:25

-> What thread? ;-)

Don't worry about it; it's just a very fortunate coincidence that something like this was requested just a few days ago. Just make sure your library supports multiple font styles and sizes. :-D

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 10 guests