May 04, 2024, 07:34:16 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Printer Offfline/Gdi only

Started by jumbuck, December 31, 2008, 09:54:45 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jumbuck

(a) In Emergence Basic how do you find if a printer is just offline?.
(b) In Emergence Basic is there some way to ascertain if a
     printer is GDI only?. (needing different print command).
     This refers to an end user of a program not yourself.
The code below does not report an error if printer offline.

SUB PrintSomeDetails 
DEF prtname as STRING
DEF hPrinter as UINT
DEF pagefrom,pageto,copies,collate as INT
pagefrom = 1
pageto = 1
copies = 1
prtname = PRTDIALOG(NULL,pagefrom,pageto,copies,collate)
hPrinter = OPENPRINTER(prtname,"Job 1","TEXT")
IF hPrinter = 0
MESSAGEBOX(d3,"Printer is Offline","ERROR",@MB_ICONSTOP|@MB_OK)
ENDIF
RETURN
ENDSUB

Jumbuck

Ficko


jumbuck

In the Windows.inc for EB I find the following reference;-
CONST PRINTER_STATUS_OFFLINE = 0x80
How could this be used to ascertain if a printer is offline
before sending data.
Jumbuck

LarryMc

This should give you something to work with.

I hacked up some code from the old forums.

There is a more direct way to do this but I couldn't get it to work.

AUTODEFINE "OFF"
' Code adapted from Paul's EnumPortA example
TYPE lPRINTER_INFO_2
  DEF pServerName:         POINTER
  DEF pPrinterName:        POINTER
  DEF pShareName:          POINTER
  DEF pPortName:           POINTER
  DEF pDriverName:         POINTER
  DEF pComment:            POINTER
  DEF pLocation:           POINTER
  DEF pDevMode:            POINTER
  DEF pSepFile:            POINTER
  DEF pPrintProcessor:     POINTER
  DEF pDatatype:           POINTER
  DEF pParameters:         POINTER
  DEF pSecurityDescriptor: POINTER
  DEF Attributes:          INT
  DEF Priority:            INT
  DEF DefaultPriority:     INT
  DEF StartTime:           INT
  DEF UntilTime:           INT
  DEF Status:              INT
  DEF cJobs:               INT
  DEF AveragePPM:          INT
ENDTYPE
DECLARE "winspool.drv",EnumPrintersA(flags:INT,name:STRING,Level:INT,nPrinterEnum:MEMORY,cdBuf:INT,pNeed:POINTER,pcReturned:POINTER),INT
DEF result, Need, xEnum, I:INT
DEF ptrBUF: MEMORY
DEF udtPRT: lPRINTER_INFO_2

OPENCONSOLE
string prtname = GETDEFAULTPRINTER
' If Need = 0, then the API returns the number of bytes needed
Need = 0
result = EnumPrintersA(2,"",2,ptrBUF,Need,Need,xEnum)
' Now allocate a memory buffer for the table to be returned
ALLOCMEM ptrBUF, 1, Need
result = EnumPrintersA(2,"",2,ptrBUF,Need,Need,xEnum)
' xEnum contains the number of udt's
FOR I = 1 TO xEnum
'  copy from table to local udt
  READMEM ptrBUF, I, udtPRT

if prtname = udtPRT.#<string>pPrinterName
  CLS
  PRINT "ServerName         : ", udtPRT.#<string>pServerName
  PRINT "PrinterName        : ", udtPRT.#<string>pPrinterName
  PRINT "ShareName          : ", udtPRT.#<string>pShareName
  PRINT "PortName           : ", udtPRT.#<string>pPortName
  PRINT "DriverName         : ", udtPRT.#<string>pDriverName
  PRINT "Comment            : ", udtPRT.#<string>pComment
  PRINT "Location           : ", udtPRT.#<string>pLocation
  PRINT "DevMode            : ", udtPRT.#<string>pDevMode
  PRINT "SepFile            : ", udtPRT.#<string>pSepFile
  PRINT "PrintProcessor     : ", udtPRT.#<string>pPrintProcessor
  PRINT "Datatype           : ", udtPRT.#<string>pDatatype
  PRINT "Parameters         : ", udtPRT.#<string>pParameters
  PRINT "SecurityDescriptor : ", udtPRT.#<string>pSecurityDescriptor
  string stat="Status             : "
