Delphi's DocumentProperties() Declaration

From: AlanGLLoyd (alanglloyd_at_aol.com)
Date: 12/22/03


Date: 22 Dec 2003 12:42:04 GMT

DocumentProperties() is declared in MSDN as ...

LONG DocumentProperties(
  HWND hWnd, // handle to parent window
  HANDLE hPrinter, // handle to printer object
  LPTSTR pDeviceName, // device name
  PDEVMODE pDevModeOutput, // modified device mode
  PDEVMODE pDevModeInput, // original device mode
  DWORD fMode // mode options
);

.. but in my Delphi 3 WinSpool.pas it is declared as ...

function DocumentProperties(hWnd: HWND; hPrinter: THandle; pDeviceName: PChar;
  const pDevModeOutput: TDeviceMode; var pDevModeInput: TDeviceMode;
  fMode: DWORD): Longint; stdcall;

.. and I have coded ...

  {initial memory allocation}
  PtrDMIn := AllocMem(DMMemSize);
  DMIn := PtrDMIn^;
  PtrDMOut := AllocMem(DMMemSize);
  DMOut := PtrDMOut^;
  if not OpenPrinter('HP Laserjet 5P/5MP (HP)', hndPrinter, nil) then
    ShowMessage('Opened Printer failed');
    Exit;
  end;
  {get total memory size}
  DMMemSize := DocumentProperties(Self.Handle, hndPrinter, 'HP Laserjet 5P/5MP
(HP)',
                   DMIn, DMOut, 0);
  {reallocate memory to total size}
  PtrDMIn := ReAllocMem(ptrDMIn, DMMemSize);
  DMIn := PtrDMIn^;
  PtrDMOut := ReAllocMem(ptrDMOut, DMMemSize);
  DMOut := PtrDMOut^;
  {get printer devmode}
  DocumentProperties(Self.Handle, hndPrinter, 'HP Laserjet 5P/5MP (HP)',
                     DMIn, DMOut, DM_OUT_BUFFER);

But this causes an AV unless I redeclare DocumentProperties() as ...

  function DocumentProperties(hWnd: HWND; hPrinter: THandle; pDeviceName:
PChar;
  const pDevModeOutput: PDeviceMode; var pDevModeInput: TDeviceMode;
  fMode: DWORD): Longint; stdcall;

... and call appropriately.

This seems to be a bug in Delphi 3. Is it otherwise known, or am I doing
something incorrectly. The AV definitely occurs at the second
DocumentProperties() call.

Is my correction of the Delphi declaration correct or should I really be
declaring that parameter as "var pDevModeOutput : TDeviceMode".

In any case, declaring the parameters as "var ...TDeviceMode" seems perverse
when one considers that a variable amount of memory (usually much more than
SizeOf(TDeviceMode)) must be provided. Declaring as PDeviceMode would make for
much easier code.

Alan Lloyd
alanglloyd@aol.com