Board index » delphi » array[0..0] of Anything;

array[0..0] of Anything;

Hello All,

     I am a "C" programmer learning "Delphi", and I have some questions about
Pascal arays, specifically the construct:

          array[0..0] of Anything;

1)  What is this creature?  I've seen this in function and procedure
declarations, and it seems to be used whenever the number of elements in the
array is not specified by the "type".  In these cases, the array AND the
number of elements in the array are passed to the function are procedure.

2)  Here is a specific example of when this construct is used.  The Windows'
API function, CreatePalette(), has the following declaration (via Delphi
Online Help):

          function CreatePalette(var LogPalette: TLogPalette): HPalette;

where a TLogPalette is:

          TLogPalette = record
             palVersion: Word;
             palNumEntries: Word;
             palPalEntry: array[0..0] of TPalet{*word*249}try;
          end;

and a TPalet{*word*249}try is:

          TPalet{*word*249}try = record
              peRed: Byte;
              peGreen: Byte;
              peBlue: Byte;
              peFlags: Byte;
           end;

     QUESTION:  How do I create an array of TPalet{*word*249}try's (with say, 10
          elements) and assign this array to TLogPalette.palPalEntry?  No
          matter what I try, I get a type mismatch.

*Any* Help is greatly appreciated.  Thanks,
-neal.

 

Re:array[0..0] of Anything;


Quote
On Wed, 29 Nov 1995, Neal Lawson wrote:
> Hello All,

>      I am a "C" programmer learning "Delphi", and I have some questions about
> Pascal arays, specifically the construct:

>           array[0..0] of Anything;

> 1)  What is this creature?  I've seen this in function and procedure
> declarations, and it seems to be used whenever the number of elements in the
> array is not specified by the "type".  In these cases, the array AND the
> number of elements in the array are passed to the function are procedure.

It is a placeholder, and depends on you having the Range-checking turned
off.

Quote

> 2)  Here is a specific example of when this construct is used.  The Windows'
> API function, CreatePalette(), has the following declaration (via Delphi
> Online Help):

>           function CreatePalette(var LogPalette: TLogPalette): HPalette;

> where a TLogPalette is:

>           TLogPalette = record
>              palVersion: Word;
>              palNumEntries: Word;
>              palPalEntry: array[0..0] of TPalet{*word*249}try;
>           end;

> and a TPalet{*word*249}try is:

>           TPalet{*word*249}try = record
>               peRed: Byte;
>               peGreen: Byte;
>               peBlue: Byte;
>               peFlags: Byte;
>            end;

>      QUESTION:  How do I create an array of TPalet{*word*249}try's (with say, 10
>           elements) and assign this array to TLogPalette.palPalEntry?  No
>           matter what I try, I get a type mismatch.

> *Any* Help is greatly appreciated.  Thanks,
> -neal.

Hmm...  Kindof inconvenient, eh?  Well, that is the way of Windows.  I
don't think things get a whole lot easier in other languages with this
kind of thing.  However, the solution isn't that tough.  Unfortunately,
neither is the solution elegant or portable.  What you do is define your
specific types as you are doing, but typecast them, as in
CreatePallette(TLogPallette(myPalletteVar));
Pretty {*word*193}, eh?

Re:array[0..0] of Anything;


Quote
In article <nlawson.1.000AE...@uga.cc.uga.edu> nlaw...@uga.cc.uga.edu (Neal Lawson) writes:
>     I am a "C" programmer learning "Delphi", and I have some questions about
>Pascal arays, specifically the construct:
>          array[0..0] of Anything;
>1)  What is this creature?  I've seen this in function and procedure
>declarations, and it seems to be used whenever the number of elements in the
>array is not specified by the "type".  In these cases, the array AND the
>number of elements in the array are passed to the function are procedure.
>2)  Here is a specific example of when this construct is used.  The Windows'
>API function, CreatePalette(), has the following declaration (via Delphi
>Online Help):
>          function CreatePalette(var LogPalette: TLogPalette): HPalette;
>where a TLogPalette is:
>          TLogPalette = record
>             palVersion: Word;
>             palNumEntries: Word;
>             palPalEntry: array[0..0] of TPalet{*word*249}try;
>          end;
>and a TPalet{*word*249}try is:
>          TPalet{*word*249}try = record
>              peRed: Byte;
>              peGreen: Byte;
>              peBlue: Byte;
>              peFlags: Byte;
>           end;
>     QUESTION:  How do I create an array of TPalet{*word*249}try's (with say, 10
>          elements) and assign this array to TLogPalette.palPalEntry?  No
>          matter what I try, I get a type mismatch.

Looks like some strange coding practices to me.  Presumably the code in
question is compiled with array-bounds checking turned off...

Presumably the structure contains a variable number of TPalet{*word*249}tries,
beginning with #0 and moving up.  The entry is declared as an array starting
with zero because it is logically an array of identical entries, and the upper
boundary does not matter because no bounds-checking is being done anyway.

