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, пока убрать, также как и прорисовки. Вот что получится: