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

📄 generatormessagesgrid.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    AxisInfo.LastFullVisibleCell := AxisInfo.FirstGridCell;
    //only fixed cells fit (maybe not even they)
    AxisInfo.FullVisBoundary := AxisInfo.FixedBoundary;
    if AxisInfo.GridBoundary >                      //fixed cells don't fit?
       AxisInfo.GridExtent + AxisInfo.EffectiveLineWidth then
     AxisInfo.GridBoundary := AxisInfo.GridExtent;    //use maximum space
   end;
 end;

begin
 CalcFixedInfo(DrawInfo);             //calculate information about fixed cells
 CalcAxis(DrawInfo.Horz, UseWidth);   //and of both axes
 CalcAxis(DrawInfo.Vert, UseHeight);
end;

{Calculates the information about the always visible parts of the grid.
~param DrawInfo out: information about always visible parts of the grid }
procedure TGMGrid.CalcFixedInfo(var DrawInfo: TGridDrawInfo);

  {Calculates the information about the always visible parts of an axis.
  ~param Axis          out: information about always visible parts of the axis
  ~param LineOptions   option pertaining this axis that may be set
  ~param FirstCell     the first visible (non-fixed) cell
  ~param CellCount     the total number of cells in this axis
  ~param GetExtendFunc the function to get the used space of cells
  ~param Row           whether it is the horizontal axis (along the rows) }
 procedure CalcFixedAxis(var Axis: TGridAxisDrawInfo;
                         LineOptions: TGMGridOption;
                         FirstCell, CellCount: Integer;
                         GetExtentFunc: TGetExtentsFunc; Row: Boolean);
 begin
  if FirstCell < 0 then        //make sure the value of the first cell is valid
   FirstCell := 0;

  if LineOptions in Options then      //set width of the line between the cells
   Axis.EffectiveLineWidth := 1
  else
   Axis.EffectiveLineWidth := 0;

  if Row or (GetFixedRows = 0) then   //no fixed cells used for the axis?
   begin
    Axis.FixedBoundary := 0;            //they use not space
    Axis.FixedCellCount := 0;           //no fixed cells
   end
  else
   begin
    Axis.FixedBoundary := FTitleHeight; //set height of title bar
    Axis.FixedCellCount := 1;           //the title bar is only one row
    if FirstCell = 0 then      //make sure the value of the first cell is valid
     FirstCell := 1;
   end;

  Axis.FirstGridCell := FirstCell;    //set the first visible (non-fixed) cell
  Axis.GridCellCount := CellCount;    //the number of cells and
  Axis.GetExtent := GetExtentFunc;    //the function to get the size of cells
 end;

begin
 //calculate the information about the always visible parts of both axes
 CalcFixedAxis(DrawInfo.Horz, goVertLine, LeftCol, ColCount, GetWidthOfCol,
               True);
 CalcFixedAxis(DrawInfo.Vert, goHorzLine, TopRow, RowCount, GetRowHeights,
               False);
end;

