Конференция "Компоненты" » Многострочные заголовки в DBGrid [D7, WinXP]
 
  • _newman_ (04.03.07 15:43) [0]
    Написал компонент (наследник от TCustomDBGrid) с многострочными заголовками. Все вроде бы устраивает, но когда в заголвке меняется количество строк "сетка" не пересчитывает видимую область (имхо). В результате есть кол-во строк заголовка увеличилось, то последнии записи ушли вниз и когда пробегаешь курсом, то в конце-концов он скрывается за границей "сетки".

    +-------------------------+ - видимая область
    | Загаловок               |
    +-------------------------+
    | > 1 строка              |
    |   2 строка              |
    |   3 строка              |
    |   4 строка              |
    |   5 строка              |
    |   6 строка              |
    |   7 строка              |
    +-------------------------+ - видимая область

    кол-во срок загаловка увеличилось
    +-------------------------+ - видимая область
    | Много                   |
    |   строчный              | - скролируемая область
    | Загаловок               | - курсор поднимается вверх,
    +-------------------------+   под заголовок и его не видно
    |   1 строка              |
    |   2 строка              |
    |   3 строка              |
    |   4 строка              |
    |   5 строка              | - скролируемая область
    +-------------------------+ - видимая область
    | > 6 строка              | - курсор спускается вниз и его не видно
    |   7 строка              |
    +-------------------------+ - невидимая область

    кол-во строк уменьшилось
    +-------------------------+ - видимая область
    | Загаловок               |
    +-------------------------+
    | > 1 строка              | - сролируемая область
    |   2 строка              |
    |   3 строка              |
    |   4 строка              |
    |   5 строка              | - скролируемая область
    |                         | - остаются пустые строки
    |                         |
    +-------------------------+ - видимая область

    Как поправить это?
  • _newman_ (04.03.07 15:44) [1]
    Исходники компонента:
    //---------------------------------------------------------------------------

    #ifndef NovexDBGridH
    #define NovexDBGridH
    //---------------------------------------------------------------------------
    #include <SysUtils.hpp>
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <DBGrids.hpp>
    #include <Grids.hpp>
    //---------------------------------------------------------------------------
    class PACKAGE TNovexDBGrid : public TCustomDBGrid
    {
      typedef TCustomDBGrid inherited;

    public:
    __property Canvas ;
    __property SelectedRows ;

    __published:
      __property int Margin_Top = {default = 2, read = FMargin_Top, write = FMargin_Top}
    ;
      __property int Margin_Left = {default = 4, read = FMargin_Left, write = FMargin_Left};
      __property int Margin_Right = {default = 4, read = FMargin_Right, write = FMargin_Right};
      __property int Margin_Bottom = {default = 2, read = FMargin_Bottom, write = FMargin_Bottom};

    __property Align  = {default=0};
    __property Anchors  = {default=3};
    __property BorderStyle  = {default=1};
    __property Color  = {default=-10};
    __property Columns  = {stored=false};
    __property Constraints ;
    __property DataSource ;
    __property DefaultDrawing  = {default=1};
    __property DragMode  = {default=0};
    __property Enabled  = {default=1};
    __property FixedColor  = {default=-2};
    __property Font ;
    __property Options  = {default=3325};
    __property ParentColor  = {default=0};
    __property ParentFont  = {default=1};
    __property ParentShowHint  = {default=1};
    __property PopupMenu ;
    __property ReadOnly  = {default=0};
    __property ShowHint ;
    __property TabOrder  = {default=-1};
    __property TabStop  = {default=1};
    __property TitleFont ;
    __property Visible  = {default=1};
    __property OnCellClick ;
    __property OnColEnter ;
    __property OnColExit ;
    __property OnColumnMoved ;
    __property OnDrawDataCell ;
    __property OnDrawColumnCell ;
    __property OnDblClick ;
    __property OnDragDrop ;
    __property OnDragOver ;
    __property OnEditButtonClick ;
    __property OnEndDrag ;
    __property OnEnter ;
    __property OnExit ;
    __property OnKeyDown ;
    __property OnKeyPress ;
    __property OnKeyUp ;
    __property OnMouseDown ;
    __property OnMouseMove ;
    __property OnMouseUp ;
    __property OnStartDrag ;
    __property OnTitleClick ;

    private:
      int m_nTitleHeight;    
      int m_nTitleRow;        
      int FMargin_Top;
      int FMargin_Left;
      int FMargin_Right;
      int FMargin_Bottom;

    protected:
      void __fastcall CalcTitleCellHeight (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState);
      void __fastcall DrawTitleCell (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState);
      int __fastcall HeightTitleCell (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState);

      virtual void __fastcall DrawCell(int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState);

    public:
      __fastcall TNovexDBGrid(TComponent* Owner);
    __published:
    };
    //---------------------------------------------------------------------------
    #endif

  • _newman_ (04.03.07 15:44) [2]
    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop

    #include "NovexDBGrid.h"    
    #pragma package(smart_init)    
    //---------------------------------------------------------------------------

    static inline void ValidCtrCheck(TNovexDBGrid *)
    {
      new TNovexDBGrid(NULL);
    }

    //---------------------------------------------------------------------------
    __fastcall TNovexDBGrid::TNovexDBGrid(TComponent* Owner)
      : TCustomDBGrid(Owner)
    {
    }

    //---------------------------------------------------------------------------
    namespace Novexdbgrid
    {
      void __fastcall PACKAGE Register()
      {
          TComponentClass classes[1] = {__classid(TNovexDBGrid)}
    ;
          RegisterComponents("Novex", classes, 0);
      }
    }
    //---------------------------------------------------------------------------

    //---------------------------------------------------------------------------
    int __fastcall TNovexDBGrid::HeightTitleCell (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState)
    {
      int nHeight = 1;
      int nLastSpaceChar = -1;

      AnsiString sText = "";
      AnsiString sCurrText = "";

      Canvas->Font = TitleFont;

      sText = Columns->Items[ACol]->Title->Caption;
      int nCellWidth = Columns->Items[ACol]->Width - Margin_Left - Margin_Right; // left & right margins

      int nTextLen = sText.Length();
      int i = 1;  
      int nWidth;

      while (i <= nTextLen)
      {
         if (sText[i] == ' ')
         {
            nLastSpaceChar = i;
         }


         sCurrText += sText[i];
         nWidth = Canvas->TextWidth (sCurrText);// + D_LEFT + D_RIGHT; // Left & Right margins

         if (nWidth > nCellWidth)
         {
            if (sCurrText.Length() > 1)
            {
               if (nLastSpaceChar < 0)
               {
                  i--;
               }

               else
               {
                  i = nLastSpaceChar;
                  nLastSpaceChar = -1;
               }

            }

            nHeight++;
            sCurrText = "";
         }

         i++;
      }

      if (sCurrText.IsEmpty() && nHeight > 1)
         nHeight--;
         
      return nHeight;
    }
    //---------------------------------------------------------------------------

    //---------------------------------------------------------------------------
    void __fastcall TNovexDBGrid::CalcTitleCellHeight (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState)
    {
      int nMinHeight = 1;
      int nCurrHeight = 1;
      int nColumnCount = Columns->Count;
      int nStart = 0;

      for (int i = nStart; i < nColumnCount; i++)
      {
         nCurrHeight = HeightTitleCell (i, 0, ARect, AState);

         if (nCurrHeight > nMinHeight)
            nMinHeight = nCurrHeight;
      }


      Canvas->Font = TitleFont;

      m_nTitleHeight = (Canvas->TextHeight("gW") + Margin_Top) * nMinHeight + Margin_Bottom;
      RowHeights[0] = m_nTitleHeight;
      m_nTitleRow = nMinHeight;
    }
    //---------------------------------------------------------------------------

    //---------------------------------------------------------------------------
    void __fastcall TNovexDBGrid::DrawTitleCell (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState)
    {
      int nDataCol = ACol;

      if (Options.Contains(dgIndicator))
         nDataCol--;

      int nCellHeight = m_nTitleHeight;
      int nCellWidth = Columns->Items[nDataCol]->Width - Margin_Left - Margin_Right; // left & right margins
      int nCellRowCount = HeightTitleCell (nDataCol, ARow, ARect, AState);

      Canvas->Font = TitleFont;

      int nCharHeight = Canvas->TextHeight("gW");
      int nTextHeight = (nCharHeight + Margin_Top) * nCellRowCount + Margin_Bottom;
      int nDHeight = (nCellHeight - nTextHeight) / 2;

      int nHeight = 1;
      int nLastSpaceChar = -1;

      AnsiString sText = "";
      AnsiString sCurrText = "";

      Canvas->Font = TitleFont;

      sText = Columns->Items[nDataCol]->Title->Caption;

      int nTextLen = sText.Length();
      int i = 1;  // 0
      int nWidth;
      RECT TextRect;

      TextRect.left = ARect.left + Margin_Left;
      TextRect.top = ARect.top + Margin_Top + nDHeight;
      TextRect.right = ARect.right - Margin_Right;
      TextRect.bottom = ARect.bottom;//- D_BOTTOM;

      Canvas->Brush->Color = FixedColor;
      Canvas->FillRect(ARect);
     
      int nDelPos = -1;

      while (i <= nTextLen)
      {
         sCurrText += sText[i];

         if (sText[i] == ' ')
         {
            nLastSpaceChar = i;
            nDelPos = sCurrText.Length();
         }


         nWidth = Canvas->TextWidth (sCurrText);// + D_LEFT + D_RIGHT; // Left & Right margins

         if (nWidth > nCellWidth)
         {
            Canvas->Brush->Color = FixedColor;
            Canvas->Font = TitleFont;

            if (sCurrText.Length() > 1)
            {
               if (nLastSpaceChar >= 0)
               {
                  int nDelCount = sCurrText.Length() - nDelPos + 1;

                  sCurrText.Delete(nDelPos, nDelCount);
                  i = nLastSpaceChar;
                  nLastSpaceChar = -1;
                  nDelPos = -1;
               }

               else
               {
                  i--;
                  sCurrText.Delete(sCurrText.Length(),1);
               }

            }

            DrawText (Canvas->Handle, sCurrText.c_str(), sCurrText.Length(), &TextRect, DT_CENTER);
            TextRect.top += (nCharHeight + Margin_Top);

            nHeight++;
            sCurrText = "";
         }

         i++;
      }

      if (!sCurrText.IsEmpty())
      {
         Canvas->Brush->Color = FixedColor;
         Canvas->Font = TitleFont;
         DrawText (Canvas->Handle, sCurrText.c_str(), sCurrText.Length(), &TextRect, DT_CENTER);
      }


      RECT EdgeRect;

      EdgeRect.left = ARect.left;
      EdgeRect.top = ARect.top;
      EdgeRect.right = ARect.right;
      EdgeRect.bottom = ARect.bottom;

      DrawEdge (Canvas->Handle, &EdgeRect, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
      DrawEdge (Canvas->Handle, &EdgeRect, BDR_RAISEDINNER, BF_TOPLEFT);
    }
    //---------------------------------------------------------------------------

    //---------------------------------------------------------------------------
    void __fastcall TNovexDBGrid::DrawCell(int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState)
    {
      if (Options.Contains (dgTitles) && ACol == 0 && ARow == 0)
      {
         CalcTitleCellHeight (ACol, ARow, ARect, AState);
      }


      if (Options.Contains(dgIndicator) && ACol == 0)
      {
         TCustomDBGrid::DrawCell (ACol, ARow, ARect, AState);
         return;
      }


      if (Options.Contains (dgTitles) && ARow == 0)
      {
         DrawTitleCell (ACol, ARow, ARect, AState);
         return;
      }

      TCustomDBGrid::DrawCell (ACol, ARow, ARect, AState);
    }

 
Конференция "Компоненты" » Многострочные заголовки в DBGrid [D7, WinXP]
Есть новые Нет новых   [134427   +38][b:0][p:0.007]