Copyright © 2010 Promsite. All Rights Reserved.
стр. 4


TStringGrid, часть I

Автор Деймон Чандлер                                                                перевод Виктор Алексеев aka prom

       void __fastcall InsertRow( TStringGrid* StringGrid, int AfterIndex)
       {
         SendMessage(StringGrid->Handle,  WM_SETREDRAW, false, 0);
       try {
         const int row_count =  StringGrid->RowCount;

           // (1) добавить новую строку в конец грида. 
          StringGrid->RowCount = row_count +1;

          // (2) сдвинуть содержимое каждой строки.
            for (int row = row_count;row > AfterIndex + 1; --row)
            {
             StringGrid->Rows[row] =  StringGrid->Rows[row - 1];
            }
          StringGrid->Rows[ AfterIndex + 1]->Clear();
       }
         catch (...) {
          SendMessage(StringGrid->Handle,  WM_SETREDRAW, true, 0);
         }
       SendMessage(StringGrid->Handle, WM_SETREDRAW, true, 0);
       // update (repaint) the shifted rows
       RECT R =    StringGrid->CellRect(0, AfterIndex);
       InflateRect(&R, StringGrid->Width, StringGrid->Height);
         InvalidateRect(StringGrid->Handle, &R, false);
       }

Сообщение WM_SETREDRAW используется для временного предотвращения  прорисовки строка грида самой себя во время манипуляций с её содержимым. После того как  строка была вставлена, InvalidateRect () функция  API используется, чтобы  перекрасить сдвинутые клетки. Аналогичный подход может быть использован, чтобы вставить новый столбец.

Примечание переводчика:

       Хотя вышеприведенный код для вставки строки предусмотрел исключительную ситуацию и перерисовку грида, но с методической точки зрения восприятие кода сильно затруднено. Честно говоря, если бы не комментарии, то я бы долго разбирался, зачем нужны здесь хэндлы. Поэтому хочу изложить всё сказанное в несколько другой интерпретации.

    Первое, что нужно сказать, что хотя тема и называется вставка строки, но на самом деле никакая строка никуда и не вставляется. Собака зарыта в методе CLear(). Т.е. сначала добавляется новая пустая строка в конец грида, затем содержимое строк после нужной нам строки сдвигается на одну позицию вниз. И вот здесь внимание: если бы не было метода Clear(), то мы вставку просто бы не заметили. Попробуйте заремить этот метод - тогда всё будет очевидно. Можно сказать ловкость рук и никакого обмана.

    С методической точки зрения лучше код разбить на 2 функции соответствующие шагу1 и шагу2. Естественно для наглядности при создании формы грид надо чем-нибудь заполнить. Кроме того,  для экспериментов, ввод индекса строки, после которой надо "вставлять" новую строку, лучше вынести на форму в виде контрола TEdit. "Лишний" код, типа try, пока убрать, также как и прорисовки. Вот что получится:


       // (Шаг1) добавить строку в конец грида.
       void __fastcall TForm1::Button1Click(TObject *Sender)
       {
       const int row_count =  StringGrid1->RowCount;
         StringGrid1->RowCount = row_count +1;
       }
       //---------------------------------------------------------------------------
       // (Шаг2) Сдвинуть строки вниз и очистить "вставленную" строку.
       void __fastcall TForm1::Button2Click(TObject *Sender)
       {
             int row_count = StringGrid1-> RowCount;
             for (int row = row_count;row > StrToInt(AfterIndex -> Text ) +1 ; --row)
                   StringGrid1->Rows[row] =  StringGrid1->Rows[row - 1];
                    StringGrid1->Rows[ StrToInt(AfterIndex -> Text ) + 1]->Clear();
       }

стр. 4
P  R  O  M  S  I  T  E
Статьи по С++Builder 6
страницы: 1   2   3   4   5   6   7   8
страницы: 1   2   3   4   5   6   7   8

Для отображения Облака ссылок
необходим
Adobe Flash Player 9
или выше.