How to Detect Which Printer(s) Are Offline From Available Printers' List Fetched by Win_PrinterList()

739 views
Skip to first unread message

SD

unread,
Sep 13, 2012, 3:03:58 PM9/13/12
to harbou...@googlegroups.com

Hello Every1:

 

I've just begin to look into PRINTING in Harbour.

Its great that in Harbour we can fetch all the Available Printers (which Windows Printer control panel shows) in this way:

aPrn := WIN_PRINTERLIST()

nPrn := 1

nPrn := AChoice( 3, 1, MaxRow() - 1, MaxCol() - 1, aPrn, .T.,, nPrn )

Now my query is how to detect among these printers from aPrn (the array containing printer names) which ones are OFFLINE, so that they can be removed from the Printers' Selection List....i.e. HOW TO DETECT if any printer is in offline mode or not... (the Windows Printers' control panel do shows offline/online status for each printer - this property is to be fetched I think...)


In real-life situation I’ve observed that the End-users many times just selects “PRINT” from their applications (non-harbour) to a particular network printer without verifying that the network printer is in offline/online mode. It creates mess many times if in such situation the concerned printer is in offline mode…….

 

Regards,

Swapan 

DaNiEl MaXiMiLiAnO

unread,
Sep 13, 2012, 3:43:30 PM9/13/12
to harbou...@googlegroups.com
Hello Swapan:
                         in HMG.3.0.44 the situation is the same. is due to missing include PRINTER_INFO_2 * to know the status of the same
 
Saludos
                DaNIEl MaXiMiLiAnO


De: SD <swapan...@gmail.com>
Para: harbou...@googlegroups.com
Enviado: jueves, 13 de septiembre de 2012 16:03
Asunto: [harbour-users] How to Detect Which Printer(s) Are Offline From Available Printers' List Fetched by Win_PrinterList()

--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users


Bernard Mouille

unread,
Sep 13, 2012, 4:59:18 PM9/13/12
to Harbour Users
Hello Swapan,

I am so interessed to know if the printer is On Line with C function
In Windows.

When I work with dBasePlus, I have a function to know this.

It is not beautifull, work onky in Windows, but it is good for
instance.

I have translate in Harbour :
http://bernard.mouille.free.fr/0_Harbour/ZD00000003/000002.html

I hope that somebody find something in C.

Bernard

SD

unread,
Sep 14, 2012, 5:01:14 AM9/14/12
to harbou...@googlegroups.com, DaNiEl MaXiMiLiAnO
                         in HMG.3.0.44 the situation is the same. is due to missing include PRINTER_INFO_2 * to know the status of the same

Dear Daniel:

Thanks for attending this thread....
Yes, while looking for a solution in the net, I did found some1 saying about "EnumPrinters with PRINTER_INFO_2 and check for PRINTER_STATUS_OFFLINE..."

After your reply I did checked at the Microsoft's site, for the same. The following links carries interesting details regarding this. And not only status OFFLINE, many more interesting/important status properties like PRINTER_STATUS_PAPER_OUT, PRINTER_STATUS_PAPER_JAM etc. can be derived.

PRINTER_INFO_2 structure:

Status:
The printer status. This member can be any reasonable combination of the following values.
PRINTER_STATUS_OFFLINE - The printer is offline.

EnumPrinters function

If, such properties could be fetched (if not yet) from OS (Windows at-least) in Harbour then it would be very handy for some1 stuck with similar issues.....

Regards,
Swapan

SD

unread,
Sep 14, 2012, 6:13:57 AM9/14/12
to harbou...@googlegroups.com
It is not beautifull, work onky in Windows, but it is good for
instance.
I have translate in Harbour :
http://bernard.mouille.free.fr/0_Harbour/ZD00000003/000002.html


Dear Bernard,

Warm Greetings!

Thank you so much for attending this thread.....

And....and you know what – your code WORKED for me! 

