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 ***