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