|
|
|
date: Thu, 10 Jul 2008 15:07:34 -0700,
group: microsoft.public.win32.programmer.gdi
back
Re: ReadPrint Failure. How to use it properly
On Jul 10, 3:07 pm, "Carlo McKee" <Logi...@newsgroup.nospam> wrote:
> I am trying to retrieve data from a bidirectional printer using the
> ReadPrint API function.
> The printer I am using is connected via USB.
> Issue:
>
> The ReadPrint function is returning false. The error code retrieved by
> GetLastError is 6 (ERR_INVALID_HANDLE).
>
> Before I use ReadPrint I create a printer handle using the OpenPrint API
> function which returns true. Immediately after the OpenPrinter returns I
> check if my handle is not invalid and is not. Below is a snippet of my
> calls.
>
> //The open printer does return true.
> if(!OpenPrinter(( (LPTSTR)(pPrinterName)), &hPrinter, NULL ) )
> {
> DisplayError(GetLastError(),"GetPrinterStatus: OpenPrinter");
> return (FALSE);
>
> }
>
> //I check if I have a Valid Handle and I do
> if (hPrinter == INVALID_HANDLE_VALUE)
> {
> DisplayError(GetLastError(), "GetPrinterStatus: hPrinter invalid");
> return (FALSE);
>
> }
>
> //Now that Open the printer and I have a handle I use ReadPrint
> //This function actually returns false. The GetLastError is 6
> (ERR_INVALID_HANDLE)
> //But why is invalid handle if the OpenPrinter gave me a valid handle
> if (!ReadPrinter(hPrinter, &Status, 16, &bytesRead))
> {
> DisplayError( GetLastError(), "GetPrinterStatus: ReadPrinter) );
> return (FALSE);
>
> }
>
> I am positive I am getting a good handle from the OpenPrinter since I can
> use OpenPrinter to write to the printer using the WritePrinter API. I can
> successfully print using WritePrinter but fail to ReadPrinter.
>
> Please advice what I may doing wrong or is there any other API to get data
> from a printer.
>
> Thank you
Hi,
You can use the following API to retrieve information
about a specified printer:
GetPrinter()
http://msdn.microsoft.com/en-us/library/ms535494(VS.85).aspx
Kellie.
date: Thu, 10 Jul 2008 19:51:19 -0700 (PDT)
author: Kellie Fitton
RE: ReadPrint Failure. How to use it properly
Hi Carlo ,
I have found an internal record discussing on a similar issue.
In the record, our engineer found out through Windows source code that you
can't read from a printer handle, but you can from a printer job handle. So
the trick is to create a Job using StartDocPrinter, then open a handle to
the printer job (which you can obtain by specifying the following syntax
for the printer name in OpenPrinter... "PrinterName,Job xxxx" (where xxxx
is a job id)).
Below is some test code that does this.
#define BUFSIZE 256
BOOL TestReadPrinterWithJob(LPSTR szPrinterName)
{
HANDLE hPrinter = NULL;
HANDLE hPrinterJob = NULL;
DWORD dwBytesRead;
LPVOID lpBytes = NULL;
DOC_INFO_1 dc;
DWORD jobid;
TCHAR jobStr[100];
// Open a handle to the printer.
if (!OpenPrinter(szPrinterName, &hPrinter, NULL))
{
PrintError(GetLastError(), "OpenPrinter");
return FALSE;
}
// We can't read from a printer handle, but we can read from
// a printer job handle, So the trick is to create a Job using
// StartDocPrinter, then open a handle to the printer job...
ZeroMemory(&dc, sizeof(DOC_INFO_1));
dc.pDocName="Dummy job";
jobid = StartDocPrinter(hPrinter,1,(LPSTR)&dc); // start a Doc
if (jobid == 0)
{
ClosePrinter(hPrinter);
PrintError(GetLastError(), "OpenPrinter");
return FALSE;
}
// Open handle to the printer job...
wsprintf(jobStr, "%s,Job %i", szPrinterName, jobid);
if (!OpenPrinter(jobStr, &hPrinterJob, NULL))
{
ClosePrinter(hPrinter);
PrintError(GetLastError(), "OpenPrinter Job");
return FALSE;
}
// Allocate a buffer to read printer data into...
lpBytes = (LPVOID)malloc(BUFSIZE);
if (!lpBytes)
{
PrintError(GetLastError(), "malloc");
ClosePrinter(hPrinter);
ClosePrinter(hPrinterJob);
return FALSE;
}
// Try ReadPrinter...
SetLastError(0);
if (!ReadPrinter(hPrinterJob, lpBytes, BUFSIZE, &dwBytesRead))
{
PrintError(GetLastError(), "ReadPrinter");
ClosePrinter(hPrinter);
ClosePrinter(hPrinterJob);
if (lpBytes)
free(lpBytes);
return FALSE;
}
else
{
printf("%i bytes successfully read by ReadPrinter (%i attempted)\n",
dwBytesRead, BUFSIZE);
}
// Clean up...
ClosePrinter(hPrinterJob);
EndDocPrinter(hPrinter); // end the doc
ClosePrinter(hPrinter);
if (lpBytes)
free(lpBytes);
return TRUE;
}
void PrintError( DWORD dwError, LPCSTR lpString )
{
#define MAX_MSG_BUF_SIZE 512
char *msgBuf;
DWORD cMsgLen;
cMsgLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL, dwError,
MAKELANGID(0, SUBLANG_ENGLISH_US), (LPTSTR) &msgBuf, MAX_MSG_BUF_SIZE,
NULL);
printf( "%s Error [%d]:: %s\n", lpString, dwError, msgBuf );
LocalFree( msgBuf );
#undef MAX_MSG_BUF_SIZE
}
So, the basic components necessary are a bidi-aware language monitor (i.e.
one that implements ReadPort), the bidi checkbox checked for the printer
properties, and a printer job handle returned from OpenPrinter (which
implies that a job needs to exist).
Before you can do bidirectional printing, you'll need to have a bidi-aware
printer driver and a language monitor (both which are discussed in the DDK
(Driver Development Kit) documentation. The language monitor or port
monitor should already be using SetPrinter() and SetJob() to set the
printer and job status, which can then be read from an application with
GetPrinter() and/or GetJob(). <http://support.microsoft.com/?id=160129>
shows how to read the status, provided the monitor is setting it.
Hope this helps.
Best regards,
Jeffrey Tan
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
date: Fri, 11 Jul 2008 03:23:57 GMT
author: (Jeffrey Tan[MSFT])
|
|