Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.07.2010, 05:59   #1
megachuhancer
Форумчанин
 
Регистрация: 16.04.2009
Сообщений: 247
По умолчанию Проблемы с рисованием на TStringGrid

Код:
procedure TCell.Draw(Rect: TRect; State: TGridDrawState; Collapsed,
  FieldNames: Boolean; FV: array of Boolean; ACol, ARow: Integer);
var
  i, j, tw, ctop, cs, off, htop, hbottom: Integer;
  s1, s2, str: string;
  r: TRect;
  NeedDrawTriangle: Boolean;
begin
  with FGrid, FGrid.Canvas do begin
    NeedDrawTriangle := False;
    r := Rect;
    if Collapsed then InflateRect(r, 0, 1);
    //----------------------
    Brush.Style := bsSolid;
    if gdSelected in State then Brush.Color := clLtGray
    else Brush.Color := clWhite;
    //----------------------
    Pen.Color := clWhite;
    if Collapsed then Pen.Color := clLtGray;
      Rectangle(r);
    //----------------------
    InflateRect(r, -1, -1);
    //----------------------
    Pen.Color := clLtGray;
    Rectangle(r);
    //----------------------
    if Length(FItems) = 0 then begin
      Brush.Style := bsBDiagonal;
      Brush.Color := clBlack;
      Rectangle(r);
    end;
    Brush.Style := bsSolid;
    Brush.Color := clWhite;
  end;
end;
Тут есть лишние переменные, потому что я не стал сюда вставлять закомменченый код.
Если что, из GridDrawCell вызывается TCell.Draw. В каждом экземпляре TCell есть ссылка на грид.

Собственно, почему при прокрутке возникает такой эффект?




Последний раз редактировалось megachuhancer; 29.07.2010 в 06:01.
megachuhancer вне форума Ответить с цитированием
Старый 29.07.2010, 06:07   #2
Sparkman
220400
Форумчанин
 
Аватар для Sparkman
 
Регистрация: 21.05.2010
Сообщений: 726
По умолчанию

Попробуйте <Имя вашей формы>.DoubleBuffered := true;

ПС: в своем TStringGrid не нашел событие TCell.Draw
Cерьёзной помощи не ждите - помогаю в перерывах на "перекур".
Не существует ничего невозможного для человека, который не собирается ничего делать сам.
Не учите человека, если вы не его учитель.
Sparkman вне форума Ответить с цитированием
Старый 29.07.2010, 06:16   #3
megachuhancer
Форумчанин
 
Регистрация: 16.04.2009
Сообщений: 247
По умолчанию

Цитата:
Попробуйте <Имя вашей формы>.DoubleBuffered := true;
DoubleBuffered уже пробовал - не помогает.
Цитата:
ПС: в своем TStringGrid не нашел событие TCell.Draw
Не, там используется событие OnDrawCell. Просто вызывается соответствующий метод связанного объекта. Вот:
Код:
procedure TfrmSchedule.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  FV: array of Boolean;
  i: Integer;
begin
  SetLength(FV, Length(chksFieldsVisible));
  for i:= 0 to High(FV) do FV[i] := chksFieldsVisible[i].Checked;
  (Grid.Objects[ACol, ARow] as TCustomCell).Draw(Rect, State,
    not chkEmptyLines.Checked and (ecol[ACol] or erow[ARow]),
      chkFieldNames.Checked, FV, ACol, ARow);
end;
Проблема по видимому в том, что в GridDrawCell передаётся прямоугольник, который содержит только видимую на экране часть ячейки (такой же прямоугольник возвращает метод CellRect). Хотя я не уверен. Но если это так, это очень существенно для рисования любых косых линий, потому что угол наклона получается совсем другой. Отсюда "переломанные" линии. Только вот что делать с этим, я не знаю. Не для каждой же ячейки пробегаться по ColWidths и RowHeights чтобы узнать реальный прямоугольник ячейки.

Получается, что GridDrawCell вызывается с такими параметрами, с какими "считает нужным" сам TStringGrid. И при прокрутке по мнению разработчиков этого компонента достаточно перерисовать вновь появившуюся часть ячейки.

