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"

Reply via email to