By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,692 Members | 1,210 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,692 IT Pros & Developers. It's quick & easy.

How to detect printer is color printer

P: n/a
I checked my color printers's Printersettings.SupportsColor, which all
showed false. What is wrong that I could not use this property.

Also, what other way to detect if a printer is color printer.

TIA

Nov 21 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
we saw a similar problem and were told that it was up to the printer to
expose this information. so, why it fails remains a mystery to me...

as for other ways, you can use the API function GetDeviceCaps to get at
this -- there are NUMCOLORS and BITSPIXEL items that provide color
information
(http://msdn.microsoft.com/library/de...y/en-us/gdi/de
vcons_88s3.asp)

I have a sample in c++, which is listed (in part) below (this source
comes from the Win98 Dev Handbook by Ezzell & Blaney) -- I am *not*
certain that p/invoking GetDeviceCaps will give better results...

//=======================//
// DC.H //
//=======================//

#define BUFSIZE 256

#define IDM_DISPLAY 101
#define IDM_PRINTER 102

#define IDM_BASIC 103
#define IDM_OTHER 104
#define IDM_CURVE 105
#define IDM_LINE 106
#define IDM_POLY 107
#define IDM_TEXT 108

#define IDM_PRINTLIST 109
//===============================//
// DC.C //
// C++ Windows Device Capacity //
//===============================//

#include <windows.h>
#include <winspool.h>
#include <drivinit.h>
#include <string.h>
#include "dc.h"

#define APP_ICON "DC"
#define APP_MENU "DC"
// note: no cursor assignment

HANDLE hInst;
char szAppTitle[] = "Device Capabilites";
char szAppName[] = "DC";

char gszDeviceName[BUFSIZE],
gszDriverName[BUFSIZE],
gszPort[BUFSIZE];
int cxChr, cyChr;

PPRINTER_INFO_1 gpPrinters = NULL;
PSZ * gpszPrinterNames = NULL;
PSZ * gpszDeviceNames = NULL;

typedef struct { int nMask;
char *szMask;
char *szDscp; } BITS;

void ErrorMsg( char * Message )
{
MessageBeep(0);
MessageBox( GetFocus(), Message, "Error", MB_ICONASTERISK | MB_OK );
return;
}

void ListBasic( HDC hdc, HDC hdcInfo )
{
static struct{ int nIdx;
char *szConst;
char *szDscp;
char *szNotes; } info[] =
{ HORZSIZE, "HORZSIZE", "Width", "(mm)",
VERTSIZE, "VERTSIZE", "Height", "(mm)",
HORZRES, "HORZRES", "Width", "(pixels)",
VERTRES, "VERTRES", "Height", "(pixel/raster lines)",
ASPECTX, "ASPECTX", "Pixel aspect", "(horz)",
ASPECTY, "ASPECTY", "Pixel aspect", "(vert)",
ASPECTXY, "ASPECTXY", "Pixel aspect", "(diag)",
LOGPIXELSX, "LOGPIXELSX", "Pixels per inch", "(horz)",
LOGPIXELSY, "LOGPIXELSY", "Pixels per inch", "(vert)",
// color capabilities
BITSPIXEL, "BITSPIXEL", "Color", "(bits/pixel)",
PLANES, "PLANES", "Color planes", "",
NUMBRUSHES, "NUMBRUSHES", "Device brushes", "",
NUMPENS, "NUMPENS", "Device pens", "",
NUMMARKERS, "NUMMARKERS", "Device markers", "",
NUMFONTS, "NUMFONTS", "Device fonts", "",
NUMCOLORS, "NUMCOLORS", "Device colors", "",
// Following three indexes are valid only if device
// driver sets the RC_PALETTE bit in the RASTERCAPS index
SIZEPALETTE, "SIZEPALETTE", "Palette entries", "",
NUMRESERVED, "NUMRESERVED", "Palette entries", "(reserved)",
COLORRES, "COLORRES", "Color resolution", ""
};
char szBuff[80];
int i;

for( i=0; i<sizeof(info)/sizeof(info[0]); i++ )
TextOut( hdc, cxChr, cyChr*(i+1), szBuff,
wsprintf( szBuff, "%17s: %5d %-20s | %s",
info[i].szDscp,
GetDeviceCaps( hdcInfo, info[i].nIdx ),
info[i].szNotes, info[i].szConst ) );
}

void ListOther( HDC hdc, HDC hdcInfo )
{
static BITS clipcaps[] =
{ CP_NONE, "CP_NONE", "No output clipping supported",
CP_RECTANGLE, "CP_RECTANGLE", "Output clipped to rectangle",
CP_REGION, "CP_REGION", "Output clipped to region"
};

static BITS rastercaps[] =
{
RC_BANDING, "RC_BANDING", "Banding support required",
RC_BITBLT, "RC_BITBLT", "Bitmap transfer",
RC_BITMAP64, "RC_BITMAP64", "Supports bitmaps >= 64K",
RC_DI_BITMAP, "RC_DI_BITMAP", "Supports SetDIBits and GetDIBits",
RC_DIBTODEV, "RC_DIBTODEV", "Supports SetDIBitsToDevice",
RC_FLOODFILL, "RC_FLOODFILL", "Floodfill supported",
RC_GDI20_OUTPUT, "RC_GDI20_OUTPUT", "Support Windows 2.0 features",
RC_GDI20_STATE, "RC_GDI20_STATE", "<< feature not documented >>",
RC_PALETTE, "RC_PALETTE", "Supports palette",
RC_SCALING, "RC_SCALING", "Scaling supported",
RC_BIGFONT, "RC_BIGFONT", "Supports fonts >= 64K",
RC_SAVEBITMAP, "RC_SAVEBITMAP", "<< feature not documented >>",
RC_STRETCHBLT, "RC_STRETCHBLT", "Supports StretchBlt",
RC_STRETCHDIB, "RC_STRETCHDIB", "Supports StretchDIBits",
RC_OP_DX_OUTPUT, "RC_OP_DX_OUTPUT", "<< feature not documented >>",
RC_DEVBITS, "RC_DEVBITS", "<< feature not documented >>"
};

static char *szTech[] =
{ "Vector plotter (DT_PLOTTER)",
"Raster display (DT_RASDISPLAY)",
"Raster printer (DT_RASPRINTER)",
"Raster camera (DT_RASCAMERA)",
"Character stream (DT_CHARSTREAM)",
"Metafile (DT_METAFILE)",
"Display file (DT_DISPFILE)"
};

char szBuff[80];
int i, j = GetDeviceCaps( hdcInfo, DRIVERVERSION ),
k = 2;

TextOut( hdc, cxChr, cyChr, szBuff,
wsprintf( szBuff, "Driver Version: %2d.%02d",
HIBYTE(j), LOBYTE(j) ) );
TextOut( hdc, cxChr, cyChr*k, szBuff,
wsprintf( szBuff, " Technology: %s",
szTech[ GetDeviceCaps( hdcInfo, TECHNOLOGY ) ] )
);
k += 2;
TextOut( hdc, cxChr, cyChr*k, szBuff,
wsprintf( szBuff, "Raster capabilities (RASTERCAPS)" ) );
k++;
j = GetDeviceCaps( hdcInfo, RASTERCAPS );
for( i=0; i<sizeof(rastercaps)/sizeof(rastercaps[0]); i++ )
TextOut( hdc, cxChr*4, cyChr*(k++), szBuff,
wsprintf( szBuff, "[%c] %-34s | %s",
j & rastercaps[i].nMask ? 'X' : ' ',
rastercaps[i].szDscp, rastercaps[i].szMask ) );
k++;
TextOut( hdc, cxChr, cyChr*( k++), szBuff,
wsprintf( szBuff, "Clipping capabilities (CLIPCAPS)" ) );
j = GetDeviceCaps( hdcInfo, CLIPCAPS );
for( i=0; i<sizeof(clipcaps)/sizeof(clipcaps[0]); i++ )
TextOut( hdc, cxChr*4, cyChr*(k++), szBuff,
wsprintf( szBuff, "[%c] %-34s | %s",
j & clipcaps[i].nMask?'X':' ',
clipcaps[i].szDscp, clipcaps[i].szMask ) );
}

