DeviceCapabilitiesis used to get information from a printer device driver. Unfortunately, the related Delphi prototype has a minor problem.
Background
For instance, there is a major problem printing images.
In addition, the Windows API function DeviceCapabilities must be used to get some of the printer capabilities. In most applications, this information is not required. However, I had a situation where I wanted to simplify the configuration of a barcode printer - this page documents one of the problems I had.
Windows SDK
Import Library - winspool.lib
Header File - wingdi.h
DWORD DeviceCapabilities(
LPCTSTR pDevice, // pointer to a printer-name string
LPCTSTR pPort, // pointer to a port-name string
WORD fwCapability, // device capability to query
LPTSTR pOutput, // pointer to the output
CONST DEVMODE *pDevMode // pointer to structure with device data
);
windows.pas
{$EXTERNALSYM DeviceCapabilities}
function DeviceCapabilities(pDriverName, pDeviceName, pPort: PChar;
iIndex: Integer; pOutput: PChar; DevMode: PDeviceMode): Integer; stdcall;
const
gdi32 = 'gdi32.dll';
implementation
function DeviceCapabilities; external gdi32 name 'DeviceCapabilitiesA';
I noticed the different number of arguments right off (the program would not compile),
but still had trouble with the program crashing with an access violation.
I searched google for
DeviceCapabilities delphiThe second reference was how to call the Windows API function DeviceCapabilities by Joe C. Hecht. This indicated that the correct library was
winspool.drvI verified the library by using depends.exe (the Microsoft Dependency Walker).
winspool.pas
{$EXTERNALSYM DeviceCapabilities}
function DeviceCapabilities(pDevice, pPort: PChar; fwCapability: Word;
pOutput: PChar; DevMode: PDeviceMode): Integer; stdcall;
const
winspl = 'winspool.drv';
implementation
function DeviceCapabilities; external winspl name 'DeviceCapabilitiesA';
Include winspool AFTER windows in your uses clause.
interface uses Windows, WinSpool, Printers, ... ;
Paper Names Example
First, include winspool and Printers to your uses clause.
interface
uses
Windows, WinSpool, Printers, ... ;
implementation
procedure TForm1.GetPapers_UIButtonClick(Sender: TObject);
var
buffer1 : array[0..250] of char;
buffer2 : array[0..250] of char;
buffer3 : array[0..250] of char;
ADevice, ADriver, APort : pchar;
buffer4 : pchar;
PageBuff: array[0..64] of char; // 1 larger than necessary
hBuffer : THandle;
hDm : THandle;
s : string;
i, cnt : integer;
begin
ADevice := buffer1;
ADriver := buffer2;
APort := buffer3;
Printer.GetPrinter(ADevice, ADriver, APort, hDm);
// This determines how large the buffer should be
cnt := DeviceCapabilities(ADevice, APort, DC_PAPERNAMES, nil, nil);
hBuffer := GlobalAlloc(GMEM_MOVEABLE and GMEM_ZEROINIT, 64 * cnt);
buffer4 := GlobalLock (hBuffer);
cnt := DeviceCapabilities(ADevice, APort, DC_PAPERNAMES, buffer4, nil);
RichEdit1.Lines.Clear;
for i:=0 to cnt-1 do begin
move(buffer4[i*64], PageBuff[0], 64); // get next string / paper type
s := PageBuff;
RichEdit1.Lines.Add(s);
end;
GlobalUnlock(hBuffer);
GlobalFree(hBuffer);
end;
Author: Robert Clemenzi -
clemenzi@cpcug.org