if udtPRT.Status & &H1 then stat+="PRINTER_STATUS_PAUSED "
if udtPRT.Status & &H2 then stat+="_STATUS_ERROR "
if udtPRT.Status & &H4 then stat+="_STATUS_PENDING_DELETION "
if udtPRT.Status & &H8 then stat+="_STATUS_PAPER_JAM "
if udtPRT.Status & &H10 then stat+="_STATUS_PAPER_OUT "
if udtPRT.Status & &H20 then stat+="_STATUS_MANUAL_FEED "
if udtPRT.Status & &H40 then stat+="_STATUS_PAPER_PROBLEM "
if udtPRT.Status &  &H80 then stat+="_STATUS_OFFLINE "
if udtPRT.Status &  &H100 then stat+="_STATUS_IO_ACTIVE "
if udtPRT.Status &  &H200 then stat+="_STATUS_BUSY "
if udtPRT.Status &  &H400 then stat+="_STATUS_PRINTING "
if udtPRT.Status &  &H800 then stat+="_STATUS_OUTPUT_BIN_FULL "
if udtPRT.Status &  &H1000 then stat+="_STATUS_NOT_AVAILABLE "
if udtPRT.Status &  &H2000 then stat+="_STATUS_WAITING "
if udtPRT.Status &  &H4000 then stat+="_STATUS_PROCESSING "
if udtPRT.Status &  &H8000 then stat+="_STATUS_INITIALIZING "
if udtPRT.Status &  &H10000 then stat+="_STATUS_WARMING_UP "
if udtPRT.Status &  &H20000 then stat+="_STATUS_TONER_LOW "
if udtPRT.Status &  &H40000 then stat+="_STATUS_NO_TONER "
if udtPRT.Status &  &H80000 then stat+="_STATUS_PAGE_PUNT "
if udtPRT.Status &  &H100000 then stat+="_STATUS_USER_INTERVENTION "
if udtPRT.Status &  &H200000 then stat+="_STATUS_OUT_OF_MEMORY "
if udtPRT.Status &  &H400000 then stat+="_STATUS_DOOR_OPEN "
if udtPRT.Status &  &H800000 then stat+="_STATUS_SERVER_UNKNOWN "
if udtPRT.Status &  &H1000000 then stat+="_STATUS_POWER_SAVE "

print stat
endif
NEXT I
FREEMEM ptrBUF
PRINT
PRINT "Any key to END program"
DO:UNTIL INKEY$<>""
CLOSECONSOLE
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

jumbuck

Ficko,
Looked at article you suggested. All VB code which I
would not be able to convert to EB.
Larry,
Ran your code. Returned my printer name, port, etc but
shows nothing for status. Tried offline, online, disconnected
still nothing. Tried inserting OPENPRINTER then WRITEPRINTER
but got same result.
Jumbuck

Brian

Hi,

Been playing with this also this morning. Don't get any status messages back
whether the printer is off, warming up or on. I get the feeling that this
call is only working with parallel ports

Brian

LarryMc

January 05, 2009, 04:25:08 AM #6 Last Edit: January 05, 2009, 04:28:09 AM by Larry McCaughn
That's odd.

It works with my HP 3-in-1 printer connected to a USB port.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Brian

Hi, Larry,

Sorry, I do get some messages back, but they are probably coming
from the driver. What I don't get is actual physical printer status

Brian

LarryMc

I maxed my brain out on what I got to print out. :P

I have no idea of what to do next. ???

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Brian

Larry,

The only real difference I can see is that mine is a WinPrint RAW driver, and yours is a named driver

I see that Epson has an updated driver - perhaps I'll have a look at that...

Brian

jumbuck

Thanks to all who responded to this post, Larry in particular.
After reading posted replies I went to Epson site and
downloaded a driver for my Epson C90 dated 20/07/2008.
Made no difference still nothing for status.
Example code reports Winprint, RAW, Usb port.
Unless there is a universal method for all printers it is
of limited use for end users. Probably best to just have
a message telling end users to ensure printer is connected,
on line, with sufficient paper etc.
I am told that most of the cheap printers being sold are in
fact GDI only and I understand EB requires a different method
to print to this type printer normally.
Yes I know it has been suggested create a hiidden window then
print, use RichEdit, purchase DDOC etc. all worthy of consideration
but as always there are other methods. Using a printing routine
consisting of all API calls is one. I posted example of these API's on
this forum just requiring somebody with sufficient know how to convert
to EB code.
Jumbuck