void ListText( HDC hdc, HDC hdcInfo )
{
static BITS text[] =
{ TC_OP_CHARACTER, "TC_OP_CHARACTER", "character output precision",
TC_OP_STROKE, "TC_OP_STROKE", "stroke output precision",
TC_CP_STROKE, "TC_CP_STROKE", "stroke clip precision",
TC_CR_90, "TC_CR_90", "90-degree char rotation",
TC_CR_ANY, "TC_CR_ANY", "any character rotation",
TC_SF_X_YINDEP, "TC_SF_X_YINDEP", "independent x / y scaling",
TC_SA_DOUBLE, "TC_SA_DOUBLE", "doubled character scaling",
TC_SA_INTEGER, "TC_SA_INTEGER", "integer multiple scaling",
TC_SA_CONTIN, "TC_SA_CONTIN", "any multiples for exact scaling",
TC_EA_DOUBLE, "TC_EA_DOUBLE", "double-weight characters",
TC_IA_ABLE, "TC_IA_ABLE", "italics",
TC_UA_ABLE, "TC_UA_ABLE", "underlining",
TC_SO_ABLE, "TC_SO_ABLE", "strikeouts",
TC_RA_ABLE, "TC_RA_ABLE", "raster fonts",
TC_VA_ABLE, "TC_VA_ABLE", "vector fonts"
};
static char szBuff[80];
int i, j;

TextOut( hdc, cxChr, cyChr, szBuff,
wsprintf( szBuff, "Text capabilities (TEXTCAPS)"));
j = GetDeviceCaps( hdcInfo, TEXTCAPS );
for( i=0; i<sizeof(text)/sizeof(text[0]); i++ )
TextOut( hdc, cxChr, cyChr*(i+3), szBuff,
wsprintf( szBuff, "[%c] Supports %-31s | %s",
j & text[i].nMask ? 'X' : ' ',
text[i].szDscp, text[i].szMask ) );
}

void ListCurve( HDC hdc, HDC hdcInfo )
{
static BITS curves[] =
{ CC_NONE, "CC_NONE", "Curves not supported",
CC_CIRCLES, "CC_CIRCLES", "Supports circles",
CC_PIE, "CC_PIE", "Supports pie wedges",
CC_CHORD, "CC_CHORD", "Supports chord arcs",
CC_ELLIPSES, "CC_ELLIPSES", "Supports ellipses",
CC_WIDE, "CC_WIDE", "Supports wide borders",
CC_STYLED, "CC_STYLED", "Supports styled borders",
CC_WIDESTYLED, "CC_WIDESTYLED", "Supports wide and styled borders",
CC_INTERIORS, "CC_INTERIORS", "Supports interiors",
CC_ROUNDRECT, "CC_ROUNDRECT", "Supports rounded rectangles"
};
static char szBuff[80];
int i, j;

TextOut( hdc, cxChr, cyChr, szBuff,
wsprintf( szBuff, "Curve capabilities (CURVECAPS)" ) );
j = GetDeviceCaps( hdcInfo, CURVECAPS );
for( i=0; i<sizeof(curves)/sizeof(curves[0]); i++ )
TextOut( hdc, cxChr, cyChr*(i+3), szBuff,
wsprintf( szBuff, "[%c] %-32s | %s",
j & curves[i].nMask ? 'X' : ' ',
curves[i].szDscp, curves[i].szMask ) );
}

void ListLines( HDC hdc, HDC hdcInfo )
{
static BITS lines[] =
{ LC_NONE, "LC_NONE", "Lines not supported",
LC_POLYLINE, "LC_POLYLINE", "Supports polylines",
LC_MARKER, "LC_MARKER", "Supports markers",
LC_POLYMARKER, "LC_POLYMARKER", "Supports polymarkers",
LC_WIDE, "LC_WIDE", "Supports wide lines",
LC_STYLED, "LC_STYLED", "Supports styled lines",
LC_WIDESTYLED, "LC_WIDESTYLED", "Supports wide and styled lines",
LC_INTERIORS, "LC_INTERIORS", "Supports interiors:"
};
static char szBuff[80];
int i, j;

TextOut( hdc, cxChr, cyChr, szBuff,
wsprintf( szBuff, "Line Capabilities (LINECAPS)" ) );
j = GetDeviceCaps( hdcInfo, LINECAPS );
for( i=0; i<sizeof(lines)/sizeof(lines[0]); i++ )
TextOut( hdc, cxChr, cyChr*(i+3), szBuff,
wsprintf( szBuff, "[%c] %-31s | %s",
j & lines[i].nMask ? 'X' : ' ',
lines[i].szDscp, lines[i].szMask ) );
}