Yes, I’m on Windows platform. This is exactly what I was looking for. You made my day 2day! I’ve incorporated your solution, and would address to this issue of detecting printer OFFLINE status with your code, till I find any direct substitute command/function from Harbour itself. An excellent job! Keep it up...

My sincere thanks for your this help.

“remerciements les plus sincères.....”

Regards,

Swapan

/* ------------------------------------------------------------------------------------------------------------*/

OFF-TOPIC: about Barnard's webiste:http://bernard.mouille.free.fr/

/* ------------------------------------------------------------------------------------------------------------*/

Dear Barnard:

 I take this opportunity to say a few words about your website/blog also:

a) You’ve adopted a unique design & style to showcase a technical website. It is simple, minimalist in approach yet very neat & clean site with rich content.

b) Never thought font Courier New could be so good for a website, esp. while displaying examples (source codes).

c) The site carries excellent examples from real-life issues/cases (w.r.t Harbour). The examples are complete with necessary compilation help and comments. And  neat & clean representation – makes simpler while adapting.

d) I’m again telling you, I have seen lot of sites, and somehow your website this “simple looks” has won me. Minimalist design approach & Content is King is for technical sites like yours! Please keep the good work.......

Regards,

Swapan

Bernard Mouille

unread,
Sep 14, 2012, 6:39:44 AM9/14/12
to Harbour Users
Hello Swapan,

Thank's for your compliment.
I have not time to day but I think that you can try
WIN_PRINTERSTATUS()

File source HB 3.0.0. win_prn2.c

/*
* $Id: win_prn2.c 16817 2011-05-25 13:14:17Z druzus $
*/

/*
* Harbour Project source code:
* Harbour Windows Printing support functions
*
* Copyright 2009 Viktor Szakats (harbour.01 syenar.hu)
* Copyright 2002 Luiz Rafael Culik <cul...@uol.com.br>
* www - http://harbour-project.org
*
* This program is free software; you can redistribute it and/or
modify
* it under the terms of the GNU General Public License as published
by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public
License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public
License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid
misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your
choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/

#include "hbwin.h"
#include "hbwapi.h"
#include "hbapifs.h"
#include "hbapiitm.h"

#if ! defined( HB_OS_WIN_CE )
#include <winspool.h>
#endif

#define _ENUMPRN_FLAGS_ ( PRINTER_ENUM_LOCAL |
PRINTER_ENUM_CONNECTIONS )

#if ! defined( HB_OS_WIN_CE )
static HB_BOOL hb_IsLegacyDevice( const char * pszPrinterName )
{
static const char * s_pszPrnDev[] = { "lpt1", "lpt2", "lpt3",
"lpt4", "lpt5", "lpt6", "com1", "com2", "com3", "com4", NULL };
int i;

for( i = 0; s_pszPrnDev[ i ]; ++i )
{
if( hb_strnicmp( pszPrinterName, s_pszPrnDev[ i ],
strlen( s_pszPrnDev[ i ] ) ) == 0 )
return HB_TRUE;
}

return HB_FALSE;
}
#endif

HB_FUNC( WIN_PRINTEREXISTS )
{
HB_BOOL bResult = HB_FALSE;

#if ! defined( HB_OS_WIN_CE )
if( HB_ISCHAR( 1 ) )
{
const char * pszPrinterName = hb_parc( 1 );

/* Don't bother with test if '\' in string */
if( ! strchr( pszPrinterName, HB_OS_PATH_LIST_SEP_CHR ) && !
hb_IsLegacyDevice( pszPrinterName ) )
{
DWORD dwNeeded = 0, dwReturned = 0;

EnumPrinters( _ENUMPRN_FLAGS_, NULL, 5, ( LPBYTE ) NULL, 0,
&dwNeeded, &dwReturned );
if( dwNeeded )
{
PRINTER_INFO_5 * pPrinterEnumBak;
PRINTER_INFO_5 * pPrinterEnum = pPrinterEnumBak =
( PRINTER_INFO_5 * ) hb_xgrab( dwNeeded );

if( EnumPrinters( _ENUMPRN_FLAGS_, NULL, 5, ( LPBYTE )
pPrinterEnum, dwNeeded, &dwNeeded, &dwReturned ) )
{
PHB_ITEM pTemp = hb_itemNew( NULL );
DWORD i;

for( i = 0; ! bResult && i < dwReturned; ++i, +
+pPrinterEnum )
{
HB_ITEMPUTSTR( pTemp, pPrinterEnum->pPrinterName );
bResult = ( strcmp( pszPrinterName,
hb_itemGetCPtr( pTemp ) ) == 0 );
}

hb_itemRelease( pTemp );
}

hb_xfree( pPrinterEnumBak );
}
}
}
#endif

hb_retl( bResult );
}

static void hb_GetDefaultPrinter( PHB_ITEM pPrinterName )
{
#if ! defined( HB_OS_WIN_CE )
HB_BOOL bResult = HB_FALSE;

hb_itemPutC( pPrinterName, NULL );

if( hb_iswin2k() ) /* Windows 2000 or later */
{
typedef BOOL( WINAPI * DEFPRINTER ) ( LPTSTR, LPDWORD );
DEFPRINTER fnGetDefaultPrinter;
HMODULE hWinSpool =
hbwapi_LoadLibrarySystem( TEXT( "winspool.drv" ) );

if( hWinSpool )
{
fnGetDefaultPrinter = ( DEFPRINTER )
GetProcAddress( hWinSpool,
#if defined( UNICODE )
"GetDefaultPrinterW" );
#else
"GetDefaultPrinterA" );
#endif

if( fnGetDefaultPrinter )
{
TCHAR lpPrinterName[ 256 ];
DWORD dwSize = HB_SIZEOFARRAY( lpPrinterName ) - 1;

bResult = ( *fnGetDefaultPrinter )( lpPrinterName,
&dwSize );

HB_ITEMPUTSTR( pPrinterName, lpPrinterName );
}

FreeLibrary( hWinSpool );
}
}

if( ! bResult ) /* Win9x and Windows NT 4.0 or earlier & 2000+ if
necessary for some reason i.e. dll could not load! */
{
TCHAR lpPrinterName[ 256 ];

DWORD dwSize = GetProfileString( TEXT( "windows" ),
TEXT( "device" ), TEXT( "" ), lpPrinterName, ( DWORD )
HB_SIZEOFARRAY( lpPrinterName ) - 1 );

if( dwSize && dwSize < HB_SIZEOFARRAY( lpPrinterName ) )
{
dwSize = 0;
while( lpPrinterName[ dwSize ] != '\0' &&
lpPrinterName[ dwSize ] != ',' )
dwSize++;
lpPrinterName[ dwSize ] = '\0';

bResult = HB_TRUE;

HB_ITEMPUTSTRLEN( pPrinterName, lpPrinterName, dwSize );
}
}

if( ! bResult && hb_iswin9x() )
{
/* This option should never be required but is included because
of this article
http://support.microsoft.com/kb/246772/en-us

This option will not enumerate any network printers.

From the SDK technical reference for EnumPrinters();
If Level is 2 or 5, Name is a pointer to a null-terminated
string that specifies
the name of a server whose printers are to be enumerated.
If this string is NULL, then the function enumerates the
printers installed on the local machine.
*/
DWORD dwNeeded = 0, dwReturned = 0;

if( EnumPrinters( PRINTER_ENUM_DEFAULT, NULL, 2, NULL, 0,
&dwNeeded, &dwReturned ) )
{
if( dwNeeded )
{
PRINTER_INFO_2 * pPrinterInfo = ( PRINTER_INFO_2 * )
hb_xgrab( dwNeeded );

if( EnumPrinters( PRINTER_ENUM_DEFAULT, NULL, 2,
( LPBYTE ) pPrinterInfo, dwNeeded, &dwNeeded, &dwReturned ) &&
dwReturned )
HB_ITEMPUTSTR( pPrinterName, pPrinterInfo-
>pPrinterName );

hb_xfree( pPrinterInfo );
}
}
}
#else
hb_itemPutC( pPrinterName, NULL );
#endif
}

HB_FUNC( WIN_PRINTERGETDEFAULT )
{
PHB_ITEM pPrinterName = hb_itemNew( NULL );

hb_GetDefaultPrinter( pPrinterName );

hb_itemReturnRelease( pPrinterName );
}

#if ! defined( HB_OS_WIN_CE )
static HB_BOOL hb_GetJobs( HANDLE hPrinter, JOB_INFO_2 ** ppJobInfo,
long * plJobs )
{
HB_BOOL bResult = HB_FALSE;
DWORD dwByteNeeded = 0;

GetPrinter( hPrinter, 2, NULL, 0, &dwByteNeeded );
if( dwByteNeeded )
{
PRINTER_INFO_2 * pPrinterInfo = ( PRINTER_INFO_2 * )
hb_xgrab( dwByteNeeded );
DWORD dwByteUsed = 0;

if( GetPrinter( hPrinter, 2, ( LPBYTE ) pPrinterInfo,
dwByteNeeded, &dwByteUsed ) )
{
DWORD dwReturned = 0;

EnumJobs( hPrinter, 0, pPrinterInfo->cJobs, 2, NULL, 0,
&dwByteNeeded, &dwReturned );

if( dwByteNeeded )
{
JOB_INFO_2 * pJobStorage = ( JOB_INFO_2 * )
hb_xgrab( dwByteNeeded );

if( EnumJobs( hPrinter, 0, dwReturned, 2, ( LPBYTE )
pJobStorage, dwByteNeeded, &dwByteUsed, &dwReturned ) )
{
*plJobs = ( long ) dwReturned;
*ppJobInfo = pJobStorage;
bResult = HB_TRUE;
}
else
hb_xfree( pJobStorage );
}
}
hb_xfree( pPrinterInfo );
}

return bResult;
}
#endif

HB_FUNC( WIN_PRINTERSTATUS )
{
long nStatus = -1;

#if ! defined( HB_OS_WIN_CE )
PHB_ITEM pPrinterName = hb_itemParam( 1 );

if( hb_itemGetCLen( pPrinterName ) == 0 )
hb_GetDefaultPrinter( pPrinterName );

if( hb_itemGetCLen( pPrinterName ) > 0 )
{
void * hPrinterName;
LPCTSTR lpPrinterName = HB_ITEMGETSTR( pPrinterName,
&hPrinterName, NULL );
HANDLE hPrinter;

if( OpenPrinter( ( LPTSTR ) lpPrinterName, &hPrinter, NULL ) )
{
DWORD dwByteNeeded = 0;

GetPrinter( hPrinter, 2, NULL, 0, &dwByteNeeded );

if( dwByteNeeded )
{
PRINTER_INFO_2 * pPrinterInfo = ( PRINTER_INFO_2 * )
hb_xgrab( dwByteNeeded );

if( GetPrinter( hPrinter, 2, ( LPBYTE ) pPrinterInfo,
dwByteNeeded, &dwByteNeeded ) )
nStatus = ( long ) pPrinterInfo->Status;

hb_xfree( pPrinterInfo );
}

if( nStatus == 0 )
{
JOB_INFO_2 * pJobs;
long lJobs = 0;

if( hb_GetJobs( hPrinter, &pJobs, &lJobs ) )
{
long i;

for( i = 0; nStatus == 0 && i < lJobs; ++i )
{
if( pJobs[ i ].Status & JOB_STATUS_ERROR )
nStatus = -20;
else if( pJobs[ i ].Status & JOB_STATUS_OFFLINE )
nStatus = -21;
else if( pJobs[ i ].Status & JOB_STATUS_PAPEROUT )
nStatus = -22;
else if( pJobs[ i ].Status &
JOB_STATUS_BLOCKED_DEVQ )
nStatus = -23;
}
hb_xfree( pJobs );
}
}

CloseHandle( hPrinter );
}

hb_strfree( hPrinterName );
}

hb_itemRelease( pPrinterName );
#endif

hb_retnl( nStatus );
}

HB_FUNC( WIN_PRINTERPORTTONAME )
{
/* Set default return value */
hb_retc_null();

#if ! defined( HB_OS_WIN_CE )
if( hb_parclen( 1 ) > 0 )
{
DWORD dwNeeded = 0, dwReturned = 0;

EnumPrinters( _ENUMPRN_FLAGS_, NULL, 5, ( LPBYTE ) NULL, 0,
&dwNeeded, &dwReturned );
if( dwNeeded )
{
PRINTER_INFO_5 * pPrinterEnumBak;
PRINTER_INFO_5 * pPrinterEnum = pPrinterEnumBak =
( PRINTER_INFO_5 * ) hb_xgrab( dwNeeded );

if( EnumPrinters( _ENUMPRN_FLAGS_, NULL, 5, ( LPBYTE )
pPrinterEnum, dwNeeded, &dwNeeded, &dwReturned ) )
{
const char * pszPortNameFind = hb_parc( 1 );
HB_BOOL bSubStr = hb_parl( 2 );
HB_BOOL bFound = HB_FALSE;
PHB_ITEM pTemp = hb_itemNew( NULL );
DWORD i;

for( i = 0; i < dwReturned && ! bFound; ++i, +
+pPrinterEnum )
{
HB_ITEMPUTSTR( pTemp, pPrinterEnum->pPortName );

if( bSubStr )
bFound = ( hb_strnicmp( hb_itemGetCPtr( pTemp ),
pszPortNameFind, strlen( pszPortNameFind ) ) == 0 );
else
bFound = ( hb_stricmp( hb_itemGetCPtr( pTemp ),
pszPortNameFind ) == 0 );

if( bFound )
HB_RETSTR( pPrinterEnum->pPrinterName );
}

hb_itemRelease( pTemp );
}

hb_xfree( pPrinterEnumBak );
}
}
#endif
}

#define HB_PRINT_BUFFER_SIZE ( 32 * 1024 )

HB_FUNC( WIN_PRINTFILERAW )
{
int iResult = -1;

#if ! defined( HB_OS_WIN_CE )
if( HB_ISCHAR( 1 ) && HB_ISCHAR( 2 ) )
{
const char * pszFileName = hb_parc( 2 );

HANDLE hPrinter;
void * hDeviceName;
LPCTSTR lpDeviceName = HB_PARSTR( 1, &hDeviceName, NULL );

if( OpenPrinter( ( LPTSTR ) lpDeviceName, &hPrinter, NULL ) !=
0 )
{
void * hDocName;

DOC_INFO_1 DocInfo;
DocInfo.pDocName = ( LPTSTR ) HB_PARSTR( HB_ISCHAR( 3 ) ? 3 :
2, &hDocName, NULL );
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = ( LPTSTR ) TEXT( "RAW" );
if( StartDocPrinter( hPrinter, 1, ( LPBYTE ) &DocInfo ) !=
0 )
{
if( StartPagePrinter( hPrinter ) != 0 )
{
HB_FHANDLE fhnd = hb_fsOpen( pszFileName, FO_READ |
FO_SHARED );

if( fhnd != FS_ERROR )
{
HB_BYTE * pbyBuffer = ( HB_BYTE * )
hb_xgrab( HB_PRINT_BUFFER_SIZE );
HB_SIZE nRead;

iResult = 1;

while( ( nRead = hb_fsReadLarge( fhnd, pbyBuffer,
HB_PRINT_BUFFER_SIZE ) ) > 0 )
{
DWORD nWritten = 0;

#if 0
/* TOFIX: This check seems wrong for any input
files
larger than our read buffer, in such
case it
will strip Chr( 26 ) from inside the
file, which
means it will corrupt it. [vszakats] */
if( pbyBuffer[ nRead - 1 ] == 26 )
nRead--; /* Skip the EOF() character */
#endif

while( nWritten < nRead )
{
DWORD dwWritten = 0;
if( !WritePrinter( hPrinter,
&pbyBuffer[ nWritten ],
( DWORD ) ( nRead -
nWritten ),
&dwWritten ) )
{
iResult = -7;
break;
}
else if( dwWritten == 0 )
{
iResult = -8;
break;
}
nWritten += dwWritten;
}
if( nWritten < nRead )
break;
}

hb_fsClose( fhnd );
hb_xfree( pbyBuffer );
}
else
iResult = -6;
EndPagePrinter( hPrinter );
}
else
iResult = -4;
EndDocPrinter( hPrinter );
}
else
iResult = -3;

ClosePrinter( hPrinter );

hb_strfree( hDocName );
}
else
iResult = -2;

hb_strfree( hDeviceName );
}
#endif

hb_retni( iResult );
}

