⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generatormessagesgrid.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
begin
 CalcDrawInfo(DrawInfo);               //calculate current view
 Result := DrawInfo.Vert.GridBoundary; //return used vertical height
end;

{Calculates the visible coordinates of a single cell.
~param ACol, ARow the cell whose coordinates should be calculated
~result the coordinates of the rectangle of the cell }
function TGMGrid.CellRect(ACol, ARow: Integer): TRect;
begin
 Result := BoxRect(ACol, ARow, ACol, ARow);  //treat the cell as a rectangle
end;

{Calculates the visible coordinates of a rectangle of cells.
~param ALeft, ATop, ARight, ABottom the positions of the cells spanning the
                                    rectangle
~result the coordinates of the rectangle containing the cells }
function TGMGrid.BoxRect(ALeft, ATop, ARight, ABottom: Integer): TRect;
var      GridRect       :TGMGridRect;           //the rectangle as a rectangle
begin
 GridRect.Left := ALeft;                        //assign to rectangle structure
 GridRect.Right := ARight;
 GridRect.Top := ATop;
 GridRect.Bottom := ABottom;
 GridRectToClientRect(GridRect, Result, False); //calculate position
end;

{Calculates the client rectangle of a rectangle of cells.
~param GridRect    the rectangle of cells to calculate the visible rectangle of
~param ClientRect  out: the coordinates of the visible rectangle containing all
                        cells in the rectangle
~param IncludeLine whether the lower and right border lines of the cells should
                   be included in the resulting rectangle }
procedure TGMGrid.GridRectToClientRect(GridRect: TGMGridRect;
                                       var ClientRect: TRect;
                                       IncludeLine: Boolean);

 {Returns the client position of a line (column or row) inside the grid.
 ~param AxisInfo the information about the axis of the line to calculate the
                 position with
 ~param CellLine the line (column or row) of the grid whose position should
                 be calculated
 ~result the position of the line or 0 }
 function LinePos(const AxisInfo: TGridAxisDrawInfo;
                  CellLine: Integer): Integer;
 var      Start  :Integer;                   //first cell to count through
          i      :Integer;                   //counter through cells
 begin
  Result := 0;                               //position starts at beginning
  if CellLine < AxisInfo.FixedCellCount then //is a fixed cell?
   Start := 0                                  //start at first fixed cell
  else
   begin
    //start at first non-fixed and visible cell (FLeftTop.x/y)
    Start := AxisInfo.FirstGridCell;
    if CellLine >= Start then                  //the line is visible?
     Result := AxisInfo.FixedBoundary;           //position after fixed cells
   end;

  //add space of all visible lines before the line
  i := Start;
  while (i < CellLine) and (Result <= AxisInfo.GridExtent) do
   begin
    Inc(Result, AxisInfo.GetExtent(i) + AxisInfo.EffectiveLineWidth);
    Inc(i);
   end;
  if Result > AxisInfo.GridExtent then       //line not visible anymore?
   Result := 0;                                //return "invalid" position
 end;

 {Calculates the position of the rectangle on one of the axes.
 ~param AxisInfo      the information about the axis
 ~param GridRectMin   the smaller edge of the rectangle (Left or Top)
 ~param GridRectMax   the bigger edge of the rectangle (Right or Bottom)
 ~param ClientRectMin out: position of smaller edge
 ~param ClientRectMax out: position of bigger edge
 ~result whether the rectangle is visible on this axis }
 function CalcAxis(const AxisInfo: TGridAxisDrawInfo;
                   GridRectMin, GridRectMax: Integer;
                   var ClientRectMin, ClientRectMax: Integer): Boolean;
 begin
  //smaller edge may be visible?
  Result := (GridRectMin < AxisInfo.FixedCellCount) or
            (GridRectMin >= AxisInfo.FirstGridCell);
  if not Result then                           //smaller edge not visible?
   begin
    //bigger edge is visible or selection spans visible part?
    Result := GridRectMax >= AxisInfo.FirstGridCell;
    if Result then
     //use the first visible cell as the smaller edge instead of
     GridRectMin := AxisInfo.FirstGridCell;        //the invisible one
   end;
  if Result then                               //rectangle is visible?
   begin
    //bigger edge is not visible?
    if GridRectMax > AxisInfo.LastFullVisibleCell then
     begin
      GridRectMax := AxisInfo.LastFullVisibleCell;  //restrict to visible part
      if GridRectMax < AxisInfo.GridCellCount - 1 then //not the last cell?
       //include the following only partly visible cell
       Inc(GridRectMax);
      if LinePos(AxisInfo, GridRectMax) = 0 then    //bigger edge not visible?
       Dec(GridRectMax);                              //use the previous one
     end;

    //calculate the positions of both edges
    ClientRectMin := LinePos(AxisInfo, GridRectMin);
    ClientRectMax := LinePos(AxisInfo, GridRectMax);
    if ClientRectMax = 0 then                    //bigger edge not visible?
     //only use rectangle including the cells of the smaller edge
     ClientRectMax := ClientRectMin + AxisInfo.GetExtent(GridRectMin)
    else
     //extend the rectangle to include the cells of the bigger edge
     Inc(ClientRectMax, AxisInfo.GetExtent(GridRectMax));
    if ClientRectMax > AxisInfo.GridExtent then  //extends beyond client size?
     ClientRectMax := AxisInfo.GridExtent;         //limit to it
    if IncludeLine then                          //should include border line?
     Inc(ClientRectMax, AxisInfo.EffectiveLineWidth); //add it
   end;
 end;