You will need to use a loop, not a single assignment, to copy individual
palette entries into the structure.  Be darn sure that there really is enough
memory in whatever you are copying to; otherwise you will scribble the stack.

/mr/

Re:array[0..0] of Anything;


Quote
In article <sundial.1713.01388...@primenet.com> sund...@primenet.com (Sundial Services) writes:
>From: sund...@primenet.com (Sundial Services)
>Subject: Re: array[0..0] of Anything;
>Date: Thu, 30 Nov 1995 14:30:26 MST
>In article <nlawson.1.000AE...@uga.cc.uga.edu> nlaw...@uga.cc.uga.edu (Neal Lawson) writes:
>>     I am a "C" programmer learning "Delphi", and I have some questions about
>>Pascal arays, specifically the construct:
>>          array[0..0] of Anything;
>>1)  What is this creature?  I've seen this in function and procedure
>>declarations, and it seems to be used whenever the number of elements in the
>>array is not specified by the "type".  In these cases, the array AND the
>>number of elements in the array are passed to the function are procedure.
>>2)  Here is a specific example of when this construct is used.  The Windows'
>>API function, CreatePalette(), has the following declaration (via Delphi
>>Online Help):
>>          function CreatePalette(var LogPalette: TLogPalette): HPalette;
>>where a TLogPalette is:
>>          TLogPalette = record
>>             palVersion: Word;
>>             palNumEntries: Word;
>>             palPalEntry: array[0..0] of TPalet{*word*249}try;
>>          end;
>>and a TPalet{*word*249}try is:
>>          TPalet{*word*249}try = record
>>              peRed: Byte;
>>              peGreen: Byte;
>>              peBlue: Byte;
>>              peFlags: Byte;
>>           end;
>>     QUESTION:  How do I create an array of TPalet{*word*249}try's (with say, 10
>>          elements) and assign this array to TLogPalette.palPalEntry?  No
>>          matter what I try, I get a type mismatch.
>Looks like some strange coding practices to me.  Presumably the code in
>question is compiled with array-bounds checking turned off...

yes, bounds checking is off.

Quote
>Presumably the structure contains a variable number of TPalet{*word*249}tries,
>beginning with #0 and moving up.  The entry is declared as an array starting
>with zero because it is logically an array of identical entries, and the upper
>boundary does not matter because no bounds-checking is being done anyway.

Also correct.  I have seen (and tried) a technique for creating
zero-based dynamic arrays in Pascal, and this technique works like this:

(*-------------------*)
type
   TAnyArr = array[0..0] of Anything;
   PTAnyArr = ^TAnyArr;

var
   TArr: PTAnyArr;

begin
          (* Allocate an array of Anything's with a range 0 - numitems-1 *)
   GetMem(TArr, sizeof(Anything) * numitems);

          (* Access the 'index' element of the array *)
   something := TArr^[index].whatever;

          (* Free the dynamic array *)
   FreeMem(TArr, sizeof(Anything) * numitems);
end;
(*--------------------*)

In these cases, the array is always accessed through the POINTER variable, not
an array[0..0] variable.  BTW, the above technique looks to be identical to
"Pointer Arithmetic" in "C" (any comments?).

Quote
>You will need to use a loop, not a single assignment, to copy individual
>palette entries into the structure.  Be darn sure that there really is enough
>memory in whatever you are copying to; otherwise you will scribble the stack.
>/mr

This is where I have the problem:
   1)  I can create an array of TPalette either dynamically (using the GetMem
technique above) or on the stack (using a local array); however, I cannot
successfully assign either variable to the TLogPalette.palPalEntry.   I have
tried every typecast I can think of.  If palPalEntry were a POINTER, this
would work, right?

   2) If I assign palette entries in a loop, how do I allocate the memory for
the array?  I tried this:

   var
      aPalette: TLogPalette;
   begin
     aPalette.palVersion := $300;
     aPalette.palNumEntries := 10;

          (* This line generates a compile-time type error *)
     GetMem(aPalette.palPalEntries, sizeof(TPalet{*word*249}try)*10);

          (* This line compiles but doesn't work *)
     GetMem(Pointer(aPalette.palPalEntries), sizeof(TPalet{*word*249}try)*10);
   end;

*Thank you* to everyone who has responded!  I appreciate the help.
Still trying...
-neal

Re:array[0..0] of Anything;


In article <nlawson.2.00104...@uga.cc.uga.edu>,
   nlaw...@uga.cc.uga.edu (Neal Lawson) wrote:
******************************************************************************
This is where I have the problem:
   1)  I can create an array of TPalette either dynamically (using the GetMem
technique above) or on the stack (using a local array); however, I cannot
successfully assign either variable to the TLogPalette.palPalEntry.   I have
tried every typecast I can think of.  If palPalEntry were a POINTER, this
would work, right?

   2) If I assign palette entries in a loop, how do I allocate the memory for