/* Positions for WIN_PRINTERLIST() array */

#define HB_WINPRN_NAME 1
#define HB_WINPRN_PORT 2
#define HB_WINPRN_TYPE 3
#define HB_WINPRN_DRIVER 4
#define HB_WINPRN_SHARE 5
#define HB_WINPRN_SERVER 6
#define HB_WINPRN_LEN_ 6

HB_FUNC( WIN_PRINTERLIST )
{
PHB_ITEM pPrinterArray = hb_itemArrayNew( 0 );
#if ! defined( HB_OS_WIN_CE )
HB_BOOL bPrinterNamesOnly = ! hb_parl( 1 );
HB_BOOL bLocalPrintersOnly = hb_parl( 2 );
DWORD dwNeeded = 0, dwReturned = 0, i;

EnumPrinters( _ENUMPRN_FLAGS_, NULL, 5, ( LPBYTE ) NULL, 0,
&dwNeeded, &dwReturned );
if( dwNeeded )
{
PRINTER_INFO_5 * pPrinterEnumBak;
PRINTER_INFO_5 * pPrinterEnum = pPrinterEnumBak =
( PRINTER_INFO_5 * ) hb_xgrab( dwNeeded );

if( EnumPrinters( _ENUMPRN_FLAGS_, NULL, 5, ( LPBYTE )
pPrinterEnum, dwNeeded, &dwNeeded, &dwReturned ) )
{
PHB_ITEM pTempItem = hb_itemNew( NULL );

for( i = 0; i < dwReturned; ++i, ++pPrinterEnum )
{
if( ! bLocalPrintersOnly || pPrinterEnum->Attributes &
PRINTER_ATTRIBUTE_LOCAL )
{
if( bPrinterNamesOnly )
hb_arrayAddForward( pPrinterArray,
HB_ITEMPUTSTR( pTempItem, pPrinterEnum->pPrinterName ) );
else
{
HANDLE hPrinter;

if( OpenPrinter( pPrinterEnum->pPrinterName,
&hPrinter, NULL ) )
{
GetPrinter( hPrinter, 2, NULL, 0, &dwNeeded );
if( dwNeeded )
{
hb_arrayNew( pTempItem, HB_WINPRN_LEN_ );

HB_ARRAYSETSTR( pTempItem, HB_WINPRN_NAME,
pPrinterEnum->pPrinterName );

{
PRINTER_INFO_2 * pPrinterInfo2 =
( PRINTER_INFO_2 * ) hb_xgrab( dwNeeded );

if( GetPrinter( hPrinter, 2, ( LPBYTE )
pPrinterInfo2, dwNeeded, &dwNeeded ) )
{
HB_ARRAYSETSTR( pTempItem,
HB_WINPRN_PORT, pPrinterInfo2->pPortName );
HB_ARRAYSETSTR( pTempItem,
HB_WINPRN_DRIVER, pPrinterInfo2->pDriverName );
HB_ARRAYSETSTR( pTempItem,
HB_WINPRN_SHARE, pPrinterInfo2->pShareName );
HB_ARRAYSETSTR( pTempItem,
HB_WINPRN_SERVER, pPrinterInfo2->pServerName );
}
else
{
hb_arraySetC( pTempItem, HB_WINPRN_PORT,
NULL );
hb_arraySetC( pTempItem,
HB_WINPRN_DRIVER, NULL );
hb_arraySetC( pTempItem,
HB_WINPRN_SHARE, NULL );
hb_arraySetC( pTempItem,
HB_WINPRN_SERVER, NULL );
}

hb_xfree( pPrinterInfo2 );
}

if( pPrinterEnum->Attributes &
PRINTER_ATTRIBUTE_LOCAL )
hb_arraySetC( pTempItem, HB_WINPRN_TYPE,
"LOCAL" );
else if( pPrinterEnum->Attributes &
PRINTER_ATTRIBUTE_NETWORK )
hb_arraySetC( pTempItem, HB_WINPRN_TYPE,
"NETWORK" );
else
hb_arraySetC( pTempItem, HB_WINPRN_TYPE,
NULL );

hb_arrayAddForward( pPrinterArray,
pTempItem );
}
}
CloseHandle( hPrinter );
}
}
}

hb_itemRelease( pTempItem );
}
hb_xfree( pPrinterEnumBak );
}
#endif

hb_itemReturnRelease( pPrinterArray );

Bernard Mouille

unread,
Sep 14, 2012, 12:02:23 PM9/14/12
to Harbour Users
Hello all,

I am testing WIN_PRINTERSTATUS( cPrintername ) with a printer off
line.
With or without a job in this printer, WIN_PRINTERSTATUS() return
always 0 ( zero ).
If I put a bad cPrintername, it return -1 -> that is OK.
It do not return -21

Is somebody has an idea ?

My configuration : Harbour 3.0.0 - Windows 7 pro 32

Bernard

SD

unread,
Sep 14, 2012, 2:33:00 PM9/14/12
to harbou...@googlegroups.com
On Friday, September 14, 2012 4:09:45 PM UTC+5:30, Bernard Mouille wrote:
I have not time to day but I think that you can try
WIN_PRINTERSTATUS()

File source HB 3.0.0. win_prn2.c

/*
 * $Id: win_prn2.c 16817 2011-05-25 13:14:17Z druzus $
 */


Thanks Bernard for the pointer. I've installed only the latest installer version of Harbour, which I think doesn't contains the sources. And it needs better expertise to understand those sources. But this time, on your advice I went through this wonderful source code (thanks for posting here..). I'm amazed to see that it did contains all the necessary things which I've raised while replying to Daniel regarding fetching the Windows printer properties.

Unfortunately, I couldn't make out the result though, with WIN_PRINTERSTATUS() .....

nOffLineStat:=WIN_PRINTERSTATUS( cPrinter ) && where cPrinter is the printer selected by the user or the default printer as the case may be...
The return value is always 0 (zero), for the printer irrespective of its offline/ready status.
 
The source code says:
else if( pJobs[ i ].Status & JOB_STATUS_OFFLINE ) 
                     nStatus = -21; 

but not getting -21 or any other value other then 0.

Any mistake in using this function?

Regards,
Swapan 


The snippet for Harbour Source Code: File source HB 3.0.0. win_prn2.c , which shows WIN_PRINTERSTATUS has been included, to handle such issues....

SD

unread,
Sep 15, 2012, 12:45:00 AM9/15/12
to harbou...@googlegroups.com
It is not beautifull, work onky in Windows, but it is good for
instance.
I have translate in Harbour :
http://bernard.mouille.free.fr/0_Harbour/ZD00000003/000002.html

Dear Bernard,

And....and you know what – your code WORKED for me! 

Yes, I’m on Windows platform. This is exactly what I was looking for. You made my day 2day! I’ve incorporated your solution, and would address to this issue of detecting printer OFFLINE status with your code, till I find any direct substitute command/function from Harbour itself. An excellent job! Keep it up...


PLEASE NOTE: 

Strangely, the Dot Matrix Printers (and may be with certain Barcode Printers) which are connected to Pcs, always shows "READY" status even they are in POWER/SWTICHED OFF mode in the Windows Printers' Control Panel (Devices and Printers / Printers and Faxes Panel). 

I've seen this "strange" behaviour with 2-3 DMPs and with one Barcode printer (Godex EZ-1100 Plus)...........

And its obvious that in these cases Bernard's code fails (as Windows is "failing" in doing so.....)

Dear Bernard, if possible do check this thing with the DMP available at your end (under Win XP/7), to confirm the same.

Regards,
Swapan

Bernard Mouille

unread,
Sep 15, 2012, 5:10:47 AM9/15/12
to Harbour Users
Hello Swapan,

I have put a test source on :
http://bernard.mouille.free.fr/0_Harbour/ZD00000003/000003.html

The infos arent working only if a job is in the printer :
- DetectedErrorState
- ExtendedDetectedErrorState
- ExtendedPrinterStatus
- PrinterState
- Status

Maybe you can make a function with this elements ?

Good week end

Bernard

Bernard Mouille

unread,
Sep 15, 2012, 7:37:26 AM9/15/12
to Harbour Users
I have test
- Status

With W7 pro 64 bits, its'work
With W7 pro 32 bits, it do not work

I have a HP printer connect by ethernet.

Bernard

Bernard Mouille

unread,
Sep 15, 2012, 8:16:46 AM9/15/12
to Harbour Users


I am now working with WIN_PRINTERSTATUS(), it work like -Status.

Bernard Mouille

unread,
Sep 15, 2012, 8:40:02 AM9/15/12
to Harbour Users
Finaly, WIN_PRINTERSTATUS() work with :
XP pro 32
W7 pro 64

For W7 32, a bug in Windows with EnumJobs() function.

Dowload home Microsoft :
http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=981559&kbln=us

Image and sound not work today home Micorsoft !!!

Bernard Mouille

unread,
Sep 15, 2012, 10:50:13 AM9/15/12
to Harbour Users
Hello Swapan,

After a lot of coffes and cigars, I have made à code to test
WIN_PRINTERSTATUS() :
http://bernard.mouille.free.fr/0_Harbour/ZD00000005/000003.html

This function is long for the change of state (about 4 minutes to
detect the fault).

There must be a job for the current printer status.
Works with XP pro 32 bit.

WINDOWS 7 pro 32 bit, it does not work: you need to install a patch
EnumJobs for the C ():
http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=981559&kbln=us

Windows 7 Pro 64-bit, it takes much longer to detect the fault:
Perhaps you should have to install the patch.

15 September 2012, the Microsoft site does not work (image and
security).

Bernard

SD

unread,
Sep 15, 2012, 1:08:28 PM9/15/12
to harbou...@googlegroups.com
Dear Bernard:

Its great that you were able to get WIN_PRINTERSTATUS() to work! And can understand lot of time & energy went into it...thanks.

For next 2days I'll be away from work, so will not be able to test. Still before posting this post I did tried with your latest code for Win_Printerstatus() under Win Vista
Ultimate - there's no physical printer connected but do have CutePDF Creator as printer. Its always showing 0 and your program doesn't ends even after 5-6 minutes. I tried both way - OFFLINE and READY mode.

But your earlier function the adapted code from C "FUNCTION bm_IsPrinterWorkOnLine( cPrintername )" is capable of detecting the OFFLINE/READY status in Vista also and there's NO DELAY.....So would love to keep that function only for the time being.

PLEASE NOTE:
What I mentioned that in case of DMP printers only, there's seems to be an issue as even Windows shows these printers as READY in-spite of the concerned DMP printer is physically in SWITCHED OFF mode. And so  FUNCTION bm_IsPrinterWorkOnLine( cPrintername ) also fails in such situations, but its ACCEPTABLE as even the concerned OS (Windows) not showing it as OFFLINE..
 
So, for me your FUNCTION bm_IsPrinterWorkOnLine( cPrintername ) is rocking!

Regards,
Swapan

 
Reply all
Reply to author
Forward
0 new messages