Последний раз редактировалось megachuhancer; 29.07.2010 в 06:31.
megachuhancer вне форума Ответить с цитированием
Старый 29.07.2010, 09:47   #4
Sparkman
220400
Форумчанин
 
Аватар для Sparkman
 
Регистрация: 21.05.2010
Сообщений: 726
По умолчанию

Используйте компонент TDrawGrid, а не TStringGrid
помню уже сталкивался с проблемой рисования в StringGrid'е, чего только не пробовал - помогло одно - переход на TDrawGrid
Cерьёзной помощи не ждите - помогаю в перерывах на "перекур".
Не существует ничего невозможного для человека, который не собирается ничего делать сам.
Не учите человека, если вы не его учитель.
Sparkman вне форума Ответить с цитированием
Старый 04.08.2010, 06:37   #5
megachuhancer
Форумчанин
 
Регистрация: 16.04.2009
Сообщений: 247
По умолчанию

Увы, но в TDrawGrid та же проблема, что в общем-то неудивительно, т.к. TStringGrid - наследник TDrawGrid.

Короче, вся проблема упирается в то, как определить координаты всего прямоугольника ячейки, а не только его видимой части.

Последний раз редактировалось megachuhancer; 04.08.2010 в 06:50.
megachuhancer вне форума Ответить с цитированием
Старый 08.02.2011, 11:13   #6
Diablero
Пользователь
 
Регистрация: 31.01.2011
Сообщений: 42
По умолчанию

Попробуйте явным образом определять координаты интересующей вас области. Например, закрашиваем первые 2 ячейки второго столбца таблицы GridClients:

TRect R;
GridClients->Canvas->Brush->Color=clYellow;
R.left=GridClients->ColWidths[0];
R.right=GridClients->ColWidths[0]+GridClients->ColWidths[1];

R.top=0;
R.Bottom=GridClients->RowHeights[0];
GridClients->Canvas->Rectangle(R);

R.Top=GridClients->RowHeights[0];
R.Bottom=GridClients->RowHeights[0]+GridClients->RowHeights[1];
GridClients->Canvas->Rectangle(R);

При прокрутке эффект полос исчезает.

Правда, возникает вопрос, как учесть толщину линий сетки, ибо при таком подходе при закрашивании ряда ячеек, накапливается "сползание" закрашенных областей. Если у вас возникнут какие-то соображения по этому поводу, буду рад услышать
Diablero вне форума Ответить с цитированием
Старый 08.02.2011, 15:45   #7
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
возникает вопрос, как учесть толщину линий сетки
GridLineWidth
Sibedir вне форума Ответить с цитированием
Старый 08.02.2011, 19:57   #8
Diablero
Пользователь
 
Регистрация: 31.01.2011
Сообщений: 42
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
GridLineWidth
То есть ширина i-й ячейки c учётом линий сетки равна StringGrid->ColWidths[i]+GridLineWidth (0.5*GridLineWidth для левой границы ячейки и 0.5*GridLineWidth для правой), и соответственно такой же будет ширина области рисования?
Diablero вне форума Ответить с цитированием
Старый 08.02.2011, 20:04   #9
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Нет. Ширина i-ой ячейки = ColWidths[i]. А GridLineWidth - расстояние м/у ячейками.
Sibedir вне форума Ответить с цитированием
Старый 08.02.2011, 21:40   #10
Diablero
Пользователь
 
Регистрация: 31.01.2011
Сообщений: 42
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
Нет. Ширина i-ой ячейки = ColWidths[i]. А GridLineWidth - расстояние м/у ячейками.
Тогда как правильно переписать мой пример выше, чтобы избежать эффекта смещения области рисования?
Diablero вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с рисованием на Timage Delphi7 Dalagardi Помощь студентам 1 19.04.2010 20:48
Проблема с рисованием на канве в TPaintBox pro100-delphi Помощь студентам 10 09.03.2010 19:41
проблема с рисованием сферы kady Помощь студентам 14 25.01.2010 17:48
Непонятки с рисованием на форме ROD Общие вопросы C/C++ 2 03.02.2009 18:14
Проблема с рисованием прямоугольника Юра. Общие вопросы Delphi 13 04.08.2007 06:08