void ListPoly( HDC hdc, HDC hdcInfo )
{
static BITS poly[] =
{ PC_NONE, "PC_NONE", "Polygonals not supported",
PC_POLYGON, "PC_POLYGON", "Supports alternate fill polygon",
PC_RECTANGLE, "PC_RECTANGLE", "Supports rectangles",
PC_TRAPEZOID, "PC_TRAPEZOID", "Supports winding number fill polygon",
PC_SCANLINE, "PC_SCANLINE", "Supports scan lines",
PC_WIDE, "PC_WIDE", "Supports wide borders",
PC_STYLED, "PC_STYLED", "Supports styled borders",
PC_WIDESTYLED, "PC_WIDESTYLED","Supports wide and styled polygons",
PC_INTERIORS, "PC_INTERIORS", "Supports interiors"
};
static char szBuff[80];
int i, j;

TextOut( hdc, cxChr, cyChr, szBuff,
wsprintf( szBuff, "Polygonal capabilities (POLYGONALCAPS)" ) );
j = GetDeviceCaps( hdcInfo, POLYGONALCAPS );
for( i=0; i<sizeof(poly)/sizeof(poly[0]); i++ )
TextOut( hdc, cxChr, cyChr*(i+3), szBuff,
wsprintf( szBuff, "[%c] %-36s | %s",
j & poly[i].nMask ? 'X' : ' ',
poly[i].szDscp, poly[i].szMask ) );
}

BOOL APIENTRY PrinterProc( HWND hDlg, UINT msg,
UINT wParam, LONG lParam )
{
DWORD cbPrinters = 4096L, cbNeeded, cReturned;
char szPrinter[40] = "\0";
int i, j;

switch( msg )
{
case WM_INITDIALOG:
if( ! ( gpPrinters = (PPRINTER_INFO_1)
LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
cbPrinters ) ) )
{
ErrorMsg( "gpPrinters local alloc failed." );
return( FALSE );
}
if( ! EnumPrinters( PRINTER_ENUM_DEFAULT, NULL, 1,
(LPBYTE) gpPrinters, cbPrinters,
&cbNeeded, &cReturned ) )
{
if( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
{
LocalFree( (LOCALHANDLE) gpPrinters );
gpPrinters = (PPRINTER_INFO_1)
LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, cbNeeded );
cbPrinters = cbNeeded;
if( ! EnumPrinters( PRINTER_ENUM_LOCAL, NULL, 1,
(LPBYTE) gpPrinters, cbPrinters,
&cbNeeded, &cReturned ) )
{
ErrorMsg( "Can't enumerate printers" );
return( FALSE );
} }
else
{
ErrorMsg( "Can't enumerate printers" );
return( FALSE );
} }
if( ! cReturned )
{
ErrorMsg( "No printers installed" );
EndDialog( hDlg, FALSE );
return( FALSE );
}
for( i=0; i<(INT)cReturned; i++ )
SendDlgItemMessage( hDlg, IDM_PRINTLIST, LB_ADDSTRING, 0,
(LPARAM) gpPrinters[i].pDescription );
SendDlgItemMessage( hDlg, IDM_PRINTLIST, LB_SETCURSEL, 0, 0 );
return( TRUE );

case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case IDOK:
// LB_GETCURSEL message retrieves the index of currently
// selected item, if any, in a single-selection list box
i = SendDlgItemMessage( hDlg, IDM_PRINTLIST, LB_GETCURSEL, 0, 0 );
// LB_GETTEXT message retrieves a string from a list box
SendDlgItemMessage( hDlg, IDM_PRINTLIST, LB_GETTEXT,
(WPARAM) i, (LPARAM)(LPCTSTR) szPrinter );
// Parse the string into device, driver and port names
j = 0;
i = -1;
while( szPrinter[++i] != ',' )
gszDeviceName[i] = szPrinter[i];
gszDeviceName[i] = '\0';
while( szPrinter[++i] != ',' )
gszDriverName[j++] = szPrinter[i];
gszDriverName[j] = '\0';
j = 0;
while( szPrinter[++i] != '\0')
gszPort[j++] = szPrinter[i];
gszPort[j] = '\0';
EndDialog( hDlg, TRUE );
return( TRUE );

case IDCANCEL:
EndDialog( hDlg, FALSE );
return( FALSE );
}
break;
}
return 0;
}

long APIENTRY WndProc( HWND hwnd, UINT msg,
UINT wParam, LONG lParam )
{
static int nCurInfo = IDM_BASIC;
HDC hdc, hdcInfo;
char szTitle[BUFSIZE];
HMENU hMenu;
PAINTSTRUCT ps;
TEXTMETRIC tm;

switch( msg )
{
case WM_CREATE:
hdc = GetDC( hwnd );
SelectObject( hdc, GetStockObject( SYSTEM_FIXED_FONT ) );
GetTextMetrics( hdc, &tm );
cxChr = tm.tmAveCharWidth;
cyChr = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC( hwnd, hdc );
strcpy( gszDriverName, "DISPLAY" );
gszDeviceName[0] = gszPort[0] = '\0';
break;

case WM_COMMAND:
hMenu = GetMenu( hwnd );
switch( LOWORD(wParam) )
{
case IDM_DISPLAY:
CheckMenuItem( hMenu, IDM_DISPLAY, MF_CHECKED );
CheckMenuItem( hMenu, IDM_PRINTER, MF_UNCHECKED );
strcpy( gszDriverName, "DISPLAY" );
gszDeviceName[0] = gszPort[0] = '\0';
InvalidateRect( hwnd, NULL, TRUE );
break;

case IDM_PRINTER:
CheckMenuItem( hMenu, IDM_DISPLAY, MF_UNCHECKED );
CheckMenuItem( hMenu, IDM_PRINTER, MF_CHECKED );
if( DialogBox( hInst, "PRINTER", hwnd, PrinterProc ) )
InvalidateRect( hwnd, NULL, TRUE );
break;

case IDM_BASIC: case IDM_OTHER:
case IDM_CURVE: case IDM_LINE:
case IDM_POLY: case IDM_TEXT:
CheckMenuItem( hMenu, nCurInfo, MF_UNCHECKED );
nCurInfo = wParam;
CheckMenuItem( hMenu, nCurInfo, MF_CHECKED );
InvalidateRect( hwnd, NULL, TRUE );
break;

default:
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
}
break;

case WM_DEVMODECHANGE:
InvalidateRect( hwnd, NULL, TRUE );
break;

case WM_PAINT:
hdc = BeginPaint( hwnd, &ps );
SelectObject( hdc, GetStockObject( SYSTEM_FIXED_FONT ) );
hdcInfo = CreateIC( gszDriverName, gszDeviceName, gszPort, NULL );
wsprintf( szTitle, "Device: %s %s %s",
gszDeviceName, gszDriverName, gszPort );
SetWindowText( hwnd, szTitle );
if( hdcInfo )
{
switch( nCurInfo )
{
case IDM_BASIC: ListBasic( hdc, hdcInfo ); break;
case IDM_OTHER: ListOther( hdc, hdcInfo ); break;
case IDM_TEXT: ListText( hdc, hdcInfo ); break;
case IDM_CURVE: ListCurve( hdc, hdcInfo ); break;
case IDM_LINE: ListLines( hdc, hdcInfo ); break;
case IDM_POLY: ListPoly( hdc, hdcInfo ); break;
}
DeleteDC( hdcInfo );
}
EndPaint( hwnd, &ps );
break;

case WM_DESTROY: PostQuitMessage(0); break;

default:
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
}
return 0;
}

#include "template.i"

int APIENTRY WinMain( HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
MSG msg;

if( ! hPrevInstance )
if( ! InitApplication( hInstance ) )
return( FALSE );
if( ! InitInstance( hInstance, nCmdShow ) )
return (FALSE);
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( msg.wParam );
UNREFERENCED_PARAMETER( lpCmdLine );
}

--
http://code.box.sk
nemo me impune lacessit

*** Sent via Developersdex http://www.developersdex.com ***
Nov 21 '05 #2

P: n/a
You question intrigued me so I wrote a little code to display the available
printers in a list box so that when you clicked on one it would return a
message with the name and then a message as to whether it supports color.

It returned the correct information on color for three color printers, a
gray scale printer and several others like FAX & Adobe PDF writer.

Here is the code:

Private Sub btnListPrinters_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnListPrinters.Click

Dim objPrint As New System.Drawing.Printing.PrinterSettings
Dim strItem As String
Dim strPrinters As String
For Each strItem In objPrint.InstalledPrinters
Me.ListBox1.Items.Add(strItem)
Next
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged

MsgBox("Printer Selected: " & Me.ListBox1.SelectedItem)
Dim pd As New System.Drawing.Printing.PrintDocument
pd.PrinterSettings.PrinterName = Me.ListBox1.SelectedItem
MsgBox("Supports Color: " &
pd.PrinterSettings.SupportsColor.ToString)
End Sub

"dever" <we**********@yahoo.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
I checked my color printers's Printersettings.SupportsColor, which all
showed false. What is wrong that I could not use this property.

Also, what other way to detect if a printer is color printer.

TIA

Nov 21 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.