{Checks whether the size of a column can be changed at the position.
~param X, Y          the position of the mouse pointer within the component
~param State         out: gsColSizing if a column can be resized at the
                          position or gsNormal if that is not the case
~param Index         out: index of the column to be resized
~param SizingOrgSize out: the position of the of the separator that can be used
                          to resize the column
~param SizingOfs     out: the offset (difference) of the mouse pointer from the
                          separator
~param FixedInfo information about the view of the grid }
procedure TGMGrid.CalcSizingState(X, Y: Integer; var State: TGMGridState;
                                  var Index: Integer;
                                  var SizingOrgSize, SizingOfs: Integer;
                                  const FixedInfo: TGridDrawInfo);

  {Checks whether the size of a column can be changed.
  ~param AxisInfo the information about the axis to check for resizing
  ~param Pos      the position on the axis }
  procedure CalcAxisState(const AxisInfo: TGridAxisDrawInfo; Pos: Integer);
  var       Range        :Integer;       //the range forward to check
            Back         :Integer;       //the range backward to check
            Line         :Integer;       //the position of the sizing line
            i            :Integer;       //counter through columns
  begin
   if UseRightToLeftAlignment then       //grid is mirrored left to right?
    Pos := ClientWidth - Pos;              //correct position
   Range := AxisInfo.EffectiveLineWidth; //widths of lines to resize columns
   if Range < 5 then                     //range is too small?
    begin
     Range := 5;                           //use this minimal width
     Back := (Range - AxisInfo.EffectiveLineWidth) div 2 +
             AxisInfo.EffectiveLineWidth;  //this means this far backward
    end
   else
    //line width will be added before comparing, so adjust backward range
    Back := AxisInfo.EffectiveLineWidth;
   Dec(Range, Back);                     //decrease forward by backward

   Line := AxisInfo.FixedBoundary;       //start at the first cell
   i := AxisInfo.FirstGridCell;
   if i < AxisInfo.GridCellCount then    //some cells available?
    begin
     repeat
       Inc(Line, AxisInfo.GetExtent(i));     //calculate end of the column
       Inc(Line, AxisInfo.EffectiveLineWidth);
       Inc(i);                               //resume with next column

     //last column reached, end of grid reached or on end of column?
     until (i = AxisInfo.GridCellCount) or (Line > AxisInfo.GridBoundary) or
           ((Pos >= Line - Back) and (Pos <= Line + Range));

     if Line > AxisInfo.GridBoundary then  //end of the grid reached?
      begin
       Line := AxisInfo.GridExtent;          //compare with its end
       i := AxisInfo.LastFullVisibleCell + 1 + 1; //last column will be resized
      end;

     //is at the end of a column (between two columns)?
     if (Pos >= Line - Back) and (Pos <= Line + Range) then
      begin
       Index := i - 1;                       //return column to be resized
       SizingOrgSize := AxisInfo.GetExtent(i - 1); //set size of column
       SizingOfs := Line - Pos;              //offset of the pointer from it
       State := gsColSizing;                 //column can be resized
      end;
    end;
  end;

begin
 State := gsNormal;       //assume columns can not be resized at that position
 Index := -1;
 Assert(FixedInfo.Vert.GridExtent = ClientHeight);
 Assert(FixedInfo.Horz.GridExtent = ClientWidth);
 //is on the title bar and on a column?
 if Y < FixedInfo.Vert.FixedBoundary then
  CalcAxisState(FixedInfo.Horz, X);   //check whether it is between two columns
end;


{Calculates the minimum ~[link FTopLeft] that will put the given Coord in view,
 if the grid has to be scrolled right or down to make the cell visible.
~param Coord    the coordinate to make visible
~param DrawInfo information about the view of the grid
~result the new scroll position to be used to show the specified cell }
function TGMGrid.CalcMinTopLeft(const Coord: TGMGridCoord;
                                const DrawInfo: TGridDrawInfo): TGMGridCoord;

  {Calculates the new ~[link TopLeft] that will put the given Coord in view.
  ~param Axis  the information about the axis to check for visibility of the
               cell
  ~param Start the column or row to make visible
  ~result the new scroll position to be used to show the specified cell }
  function CalcMaxCell(const Axis: TGridAxisDrawInfo; Start: Integer): Integer;
  var      Line       :Integer;               //position of edges of the cells
  begin
   Result := Start;                           //show the cell to be shown
   if Result >= Axis.FixedCellCount then      //cells before it?
    begin
     Line := Axis.GridExtent + Axis.EffectiveLineWidth; //get maximum size
     repeat
       Dec(Line, Axis.GetExtent(Result));         //reduce space by cell
       Dec(Line, Axis.EffectiveLineWidth);        //and width of line
       Dec(Result);                               //check the previous cell
     //first cell reached or no more cells fit?
     until (Result < Axis.FixedCellCount) or (Line < Axis.FixedBoundary);

     Inc(Result);                               //decremented one too far
     //last cell does not fit and is not the cell in question?
     if (Line < Axis.FixedBoundary) and (Result <> Start) then
      Inc(Result);                                //scroll one cell farther
    end;
  end;