var       DrawInfo   :TGridDrawInfo;   //information about the view of the grid
          TempX      :Integer;         //to swap coordinates horizontally
begin
 FillChar(ClientRect, SizeOf(ClientRect), 0); //clear the resulting rectangle
 if (GridRect.Left <= GridRect.Right) and     //is a valid rectangle?
    (GridRect.Top <= GridRect.Bottom) then
  begin
   CalcDrawInfo(DrawInfo);                      //calculate current view

   //rectangle is not scrolled out of view (too far left or down)?
   if (GridRect.Left <= DrawInfo.Horz.LastFullVisibleCell + 1) and
      (GridRect.Top <= DrawInfo.Vert.LastFullVisibleCell + 1) then
    begin
     //calculate right and left client coordinates
     if CalcAxis(DrawInfo.Horz, GridRect.Left, GridRect.Right,
                 ClientRect.Left, ClientRect.Right) then
      //calculate upper and lower client coordinates
      if not CalcAxis(DrawInfo.Vert, GridRect.Top, GridRect.Bottom,
                      ClientRect.Top, ClientRect.Bottom) then //not visible?
       begin
        ClientRect.Left := 0;                         //clear rectangle again
        ClientRect.Right := 0;
       end
      else
       if UseRightToLeftAlignment and        //has to be mirrored horizontally?
          (Canvas.CanvasOrientation = coLeftToRight) then
        begin
         TempX := ClientRect.Left;             //mirror it
         ClientRect.Left := ClientWidth - ClientRect.Right;
         ClientRect.Right := ClientWidth - TempX;
        end;
    end;
  end;
end;


{Calculates the cell at the specified client coordinate.
~param X, Y     the client coordinate to search the cell at
~param DrawInfo information about the view of the grid
~result the cell located at the position, an axis may be -1 if not in a cell }
function TGMGrid.CalcCellFromPoint(X, Y: Integer;
                                  const DrawInfo: TGridDrawInfo): TGMGridCoord;

 {Calculate the row or column at the position.
 ~param AxisInfo the information about the axis of the line to calculate the
                 cell with
 ~param N        the position within the axis to calculate the cell with
 ~result the cell (column or row) at the position }
 function DoCalc(const AxisInfo: TGridAxisDrawInfo; N: Integer): Integer;
 var      Stop  :Integer;               //the last cell to check
          Line  :Integer;               //position of the cell
 begin
  if N < AxisInfo.FixedBoundary then    //is on the fixed cells?
   begin
    Result := 0;                          //start with the first (fixed) cell
    Stop := AxisInfo.FixedCellCount - 1;  //to the last fixed cell
    Line := 0;                            //fixed cell starts at the beginning
   end
  else
   begin
    Result := AxisInfo.FirstGridCell;     //start with first shown cell
    Stop := AxisInfo.GridCellCount - 1;   //up to the last cell
    Line := AxisInfo.FixedBoundary;       //cell starts after the fixed cells
   end;

  //run through all the cells until position in it
  while (Result <= Stop) and (Line < N) do
   begin                                  //move line to the next cell
    Inc(Line, AxisInfo.GetExtent(Result) + AxisInfo.EffectiveLineWidth);
    Inc(Result);                          //and resume with the next cell
   end;
  if Line < N then                      //not on a cell?
   Result := -1                           //return invalid index
  else
   Dec(Result);                           //restore matching index
 end;

 {Calculate the column at the position.
 ~param AxisInfo the information about the horizontal axis to calculate the
                 column with
 ~param N        the position within the axis to calculate the cell with
 ~result the column at the position }
 function DoCalcRightToLeft(const AxisInfo: TGridAxisDrawInfo;
                            N: Integer): Integer;
 var      Stop             :Integer;    //the last cell to check
          Line             :Integer;    //position of the cell
 begin
  N := ClientWidth - N;                 //mirror the position
  Result := AxisInfo.FirstGridCell;     //start with first shown cell
  Stop := AxisInfo.GridCellCount - 1;   //up to the last cell
  Line := 0;                            //cell starts at the beginning

  //run through all the cells until position in it
  while (Result <= Stop) and (Line < N) do
   begin                                  //move line to the next cell
    Inc(Line, AxisInfo.GetExtent(Result) + AxisInfo.EffectiveLineWidth);
    Inc(Result);                          //and resume with the next cell
   end;
  if Line < N then                      //not on a cell?
   Result := -1                           //return invalid index
  else
   Dec(Result);                           //restore matching index
 end;