Ionic Wind Support Team

Jumbuck,
Printing in Windows isn't an easy task for the beginner.  The resources given give a beginner easy access to printing, such as the ddoc control.

Here is a reply I gave another user, that was asking about the limitations of PRINTWINDOW:

Quote
An autodrawn window only has a bitmap as large as your screen size that it can draw into.  If you specify @NOAUTODRAW you can draw to any virtual size in response to @IDPAINT, which is how Windows programs normally work.  The autodrawn windows are a convenience provided by Emergence, Aurora and CBasic so programmers don't need to deal with the intricacies of GDI programming. They do have their limits though, one of which is you can't draw anything larger than your system screen size when using the default window style.

PRINTWINDOW is also a convenience function and it makes a lot of assumptions.  For example it scales based on the horizontal DPI width of the selected printer and page size, as this is what you would want to do when you are trying to print wysiwyg from a window.  It won't be appropriate for all printing tasks though, as many have discovered.

To accomplish more advanced printing you'll need to study up a bit on device contexts, and how Windows handles the translation between logical units and device units.  It is complicated, especially if you've never done any GDI programming.  Microsoft had a good idea with device contexts, a piss poor execution, but a good idea nonetheless.  The paradigm is that a device context should isolate the programmer from the hardware so that the same code could output to a screen, plotter, printer, laser prototyping machine...whatever and reuse the same code. And it works as long as your drawing code is designed to use real world logical units. Such as feet, inches, millimeters, twips, etc.

This is known as the "mapping mode". Again something to study up on.  The default Emergence, Aurora, and CBasic windows use MM_TEXT which means 1 unit = 1 pixel in the window so when you draw a line from 0 to 99 you have a line that is 100 pixels long.  It is convenient to use this mapping mode for programs that primarily display their information on a screen, and it makes sense to newbie programmers. Unfortunately it is not convenient to use MM_TEXT mode when trying to output to a printer.  Think about "dots per inch" for a moment.  A CRT or LCD screen commonly uses 96 DPI, meaning there are 96 pixels per inch of screen space.  Printers on the other hand commonly use 600, 1200 or 2400 DPI.  If you were to try and use the same output code that draws to the screen in MM_TEXT mode on a printer you would end up with a little tiny image in the upper left corner of the paper.

Which is why I included PRINTWINDOW in the first place, just as a convenience to do the scaling and copy the internal window bitmap to a printer device context.

Printing, in reality, is application specific, and there is no way I can write a "one size fits all" function to handle everyones needs.  I really should do a tutorial on mapping modes though, and how you can use them to produce the same output on different devices.  For example you could use MM_LOENGLISH where each "unit" is .01 inch, so if you were to draw a line from 0 to 99 it would be 1 inch on the screen or the printer.  The piss poor execution by Microsoft comes into play here though, when using a mapping mode other than MM_TEXT the Y axis is reversed so that positive Y values go up the window instead of down.  Also the origin ends up in the middle of your window so you have to change it if you want an origin (0,0) to be in the upper left corner of the windows client area.

In any event this describes the various mapping modes:

http://msdn.microsoft.com/en-us/library/ms533160(VS.85).aspx

Paul.

It might be a little over your head, but the bottom line is Windows doesn't have a "Lineprint" API function, or a way to write text to all printers directly.  Printers that have their own font, the non-GDI printers, are getting hard to come by these days as most of the manufacturers like to mass produce cheap plastic crap, with the print heads built into the ink cartridges, and no real hardware.  It is cheaper for them to do all of the processing through custom software.  Even laser printers are getting cheap where they don't have downloadable fonts anymore.  I have three printers at home, two are GDI only, and one is a network color laser printer that does happen to have its own memory, CPU and built in fonts.

So your only choice, if you don't want to use a ready made solution or a hidden RE control, is to learn how Windows handles obtaining a printer device context, and how to draw text into that device context.  I've written literally hundreds of applications that have needed printing support, and have vast experience working with GDI, it is just hard sometimes to consolidate that information into something that is easy for the beginner to grasp, even harder still to simplify what you need to do into say a few commands.  Each application will be different.

Paul.

Ionic Wind Support Team