begin
 //calculate position for both axes
 Result.X := CalcMaxCell(DrawInfo.Horz, Coord.X);
 Result.Y := CalcMaxCell(DrawInfo.Vert, Coord.Y);
end;

{Returns whether the grid is currently active, has the focus. This method will
 also return true if a in-place editor of the content of a cell is currently
 focused.
~result whether the grid is currently focused }
function TGMGrid.IsActiveControl: Boolean;
var      ParentForm     :TCustomForm;       //the form the grid is on
         H              :Hwnd;              //currently focused control
begin
 ParentForm := GetParentForm(Self);         //get form the grid is on
 if Assigned(ParentForm) then                 //is on a (Delphi) form?
  Result := ParentForm.ActiveControl = Self     //return whether active control
 else
  begin
   Result := False;                           //so far not determined as active
   H := GetFocus;                             //get current control
   //while not grid found and control focused or parent window known
   while not Result and IsWindow(H) do
    if H = WindowHandle then                    //is the grid?
     Result := True                               //grid is active!
    else
     H := GetParent(H);                           //try parent of the control
  end;
end;










{Cancels the current mode/state of the grid (selectings cells or moving or
 resizing columns). }
procedure TGMGrid.CancelMode;
begin
 try
   case FGridState of             //check whether in a state to be canceled?
     gsSelecting:                   //currently selecting?
          KillTimer(Handle, 1);       //stop timer to scroll the grid
     gsColSizing:                   //currently resizing a column?
          begin                       //set original size of the column
           ColWidths[FColumns[ExSizingIndex]] := ExSizingOrgSize;
           UpdateDesigner;
          end;
     gsColMoving:                   //currently moving a column?
          begin
           KillTimer(Handle, 1);      //stop timer to scroll the grid
           if ExMoveIndex <> ExOrgMoveIndex then    //column already moved?
            begin
             MoveColumn(ExMoveIndex, ExOrgMoveIndex); //move it back
             UpdateDesigner;
            end;
          end;
   end;
 finally
  FGridState := gsNormal;         //reset the state of the grid
 end;
end;


{Used during painting to temporarily change the orientation of the canvas.
~param RightToLeftOrientation whether the orientation should be set to mirror
                              the left and right sides or whether it should be
                              restored to the original setting }
procedure TGMGrid.ChangeGridOrientation(RightToLeftOrientation: Boolean);
var       Org    :TPoint;   //new origin of the coordinate system of the canvas
          Ext    :TPoint;   //direction of the axis of the coordinate system
begin
 if RightToLeftOrientation then   //canvas should mirror left and right?
  begin
   Org := Point(ClientWidth, 0);    //start x-axis on the right
   Ext := Point(-1,1);              //and it extends to the left
  end
 else
  begin
   Org := Point(0,0);               //start axes at top left corner
   Ext := Point(1,1);               //and extend them to the right lower corner
  end;
 //allow custom mapping of axes
 SetMapMode(Canvas.Handle, mm_Anisotropic);
 //set origin of the coordinate system
 SetWindowOrgEx(Canvas.Handle, Org.X, Org.Y, nil);
 //set size of the canvas
 SetViewportExtEx(Canvas.Handle, ClientWidth, ClientHeight, nil);
 //set direction of the axes
 SetWindowExtEx(Canvas.Handle, Ext.X * ClientWidth, Ext.Y * ClientHeight, nil);
end;

{Changes the number of columns and/or rows of the grid.
~param NewColCount the new number of columns in the grid
~param NewRowCount the new number of rows in the grid }
procedure TGMGrid.ChangeSize(NewColCount, NewRowCount: Integer);
          //information about the view of the grid before changing the number
var       OldDrawInfo       :TGridDrawInfo;                   //of cells
          OldColCount       :Integer;  //previous number of columns in the grid
          OldRowCount       :Integer;  //previous number of rows in the grid

 {Calculates what part of the grid has to be redrawn for a changed axis.
 ~param OldI

⌨️ 快捷键说明

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