begin
 if UseRightToLeftAlignment then        //is horizonatally mirrored?
  Result.X := DoCalcRightToLeft(DrawInfo.Horz, X) //calculate column mirrored
 else
  Result.X := DoCalc(DrawInfo.Horz, X);   //calculate column at the position
 Result.Y := DoCalc(DrawInfo.Vert, Y);  //calculate row at the position
end;


{Calculates the information about the current view of the grid.
~param DrawInfo out: information about the view of the grid }
procedure TGMGrid.CalcDrawInfo(var DrawInfo: TGridDrawInfo);
begin
 CalcDrawInfoXY(DrawInfo, ClientWidth, ClientHeight);
end;

{Calculates and sets the information about the currently shown cells.
~param DrawInfo            out: information about the view of the grid
~param UseWidth, UseHeight the size of the visible area
                           (i.e. ClientWidth and ClientHeight) }
procedure TGMGrid.CalcDrawInfoXY(var DrawInfo: TGridDrawInfo;
                                 UseWidth, UseHeight: Integer);

 {Calculates the information about the currently shown cells on one axis.
 ~param AxisInfo  out: the information about the axis
 ~param UseExtend the size of the area to use }
 procedure CalcAxis(var AxisInfo: TGridAxisDrawInfo; UseExtent: Integer);
 var       i       :Integer;                 //counter through columns/rows
 begin
  AxisInfo.GridExtent := UseExtent;          //set available space

  AxisInfo.GridBoundary := AxisInfo.FixedBoundary; //initialize used space
  i := AxisInfo.FirstGridCell;
  while (i < AxisInfo.GridCellCount) and     //add up all cells
        (AxisInfo.GridBoundary <=             //until space filled
         AxisInfo.GridExtent + AxisInfo.EffectiveLineWidth) do
   begin
    Inc(AxisInfo.GridBoundary, AxisInfo.GetExtent(i));  //add the used spaces
    Inc(AxisInfo.GridBoundary, AxisInfo.EffectiveLineWidth);
    Inc(i);                                             //next cell
   end;

  if i <> AxisInfo.FirstGridCell then        //cells available and fit?
   begin
    Dec(i);                                    //the last cell didn't fit
    AxisInfo.LastFullVisibleCell := i;         //set last fitting cell
    AxisInfo.FullVisBoundary := AxisInfo.GridBoundary; //and used space

    if AxisInfo.GridBoundary >                 //last cell didn't fit?
       AxisInfo.GridExtent + AxisInfo.EffectiveLineWidth then
     begin
      AxisInfo.GridBoundary := AxisInfo.GridExtent; //use maximum space
      //remove space of last cell again
      Dec(AxisInfo.FullVisBoundary, AxisInfo.GetExtent(i));
      Dec(AxisInfo.FullVisBoundary, AxisInfo.EffectiveLineWidth);
      Dec(AxisInfo.LastFullVisibleCell);         //last cell not fully visible
     end;
   end
  else
   begin
    //only the first cell fits (although that's probably not true)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -