🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
5 messages
5 total messages Started by Keith Tue, 22 Aug 2006 03:31
Does printer Escape PASSTHROUGH actually work?
#3146
Author: Keith
Date: Tue, 22 Aug 2006 03:31
89 lines
3011 bytes
I have the following:

// in the header..........
typedef struct
{
     WORD wSize;
     BYTE bData[2];                  // placeholder
} PASSTHROUGHSTRUCT, FAR *LPPTS;

HANDLE m_dcPrint;
LPPTS m_lpPTS;

// in a button event handler
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TPrinter *Prntr=Printer();

char device[MAX_PATH], driver[MAX_PATH], port[MAX_PATH];
HANDLE HMem;

// get default printer device, driver, and port names
Prntr->GetPrinter(device, driver, port, (unsigned int)HMem);

m_dcPrint=Prntr->Handle;

int x=PASSTHROUGH;
if (Escape(m_dcPrint, QUERYESCSUPPORT, sizeof(x), (LPCSTR) &x, NULL)<=0)

  {
  ShowMessage("Printer does not support passthrough");
  return;
  }

if (HMem)
  {
  PDEVMODE pDevMode=(PDEVMODE)GlobalLock(HMem);
  pDevMode->dmCopies =1;
  GlobalUnlock(HMem);
  }

if (!m_lpPTS)
  {
  m_lpPTS = (LPPTS)GlobalLock(GlobalAlloc(GPTR, sizeof(WORD) +
                                     2048));
  if (m_lpPTS==0)
    {
    ShowMessage("Print Aborted, cannot lock memory");
    return;
    }
  }

DOCINFO mydoc;
mydoc.cbSize=sizeof(mydoc);
mydoc.lpszDocName="MyDoc";
memset(&mydoc,0,sizeof(mydoc));
StartDoc(m_dcPrint,&mydoc);
StartPage(m_dcPrint);

char *PrintThis="Now is the time for all good men to come to the aid of
his country and Liz need not be offended.\r\n"
m_lpPTS->wSize = strlen(PrintThis);

memcpy (m_lpPTS->bData, PrintThis, strlen(PrintThis));

int rv=1;
for (int i=0;rv && i<30;++i)
  {
  rv=Escape(m_dcPrint,PASSTHROUGH,sizeof(m_lpPTS->wSize) +
m_lpPTS->wSize,
         (LPSTR)m_lpPTS,0);
  }

EndPage(m_dcPrint);
EndDoc(m_dcPrint);
GlobalUnlock(m_lpPTS);
}

The above executes from top to bottom, no ShowMessage occurs, while
stepping the code in debug, the port and device are correct strings....
and the loop executes 30 iterations....however, not a single byte is
printed, nor is the spooler ever activated.

Any of you folks have an explanation why there is no printed output?
or, alternatively, any of you ever use the Escape to attempt to send
data, for instance, PCL-5 commands, to a HP laser printer?

TIA

keith
Re: Does printer Escape PASSTHROUGH actually work?
#3147
Author: JD
Date: Tue, 22 Aug 2006 07:55
10 lines
1085 bytes
Keith <kdopson@sbcglobal.net> wrote:
>
> [...] m_dcPrint = Prntr->Handle;

There is a known issue with TPrinter and it's Handle not being
valid. Try setting the TPrinter's Index prior to the call to
GetPrinter.

~ JD
Re: Does printer Escape PASSTHROUGH actually work?
#3148
Author: Keith
Date: Tue, 22 Aug 2006 11:01
28 lines
1596 bytes

JD wrote:

> Keith <kdopson@sbcglobal.net> wrote:
> >
> > [...] m_dcPrint = Prntr->Handle;
>
> There is a known issue with TPrinter and it's Handle not being
> valid. Try setting the TPrinter's Index prior to the call to
> GetPrinter.
>
> ~ JD

It matters not.  The source file for printers.pas shows the default
setting is for index is -1, the default printer, in the constructor:

constructor TPrinter.Create;
begin
  inherited Create;
  FPrinterIndex := -1;
end;

In fact prior to the original post, I had the ineffective line in the
source code, and I deleted that line Prntr->PrinterIndex=-1;
just prior to posting.

keith
Re: Does printer Escape PASSTHROUGH actually work?
#3150
Author: Bob Gonder
Date: Tue, 22 Aug 2006 13:30
67 lines
2789 bytes
Keith wrote:

>typedef struct
>{
>     WORD wSize;
>     BYTE bData[2];                  // placeholder
>} PASSTHROUGHSTRUCT, FAR *LPPTS;
>
>LPPTS m_lpPTS;

Don't rely on "magic".
You rely on m_lpPTS being NULL, so set it.
	LPPTS  m_lpPTS = NULL;

>if (!m_lpPTS)
>  {
>  m_lpPTS = (LPPTS)GlobalLock(GlobalAlloc(GPTR, sizeof(WORD) +
>                                     2048));

Incorrect.
GPTR includes GMEM_FIXED, which is already locked, AND it returns the
Address, not a Handle. Also not sure why you want is Zero Initialized.

	m_lpPTS = (LPPTS)GlobalAlloc(GMEM_FIXED, 2050 );

>char *PrintThis="Now is the time for all good men to come to the aid of
>his country and Liz need not be offended.\r\n"
>m_lpPTS->wSize = strlen(PrintThis);
>
>memcpy (m_lpPTS->bData, PrintThis, strlen(PrintThis));
>
>int rv=1;
>for (int i=0;rv && i<30;++i)
>  {
>  rv=Escape(m_dcPrint,PASSTHROUGH,sizeof(m_lpPTS->wSize) +
>m_lpPTS->wSize,
>         (LPSTR)m_lpPTS,0);
>  }

You don't check for failure of the Escape.
You only check if it is implimented (zero return).
Are you sure the printer wants to see the size field?
I would think this would be more appropriate...

static  char  PrintThis[] = "Now is the time for all good men to come
to the aid of his country and Liz need not be offended.\r\n";

  rv=Escape( m_dcPrint ,PASSTHROUGH, sizeof(PrintThis)-1, PrintThis);
  if( rv <= 0 )
  {
	/* handle error */
	break;
   };

>EndPage(m_dcPrint);
>EndDoc(m_dcPrint);
>GlobalUnlock(m_lpPTS);

You forgot GlobalFree()
Also, since your Lock was incorrect, the Unlock is too...

	EndPage(m_dcPrint);
	EndDoc(m_dcPrint);
	GlobalFree(m_lpPTS);
	m_lpPTS = NULL;

I also didn't see where you actually Opened the Printer, or Closed it.
Re: Does printer Escape PASSTHROUGH actually work?
#3161
Author: Keith
Date: Wed, 30 Aug 2006 13:23
24 lines
1931 bytes
> Any of you folks have an explanation why there is no printed output?
> or, alternatively, any of you ever use the Escape to attempt to send
> data, for instance, PCL-5 commands, to a HP laser printer?
>
> TIA
>
> keith

For the schlep (er, hacker, i.e. programmer) who tries the above, look at
this MSDN URL:
http://support.microsoft.com/kb/138594/EN-US/

Use esc-E with caution in your raw transmissions to the printer if you use
downloaded fonts or printer macros.  Same with form feed cautions... the
spooler may also send form feeds on page breaks (...may).. and your specific
printer may, or may not, eject pages, depending on whether its raster
actually contains printable data.  Also note the value of DocInfo.pDatatype
being set to 'RAW', which doesn't appear to be defined as such in BCB.

Your best bet is 'probably' to use the printer's port as a file
open/write/close.  Unfortunately, you do not get the notifications of
document print status that winspool provides through callback.

keith
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads