How to find the actual width of grid component with scrollbar in Delphi

前端 未结 4 425
我寻月下人不归
我寻月下人不归 2020-12-20 03:46

I have a grid component (DBGrid) which has lots of columns on it. Because of large number of columns, a scrollbar was created, and thus some part of grid remains hidden. I n

相关标签:
4条回答
  • 2020-12-20 04:07

    I think I have found a solution (although it seems a little strange). In order to find the difference between column widths and real width of the DBgrid (that means find the width of the empty space left after last column), we need to keep track of which column is shown on the left now (what is current column that is scrolled to). We can do that using OnDrawColumnCell event, since it will draw only columns which are scrolled on now. Then we need to calculate sum of widths of all visible columns, and subtract that from DBGrid's width. P.S. Sorry for bad english

    Ex code:

         For i:=0 to Last do
         if Vis[i] then
         Begin
          Sum:=Sum+DBG.Columns[i].Width;
          Inc(Cnt);
         End;
    
         if dgColLines in DBG.Options then
         Sum := Sum + Cnt;
    
      //add indicator column width
        if dgIndicator in DBG.Options then
        Sum := Sum + IndicatorWidth;
        Dif:=DBG.ClientWidth - Sum;
    
    0 讨论(0)
  • 2020-12-20 04:07

    Here are functions we have used in the past. It takes into account the width of data based on the font and also compensates for vertical lines if they are visible

    function GridTextWidth(fntFont : TFont; const sString : OpenString) :
      integer;
    var
      f: TForm;
    begin
      try
        f:=TForm.Create(nil);
        f.Font:=fntFont;
        result:=f.canvas.textwidth(sstring);
      finally
        f.Free;
        end;
    end;
    
    
    
    
    function CalcGridWidth(dbg : TDBGrid { the grid to meaure }): integer; { the "exact" width }
    const cMEASURE_CHAR   = '0';
          iEXTRA_COL_PIX  = 4;
          iINDICATOR_WIDE = 11;
    var i, iColumns, iColWidth, iTitleWidth, iCharWidth : integer;
    begin
      iColumns := 0;
      result   := GetSystemMetrics(SM_CXVSCROLL);
    
      iCharWidth := GridTextWidth(dbg.font,cMeasure_char);
    
      with dbg.dataSource.dataSet do begin
        DisableControls;
        for i := 0 to FieldCount - 1 do with Fields[i] do
          if visible then
          begin
            iColWidth := iCharWidth * DisplayWidth;
            if dgTitles in dbg.Options then begin
              ititlewidth:=GridTextWidth(dbg.titlefont,displaylabel);
              if iColWidth < iTitleWidth then
                iColWidth := iTitleWidth;
            end;
            inc(iColumns, 1);
            inc(result, iColWidth + iEXTRA_COL_PIX);
          end;
          EnableControls;
        end;
    
      if dgIndicator in dbg.Options then
      begin
        inc(iColumns, 1);
        inc(result, iINDICATOR_WIDE);
      end;
      if dgColLines in dbg.Options then
        inc(result, iColumns)
      else
        inc(result, 1);
    end;
    
    0 讨论(0)
  • 2020-12-20 04:17

    Perhaps this may be helpful. It is part of a class helper for TDBGrid that auto sizes the last column, so that the grid has no empty space. Should be easy to adjust to your needs.

    As you may notice, the CalcDrawInfo method is what you are seeking for. As it is protected you can either use a class helper or the usual protected-hack to get hands on it.

    procedure TDbGridHelper.AutoSizeLastColumn;
    var
      DrawInfo: TGridDrawInfo;
      ColNo: Integer;
    begin
      ColNo := ColCount - 1;
      CalcDrawInfo(DrawInfo);
      if (DrawInfo.Horz.LastFullVisibleCell < ColNo - 1) then Exit;
    
      if (DrawInfo.Horz.LastFullVisibleCell < ColNo) then
        ColWidths[ColNo] := DrawInfo.Horz.GridBoundary - DrawInfo.Horz.FullVisBoundary
      else
        ColWidths[ColNo] := ColWidths[ColNo] + DrawInfo.Horz.GridExtent - DrawInfo.Horz.FullVisBoundary
    end;
    
    0 讨论(0)
  • 2020-12-20 04:17

    TDBGrid has a Columns property. Each of the columns has its own Width property. So you could loop through all of the columns and sum up their widths.

    Like this:

    function TotalColumnsWidth(var AGrid: TDBGrid);
    var
      i: Integer;
    begin
      Result := 0;
      for i := to AGrid.Columns.Count - 1 do
        Result := Result + AGrid.Columns[i].Width;
    end;
    
    0 讨论(0)
提交回复
热议问题