Hi Jason,
I'm guessing that you originally had something like
type EDCFailed = class(Exception);
var PaperNameArray, PaperSizeArray, PaperIDArray: PChar;
PaperNameCount := DeviceCapabilities(pDevice, pPort, dc_Papernames, nil,
nil);
if PaperNameCount = -1 then raise EDCFailed.Create('Bugger!');
Needed := DeviceCapabilities(pDevice, pPort, dc_PaperSize, nil, nil);
if Needed = -1 then raise EDCFailed.Create('Bugger!');
GetMem(PaperNameArray, PaperNameCount * 64);
GetMem(PaperSizeArray, Needed * SizeOf(Word));
GetMem(PaperIDArray, Needed * SizeOf(TPoint));
try
...
finally
FreeMem(PaperNameArray);
FreeMem(PaperSizeArray);
FreeMem(PaperIDArray);
end;
Is that what you had? Because it should work fine, if DeviceCapabilities
isn't broken. However, I notice that you don't currently check whether
DeviceCapabilities fails (returns -1) anywhere, which you definitely should
(ref. Colin's comments).
In a case like yours I'd actually prefer to use typed dynamic arrays rather
than PChars - as easy to index into as a normal array, you don't have to
free them, and you don't have to use Move all over the place.
type
Char64 = array[0..63] of Char;
var PaperNameArray: array of Char64;
PaperIDArray: array of Word;
PaperSizeArray: array of Point;
You can now go
SetLength(PaperNameArray, PaperNameCount);
SetLength(PaperSizeArray, Needed);
SetLength(PaperIDArray, Needed);
and
PaperSize := PaperSizeArray[Index];
rather than
move(PaperSizeArray[sizeof(Papersize) * Index], PaperSize,
SizeOf(PaperSize));
and you don't need to free anything in a try/finally. You just need to cast
the arrays to PChar when calling DeviceCapabilities. It's off the topic of
GetMem/FreeMem, but I still think if you replaced your code with the
GetMem/FreeMem code I wrote at the top, and added a few checks to ensure a
graceful exit if DeviceCapabilities fails, then things ought to work.
One other pitfall if you were to use PChars in your code, is that you'd have
to be careful to ensure you got the Move calls correct. Using Move brings
dangers of its own, and it's less clear with PChars, for example
Move(MyArray1[0], MyArray[0], 100); // Correct
Move(MyPChar1^, MyPChar^, 100); // Also correct
Move(MyPChar1, MyPChar2, 100); // Screwed!
In the second call, you'd get an invalid pointer exception in your block of
FreeMem's, and you'd be lucky if that was all that went wrong! I often do
this by mistake... ;-)
Cheers,
Carl
-----Original Message-----
From: Jason L. Coley [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, 10 October 2000 5:40 AM
To: Multiple recipients of list delphi
Subject: RE: [DUG]: Creating PChars
Here's one instance of the code, thi part finds the selected paper size
selected in a combo and sets the paper size and IDs and sets the
devmode. This is the code used with the Chars, i used to have the
getmems before the try and the freemem in the finally.
procedure TSetup.cboPaperSizeChange(Sender: TObject);
const
cchPaperName = 64;
var
Index, Needed: Integer;
PaperIDArray: array[0..cchPaperName * 100] of Char;
PaperNameArray: array[0..cchPaperName * 100] of Char;
PaperSizeArray: array[0..cchPaperName * 100] of Char;
PaperName: array[0..cchpaperName] of Char;
PaperSize: TPoint;
MyPapers: Word;
begin
PaperSize.x := 0;
PaperSize.y := 0;
if isloaded then
begin
Needed := DeviceCapabilities(pDevice, pPort,
dc_Papersize, nil, nil);
try
DeviceCapabilities(pDevice, pPort,
dc_Papernames, PaperNameArray, nil);
DeviceCapabilities(pDevice, pPort, dc_PaperSize,
PaperSizeArray, nil);
DeviceCapabilities(pdevice, pPort, dc_Papers,
PaperIDArray, nil);
for Index := 0 to Needed - 1 do
begin
//Move through the paper names until we
find the one selected
move(PaperNameArray[cchPaperName *
Index], PaperName[0], cchPaperName);
if PaperName = cboPaperSize.Text then
begin
//Get the correct paper ID and
set to devmode
move(PaperIDArray[sizeof(MyPapers) * Index], MyPapers,
sizeof(myPapers));
pDMode := GlobalLock(MyhDMode);
pDMode^.dmFields :=
pDMode^.dmFields or dm_PaperSize;
pDMode^.dmPaperSize := MyPapers;
GlobalUnlock(MyhDMode);
Printer.SetPrinter(pDevice,
pDriver, pPort, MyhDMode);
//Copy the dev mode for later
use
pDMode := GlobalLock(MyhDMode);
CopyDevModeSettings(pDMode,
MailPiecepDMode, pDevice);
GlobalUnlock(MyhDMode);
//Get the correct paper size
move(PaperSizeArray[sizeof(Papersize) * Index], PaperSize,
SizeOf(PaperSize));
//For some reason the print
drivers do not return the papersize info?
If (PaperSize.x = 0) or
(PaperSize.y = 0) then
begin
If rdoPortrait.Checked
then
begin
PaperSize.x :=
RoundUp(GetDeviceCaps(Printer.Handle, PHYSICALWIDTH) / ScaleX);
PaperSize.y :=
RoundUp(GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT) / ScaleY);
end
else
begin
PaperSize.y :=
RoundUp(GetDeviceCaps(Printer.Handle, PHYSICALWIDTH) / ScaleX);
PaperSize.x :=
RoundUp(GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT) / ScaleY);
end;
end;
//Copy our sizes for use later
in previews etc.
if MeasureScale = 100 then
begin
TempMailPiece.PageWidth
:= RoundUp(PaperSize.x / 2.54);
TempMailPiece.PageHeight
:= RoundUp(PaperSize.y / 2.54);
end
else
begin
TempMailPiece.PageWidth
:= PaperSize.x;
TempMailPiece.PageHeight
:= PaperSize.y;
end;
//Set the label size for
envelopes
if grpEnvelopeBarcode.Visible
then
begin
IsLoaded := False;
txtLabelWidth.Text :=
inttostr(RoundUp(TempMailPiece.PageWidth / MeasureScale));
txtLabelHeight.Text :=
inttostr(RoundUp(TempMailPiece.PageHeight / MeasureScale));
Isloaded := True;
end;
end;
end;
finally
end;
SetPreview;
SaveChanges := True;
end;
end;
---------------------------------------------------------------------------
New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
Website: http://www.delphi.org.nz
To UnSub, send email to: [EMAIL PROTECTED]
with body of "unsubscribe delphi"