Конференция "Компоненты" » Разработка FlawlessGrid [D6]
 
  • Залозных Игорь (27.03.07 15:00) [0]
    Уважаемые мастера.
    Скажите, почему я не могу использовать
    SetCell, хотя по коду кажется, что используется.
    Шрифт также не могу использовать, возникает ошибка.
    Как исправить?

      grid.Cell[5,2].Color:=clLime;
      grid.Cell[5,2].Font.Size:=20;
      grid.Cell[6,3].Color:=clGreen;

    unit FlawlessGrid;

    interface

    uses
     Windows, Messages, SysUtils, Classes, Grids, Graphics;

    const
      MaxRowCount = High(Word);
      MaxColCount = High(Byte);

    type
      THorizontalAlignment = (HaLeft,HaCenter,HaRight,HaWidth);

    type
      TVerticalAlignment = (VaTop,VaCenter,VaBottom,VaHeight);

    type
      TBorder = packed record
         Visible:Boolean;
    end;

    type
      TBorders = packed record
         Left:TBorder;
         Right:TBorder;
         Top:TBorder;
         Bottom:TBorder;
         TopLeft:TBorder;
         BottomLeft:TBorder;
    end;

    type
      TLocate = packed record
         ACol:Longint;
         ARow:Longint;
    end;

    type
      TMerge = packed record
         Merged:Boolean;
         MainCell:TLocate;
         Region:TRect;
    end;

    type
      TImage = packed record
         Empty:Boolean;
         Picture:TBitmap;
    end;

    type
      THistoryChanges = class
         private
            Number:Integer;
            Name:PChar;  
    end;

    type
      TCell = class(TObject)
         private
           FBrush:TBrush;
           FFont:TFont;
           FPen:TPen;
           FModify:Boolean;
           procedure SetBrush(Value:TBrush);
           procedure SetFont(Value:TFont);
           procedure SetPen(Value:TPen);
           procedure SetModify(Value:Boolean);
         public
            HorizontalAlignment:THorizontalAlignment;
            VerticalAlignment:TVerticalAlignment;
            Color:TColor;
            Borders:TBorders;
            Enabled:Boolean;
            Hint:PChar;
            Merged:TMerge;
            Picture:TImage;
            Empty:Boolean;
            property Brush:TBrush read FBrush write SetBrush;
            property Font:TFont read FFont write SetFont;
            property Pen:TPen read FPen write SetPen;
            property Modify:Boolean read FModify write SetModify;
    end;

    type
     TFlawlessGrid = class(TStringGrid)
     private
         function GetCell(ACol, ARow: Integer): TCell;
         procedure SetCell(ACol, ARow: Integer; Value: TCell);
         function CheckRange(var ACol,ARow:Integer):Boolean;
     protected
         procedure DrawCell(ACol, ARow: Longint; Rect: TRect;State: TGridDrawState); override;
         procedure Paint; override;
     public
         constructor Create(AOwner:TComponent); override;
         destructor Destroy; override;
         property Cell[ACol,ARow:Integer]:TCell read GetCell write SetCell;
     published
    end;

    procedure Register;

    implementation

    procedure Register;
    begin
     RegisterComponents('Samples', [TFlawlessGrid]);
    end;

    function TFlawlessGrid.CheckRange(var ACol, ARow:Integer):Boolean;
    begin
      if ACol > MaxColCount then
      begin
         ACol:=MaxColCount;
      end;
      if ARow > MaxRowCount then
      begin
         ARow:=MaxRowCount;
      end;
      Result:=True;
    end;

    procedure TFlawlessGrid.SetCell(ACol, ARow: Integer; Value: TCell);
    begin
      if Value <> nil then
      begin
         GetCell(ACol,ARow).Brush:=Value.Brush;
         GetCell(ACol,ARow).Color:=Value.Color;
         GetCell(ACol,ARow).FFont:=Value.FFont;
         GetCell(ACol,ARow).Pen:=Value.Pen;
         GetCell(ACol,ARow).Modify:=Value.Modify;
         GetCell(ACol,ARow).HorizontalAlignment:=Value.HorizontalAlignment;
         GetCell(ACol,ARow).VerticalAlignment:=Value.VerticalAlignment;
         GetCell(ACol,ARow).Borders:=Value.Borders;
         GetCell(ACol,ARow).Merged:=Value.Merged;
         GetCell(ACol,ARow).Picture:=Value.Picture;
         GetCell(ACol,ARow).Empty:=Value.Empty;
      end;
    end;

    function TFlawlessGrid.GetCell(ACol, ARow: Integer): TCell;
    begin
      Result:=nil;
      CheckRange(ACol,ARow);
      if (Objects[ACol,ARow] = nil) then
      begin
         Result:=TCell.Create;
         Result.FBrush:=TBrush.Create;
         Result.FBrush.Assign(Canvas.Brush);
         Result.FFont:=TFont.Create;
         Result.FFont.Assign(Font);
         Result.FPen:=TPen.Create;
         Result.FPen.Assign(Canvas.Pen);
         Result.FModify:=False;
         Result.HorizontalAlignment:=HaLeft;
         Result.VerticalAlignment:=VaTop;
         Result.Color:=Color;
         Result.Enabled:=True;
         Objects[ACol,ARow]:=Result;
      end else
      begin
         SetCell(ACol,ARow,Result);
      end;
    end;

    procedure TCell.SetModify(Value:Boolean);
    begin
      FModify:=Value;
    end;

    procedure TCell.SetBrush(Value:TBrush);
    begin
      if Value <> nil then
         FBrush:=Value;
    end;

    procedure TCell.SetPen(Value:TPen);
    begin
      if Value <> nil then
         FPen:=Value;
    end;

    procedure TCell.SetFont(Value:TFont);
    begin
      if Value <> nil then
         FFont:=Value;
    end;

    constructor TFlawlessGrid.Create(AOwner: TComponent);
    begin
      inherited;
      if RowCount > MaxRowCount then
         RowCount:=MaxRowCount;
      if ColCount > MaxColCount then
         ColCount:=MaxColCount;
    end;

    destructor TFlawlessGrid.Destroy;
    begin
      inherited;
    end;

    procedure TFlawlessGrid.DrawCell(ACol, ARow: Integer; Rect: TRect;State: TGridDrawState);
    procedure RepaintCell;
    var
      Temp:TRect;
    begin
     if ((Objects[ACol,ARow] as TCell) <> nil) and
     ((Objects[ACol,ARow] as TCell).Color <> Color) then
      begin
         Temp.Left:=Rect.Left-1;
         Temp.Right:=Rect.Right+1;
         Temp.Top:=Rect.Top-1;
         Temp.Bottom:=Rect.Bottom+1;
         Canvas.Brush.Color:=(Objects[ACol,ARow] as TCell).Color;
         Canvas.FillRect(Temp);
      end;
    end;
    begin
      RepaintCell;
      if gdFocused in State then
      begin
      end else
      if gdSelected in State then
      begin
      end;
    end;

    procedure TFlawlessGrid.Paint;
    begin
      inherited;
    end;

    end.
  • DimaBr (27.03.07 15:28) [1]
    метод
    procedure SetCell(ACol, ARow: Integer; Value: TCell);


    находится в private секции, поэтому вне данного модуля (и класса) использоваться не может. Перенесите его в секцию protected и вы сможете использовать его в потомках.
  • DimaBr (27.03.07 15:34) [2]
    Метод

    procedure TFlawlessGrid.SetCell(ACol, ARow: Integer; Value: TCell);
    begin
     if Value <> nil then
     begin
        GetCell(ACol,ARow).Brush:=Value.Brush;
        GetCell(ACol,ARow).Color:=Value.Color;
        GetCell(ACol,ARow).FFont:=Value.FFont;
        GetCell(ACol,ARow).Pen:=Value.Pen;
        GetCell(ACol,ARow).Modify:=Value.Modify;
        GetCell(ACol,ARow).HorizontalAlignment:=Value.HorizontalAlignment;
        GetCell(ACol,ARow).VerticalAlignment:=Value.VerticalAlignment;
        GetCell(ACol,ARow).Borders:=Value.Borders;
        GetCell(ACol,ARow).Merged:=Value.Merged;
        GetCell(ACol,ARow).Picture:=Value.Picture;
        GetCell(ACol,ARow).Empty:=Value.Empty;
     end;
    end;


    лучше переписать так

    procedure TFlawlessGrid.SetCell(ACol, ARow: Integer; Value: TCell);
    Var ACell: TCell;
    begin
     if Value = nil then Exit;
     ACell := GetCell(ACol,ARow);
     if ACell = nil then Exit;
    //   ACell.AssignTo(Value);  и в AssignTo проводить присваивание
    //  илиже прямо здесь
     ACell.Brush:=Value.Brush;
     ACell.Color:=Value.Color;
    ...
    end;

  • DimaBr (27.03.07 15:38) [3]
    Извиняюсь, сложные типы нужно присваивать так
    ACell.Brush.Assign(Value.Brush);

  • Залозных Игорь (27.03.07 16:20) [4]
    Переписал, все равно ошибка выскакивает.
    При нажатии на кнопке(пример) - Font багует.

      grid.Cell[5,2].Color:=clLime;
      grid.Cell[5,2].Font.Size:=20;
      grid.Cell[6,3].Color:=clGreen;
      grid.Cell[4,3].Color:=clYellow;
      grid.Cell[3,4].Color:=clMaroon;
      grid.Cell[4,4].Color:=clRed;
      grid.Cell[18,5].Color:=clNavy;

    procedure TFlawlessGrid.SetCell(ACol, ARow: Integer; Value: TCell);
    var
      FCell: TCell;
    begin
      if Value = nil then
         Exit;
      FCell := GetCell(ACol,ARow);
      if FCell = nil then
         Exit;
      begin
      FCell.Brush.Assign(Value.Brush);
      FCell.Font.Assign(Value.Font);
      FCell.Pen.Assign(Value.Pen);
      FCell.Modify:=Value.Modify;
      end;
    end;

    function TFlawlessGrid.GetCell(ACol, ARow: Integer): TCell;
    var
      FCell:TCell;
    begin
      Result:=nil;
      CheckRange(ACol,ARow);
      if (Objects[ACol,ARow] = nil) then
      begin
         FCell:=TCell.Create;
         FCell.Brush:=TBrush.Create;
         FCell.Brush.Assign(Canvas.Brush);
         FCell.Font:=TFont.Create;
         FCell.Font.Assign(Font);
         FCell.Pen:=TPen.Create;
         FCell.Pen.Assign(Canvas.Pen);
         FCell.Color:=Color;
         Objects[ACol,ARow]:=FCell;
         Result:=FCell;
      end else
      begin
         SetCell(ACol,ARow,(Objects[ACol,ARow] as TCell));
      end;
    end;
  • DimaBr (27.03.07 17:01) [5]
    На какую кнопку ???
  • Залозных Игорь (27.03.07 17:08) [6]
    Да я к примеру, когда инсталишь компонент и кидаешь на форму
    кнопку и FlawlessGrid, тогда и увидишь баг.
  • Залозных Игорь (27.03.07 17:34) [7]
    сам разобрался.
    Убрал вообще метод SetCell, а GetCell переписал.
    в protected
    property Cell[ACol,ARow:Integer]:TCell read GetCell;
    Хотя сейчас уже без разницы в какой уровнь ставить метод.

    Все заработало.
    Буду дальше разрабатывать.

    function TFlawlessGrid.GetCell(ACol, ARow: Integer): TCell;
    var
      FCell:TCell;
    begin
      Result:=nil;
      CheckRange(ACol,ARow);
      if (Objects[ACol,ARow] = nil) then
      begin
         FCell:=TCell.Create;
         FCell.Brush:=TBrush.Create;
         FCell.Brush.Assign(Canvas.Brush);
         FCell.Font:=TFont.Create;
         FCell.Font.Assign(Font);
         FCell.Pen:=TPen.Create;
         FCell.Pen.Assign(Canvas.Pen);
         FCell.Color:=Color;
         Objects[ACol,ARow]:=FCell;
         Result:=FCell;
      end else
      begin
         Result:=(Objects[ACol,ARow] as TCell);
      end;
    end;
  • DimaBr (28.03.07 08:41) [8]

    ...
    FCell.Pen.Assign(Canvas.Pen);
    FCell.Color:=Color;
    Objects[ACol,ARow]:=FCell;
    Result:=FCell;


    Можно и без временной переменной

    ...
    Result.Pen.Assign(Canvas.Pen);
    Result.Color:=Color;
    Objects[ACol,ARow]:=Result;

  • GrayFace © (29.03.07 18:04) [9]
    DimaBr   (27.03.07 15:38) [3]
    Извиняюсь, сложные типы нужно присваивать так
    ACell.Brush.Assign(Value.Brush);

    Только это должно делаться в TCell.SetBrush
  • DimaBr (30.03.07 08:42) [10]

    > GrayFace ©   (29.03.07 18:04) [9]
    > Только это должно делаться в TCell.SetBrush

    Само собой, и должен быть Assign.
 
Конференция "Компоненты" » Разработка FlawlessGrid [D6]
Есть новые Нет новых   [119244   +4][b:0][p:0.001]