the array?  I tried this:

   var
      aPalette: TLogPalette;
   begin
     aPalette.palVersion := $300;
     aPalette.palNumEntries := 10;

          (* This line generates a compile-time type error *)
     GetMem(aPalette.palPalEntries, sizeof(TPalet{*word*249}try)*10);

          (* This line compiles but doesn't work *)
     GetMem(Pointer(aPalette.palPalEntries), sizeof(TPalet{*word*249}try)*10);
   end;
******************************************************************************
This is how I used to do it. This code was written for WinG so just ignore
that stuff. I has the method for working with the palette like you want.

Const
  LogPaletteSize = Sizeof(TLogPalette) + Sizeof(TPalet{*word*249}try) * 255;

Procedure TMainWin.ClearSystemPalette;
Var
  ALogPalette  : PLogPalette;
  i            : Integer;
  DC           : HDC;
  AnOldPalette : HPalette;
Begin
  GetMem(ALogPalette, LogPaletteSize);
  If ALogPalette <> Nil Then
    With ALogPalette^ Do
    Begin
      palVersion := $300 ;
      palNumEntries := 256 ;
      For i := 0 To 255 Do
        With palPalEntry[i] Do
        Begin
          peRed := 0;
          peGreen := 0;
          peBlue := 0;
          peFlags := PC_NOCOLLAPSE;
        End;

      { select and realise the palette and clean up }
      DC := GetDC(HWindow);
      AnOldPalette := SelectPalette(DC, CreatePalette(ALogPalette^), False);
      RealizePalette(DC);
      DeleteObject(SelectPalette(DC, AnOldPalette, True));
      ReleaseDC(HWindow, DC);
      FreeMem(ALogPalette, LogPaletteSize);
    End;
End;

Hope it helps,

-----------------------------------------------
Mike Chapin
Powder River
-----------------------------------------------

Re:array[0..0] of Anything;


Quote
nlaw...@uga.cc.uga.edu (Neal Lawson) wrote:
>>>          TLogPalette = record
>>>             palVersion: Word;
>>>             palNumEntries: Word;
>>>             palPalEntry: array[0..0] of TPalet{*word*249}try;
>>>          end;
>   1)  I can create an array of TPalette either dynamically (using the GetMem
>technique above) or on the stack (using a local array); however, I cannot
>successfully assign either variable to the TLogPalette.palPalEntry.   I have
>tried every typecast I can think of.  If palPalEntry were a POINTER, this
>would work, right?

Since only one entry is declared, you can't do a simple assignment and
get more than one value assigned.  Just use Move() to copy as much as
you've got, e.g.

  Move(aPalette,logPalette.palPalEntry, sizeof(aPalette));

Quote

>   2) If I assign palette entries in a loop, how do I allocate the memory for
>the array?  I tried this:

>   var
>      aPalette: TLogPalette;
>   begin
>     aPalette.palVersion := $300;
>     aPalette.palNumEntries := 10;

>          (* This line generates a compile-time type error *)
>     GetMem(aPalette.palPalEntries, sizeof(TPalet{*word*249}try)*10);

You need to allocate the whole record.  It's ugly, but here's what to
do:

GetMem(aPalette, sizeof(aPalette)+
(numwanted-1)*sizeof(TPalet{*word*249}try));

You need that "-1" because the declaration for aPalette already
includes the first entry.

I think this is a really ugly construction, and I would never use it.
If you're forced to use that memory layout, you'll find you cause
yourself less trouble by doing things this way:

 1. Declare a palette header type containing just the version and the
numEntries fields.
 2. Declare a palette entry array type holding the largest conceivable
number of entries.
 3. Declare TLogPalette to have one field of the first type and one of
the second type.  Allocate it using code something like this:

GetMem(aPalette,sizeof(TPaletteHeader)+numwanted*sizeof(TPalet{*word*249}try));

The advantages of this approach are that it's clear what you're doing
during the GetMem, and it'll work with range checking on or off.
Sometimes range checking is an extremely useful tool, and you're
crippling yourself by forcing it to be off.  It's also microscopically
faster, since you don't need that stupid "-1" subtraction, but I don't
think that should be a consideration --- the GetMem will take so much
longer than the subtraction that it's not worth worrying about.

I hope this helps.

Duncan Murdoch

Re:array[0..0] of Anything;


Quote
In article <30c102b5.48735...@130.15.126.54> dmurd...@mast.queensu.ca (Duncan Murdoch) writes:
>From: dmurd...@mast.queensu.ca (Duncan Murdoch)
>Subject: Re: array[0..0] of Anything;
>Date: Sun, 03 Dec 1995 02:05:13 GMT
>nlaw...@uga.cc.uga.edu (Neal Lawson) wrote:
>>>>          TLogPalette = record
>>>>             palVersion: Word;
>>>>             palNumEntries: Word;
>>>>             palPalEntry: array[0..0] of TPalet{*word*249}try;
>>>>          end;

< super snip... >

I just wanted to give a hearty *thanks* to everyone who responded and helped
me out.  Thanks A Bunch!
-Neal Lawson

Other Threads