Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using the stringgrid objects array

Status
Not open for further replies.

sggaunt

Programmer
Jul 4, 2001
8,620
GB
perhaps I sould have tried this first.. [blush]

I created a simple type to hold some colours for cells

Code:
type TCellCol = Class(TObject)
     BackColour: TColor;
     FontColour: TColor;
     end;

initalise this (cells all draw cream as you would expect)
Code:
  Cellcolour := TCellCol.Create;
  Cellcolour.BackColour := ClCream;
  Cellcolour.FontColour := ClBlack;
  for R := 0 to 1999 do
     for c := 0 to 15 do
       begin
          emergidata.cells[C, R] := inttostr(R);
          emergidata.Objects[C, R] := Cellcolour;
       end;

draw grid gets the colours from the objects array
Code:
procedure TEmergiForm.emergidataDrawCell(Sender: TObject; Col,
  Row: Integer; Rect: TRect; State: TGridDrawState);
var count, r, C: integer;
begin
   r := row;  // Copy variable 'row' as it only  seems to be valid for a short time
   C := Col;  // yes I know this should not be required for new delphi versions
   Count :=  ((Row - 1) * emergidata.colcount) + Col;  // calculate our position in the stringlist
   if (count > 0) and (count <= list.count) then
   with (sender as tstringgrid) do
      begin
         if state = [] then  // dont overwrite fixed areas
            begin
               if R  = Foundrow then
                  canvas.brush.color := FindColour
               else
                   if r > 0 then canvas.brush.color := (Objects[c, r] as TCellCol).BackColour;

               canvas.fillrect(rect);
               canvas.textout(rect.left + 2, rect.top + 2,list.strings[count]);
            end;
      end;

end;

Problem is the array dosnt seen to work if (as a test)
I force some values in like this, then examine the test array, all the values are equal to the last element set
in this case Blue. (and all cells draw blue) None are equal to the initalised value.
Must be somthing simple. I just can't see it.

Code:
                     (Emergidata.Objects[1 ,1] as tCellCol).BackColour := clyellow;
                     (Emergidata.Objects[2, 2] as tCellCol).BackColour:= claqua;
                     (Emergidata.Objects[3, 3] as tCellCol).BackColour := clgreen;
                     (Emergidata.Objects[4, 4] as tCellCol).BackColour:= clblue;

                   inc (Item);
                end;

        end;
        for  r:= 0 to 4 do
          for c := 0 to 4 do
              testarray[c, r] := (emergidata.Objects[c,r] as TCellcol).BackColour;

[red]GNBM 4th Feb[/red] More on and other neat UK stuff at forum1091
Steve: Delphi a feersum engin indeed.
 

You only created one instance of a TCellCol (Cellcolour) and put the pointer to that in the object reference for each cell. As soon as you make a change to that object, the change will naturally apply to all cells.

 
initalistion now look like this and seems to work, Thanks Zarhras

Code:
  for R := 0 to 1999 do
    for c := 0 to 15 do
     begin
        emergidata.cells[C, R] := inttostr(R);
        emergidata.Objects[C, R] := TCellcol.Create;
     end;

[red]GNBM 4th Feb[/red] More on and other neat UK stuff at forum1091
Steve: Delphi a feersum engin indeed.
 

Rather than make 32,000 objects, you could make one of each color combination that you need and place them in a TObjectList (or TStringList if your version of Delphi doesn't support TObjectList). Then you can put the index number of the appropriate object into the object pointer of the cells. That would reduce the number of Create/Destroy operations you would need. (Not to mention the time and memory that 32,000 objects would eat up.)
Code:
  var
    CellColors: TObjectList;
    nCREAM:integer;
    nYELLOW:integer;
    nAQUA:integer;
    nGREEN:integer;
    nBLUE:integer;
  :
  :
  CellColors.Add( MakeCellCol(clCream,clBlack,nCREAM));
  CellColors.Add( MakeCellCol(clYellow,clBlack,nYELLOW));
  CellColors.Add( MakeCellCol(clAqua,clBlack,nAQUA));
  CellColors.Add( MakeCellCol(clGreen,clBlack,nGREEN));
  CellColors.Add( MakeCellCol(clBlue,clBlack,nBLUE));
  :
  :
  emergidata.Objects[C, R] := TObject(0);
  :
  :
  var
    i:integer;
    oCellCol:TCellCol
  :
  :
  i := Integer(emergidata.Objects[col,row]);
  oCellCol := TCellCol(CellColors[i]);
  :
  :
procedure MakeCellCol(cBackground,cForeground:integer; var Index:integer);
// create a TCellCol and add it to the list.
// report back to the caller the assigned position.
begin
:
:
end;
Although it might be simpler all around if you just handle the various cases in your OnDrawCell event handler and don't bother with objects at all.


 
Another way: Code the drawing behavior as a method of TCellCol:
Code:
type
  TCellCol = class(TObject)
  private
    BackColour: TColor;
    FontColour: TColor;
  public
    constructor TCreate( nBackground:TColor; ForeGround:TColor=clBlack);
    procedure DrawCell( ACanvas:TCanvas; AText:string );
  end;

var
  oCream,oYellow,oAqua,oGreen,oBlue:TCellCol;
:
:
  oCream  := TCellCol.Create( clCream );
  oYellow := TCellCol.Create( clYellow );
  oAqua   := TCellCol.Create( clAqua );
  oGreen  := TCellCol.Create( clGreen );
  oBlue   := TCellCol.Create( clBlue );
:
:
  emergidata.Objects[C, R] := oCream;
:
:
  if...
    emergidate.Objects[col,row] := oYellow;
:
:
  with emergidata do
    begin
      TCellCol(Objects[col,row]).DrawCell( Canvas, list.strings[count]);
    end;

 
Zathras
This is just an experiment to look at the practicality of holding unique information (colour font etc) for every cell in a string grid.
In fact the size of the array doesnt need to be any bigger than the size of the string grid which is allocated dynamically when the data is loaded. but in this case I was setting the theoretical maximum of 2000 rows.

In fact the fixed size 32,000 object array caused the application to chuck an exception on shut down (after I added another field), it was probably running the debugger out of memory or something.
So the answer is its not practical.

There may be some reasons to use the pointers to a fixed set of 'display types' as you say, over selecting the colours at draw time, It should be a good thing to the Ondraw routine as sort as possible.


[red]GNBM 4th Feb[/red] More on and other neat UK stuff at forum1091
Steve: Delphi a feersum engin indeed.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top