BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Delphi's DocumentProperties() Declaration

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc
View previous topic :: View next topic  
Author Message
AlanGLLoyd
Guest





PostPosted: Mon Dec 22, 2003 12:42 pm    Post subject: Delphi's DocumentProperties() Declaration Reply with quote



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
[email]alanglloyd (AT) aol (DOT) com[/email]
Back to top
Rob Kennedy
Guest





PostPosted: Mon Dec 22, 2003 4:29 pm    Post subject: Re: Delphi's DocumentProperties() Declaration Reply with quote



AlanGLLoyd wrote:
Quote:
{initial memory allocation}
PtrDMIn := AllocMem(DMMemSize);
DMIn := PtrDMIn^;
PtrDMOut := AllocMem(DMMemSize);
DMOut := PtrDMOut^;

The contents of DMIn and DMOut are all-bits-zero, but they hold
absolutely no relation to PtrDMIn and PtrDMOut.

Don't forget to protect those memory allocations with try-finally blocks
so the memory gets freed when OpenPrinter fails below.

Quote:
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^;

Once again, DMIn and DMOut are zeroed, but have no connection to the
pointers. I see no need to have allocated or initialized the variables
the first time since they aren't used to call OpenPrinter or
DocumentProperties.

Quote:
{get printer devmode}
DocumentProperties(Self.Handle, hndPrinter, 'HP Laserjet 5P/5MP (HP)',
DMIn, DMOut, DM_OUT_BUFFER);

Since you already have pointers to TDeviceMode records, pass those
instead; get rid of DMIn and DMOut altogether.

DocumentProperties(..., PtrDMIn^, PtrDMOut^, dm_Out_Buffer);

According to MSDN, you're passing the In and Out variables in the
reverse order. Also, one of those parameters is ignored unless you use
the dm_In_Buffer mode.

I agree that Borland's declaration is lousy. The variable size of the
buffer makes const and var parameters very clumsy to use. Here's how it
should have been declared:

function DocumentProperties(hWnd: HWND; hPrinter: THandle; pDeviceName:
PChar; pDevModeOutput, pDevModeInput: PDeviceMode; fMode: DWORD):
Longint; stdcall; external winspl name 'DocumentPropertiesA';

You can add that to your own unit and it should hide the declaration
from WinSpool.

--
Rob

Back to top
AlanGLLoyd
Guest





PostPosted: Mon Dec 22, 2003 6:06 pm    Post subject: Re: Delphi's DocumentProperties() Declaration Reply with quote



In article <vue6vosd3fg961 (AT) corp (DOT) supernews.com>, Rob Kennedy <.> writes:

Quote:
Since you already have pointers to TDeviceMode records, pass those
instead; get rid of DMIn and DMOut altogether.

DocumentProperties(..., PtrDMIn^, PtrDMOut^, dm_Out_Buffer);


For some reason I thought that a var Parameter must be passed as a variable,
not as a "PointerToStructure-Contents". That's what lead me down the DMIn and
DMOut path.

<snip>
Quote:
I agree that Borland's declaration is lousy. The variable size of the
buffer makes const and var parameters very clumsy to use. Here's how it
should have been declared:

Thats what I did and it all worked OK.


Thanks for the comments.

I really started out getting the paper bin names and values. Getting and
changing printer attributes is incredibly messy with complex APIs. Does it get
any better after D3 ?

OTOH is it possible to use a TDevMode with a non-standard
unknown-at-design-time size (ie other than declaring the larger buffer and then
using "PointerToDevMode-Contents")

Having sussed out the bin names and values GetPrinter and SetPrinter is a not
too bad way of doing it.

Alan Lloyd
[email]alanglloyd (AT) aol (DOT) com[/email]




Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.