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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 18.03.2010, 17:13   #1
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию Веделение ячеек StringGrid'a или DrawGrid'a

Приветствую всех.

Подскажите пожалуйста, как реализовать мою задумку. У меня в программе в цикле проверяются все ячейки StringGrid'a (можно заменить DrawGrid) и в зависимости от определённого условия нужно их закрашивать (Поменять цвет текста или цвет ячейки, вообщем как то их выделить). Условие я приводить не буду, потому что я его ещё четко не сформулировал и от него ничего не зависит.

Вот что я нашол:

Код:
procedure TfrmMain.sgShowDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  with sgShow do
  begin
    if (gdSelected in State) then
    Canvas.Brush.Color := $00EFD3C6;
    Canvas.FillRect(Rect);
    if Length(Cells[ACol, ARow]) > 0 then
    begin
      Canvas.Font.Color := clBlack;
      Canvas.TextOut(Rect.Left, Rect.Top, Cells[ACol, ARow]);
    end;
  end;
end;
Теперь не знаю как засунуть это в цикл и как указывать какую ячейку выделять.

Или вот:
Код:
procedure TForm1.ColorBox1Change(Sender: TObject);
begin
x:=ColorBox1.Selected;
end;

procedure TForm1.DrawGrid2DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if gdFocused in State then
with (Sender as TDrawGrid).Canvas do
begin
Brush.Color := x;
FillRect(Rect)
end
else
begin
with (Sender as TDrawGrid).Canvas do
begin
Brush.Color:=x;
FillRect(Rect);
end;
end;
end;
И как можно потом будет к этим закрашенным ячейкам обращаться, нужно что-то вроде

if Ячейка закрашена then ..
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 18.03.2010, 18:28   #2
spamer
Software Developer
Старожил
 
Аватар для spamer
 
Регистрация: 19.12.2008
Сообщений: 2,070
По умолчанию

Ну вот самое первое, что пришло в голову:
Код:
var
  mas : array[0..2,0..2] of Integer;
  i,j : Integer;

...

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  with StringGrid1 do
  begin
    if Cells[ACol, ARow] = '15' then
      begin
        Canvas.Brush.Color := clRed;
        Canvas.FillRect(Rect);
        mas[ACol, ARow] := 1;
      end;
    if Length(Cells[ACol, ARow]) > 0 then
    begin
      Canvas.Font.Color := clBlack;
      Canvas.TextOut(Rect.Left+2, Rect.Top, Cells[ACol, ARow]);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
for i := 0 to 2 do
begin
  for j := 0 to 2 do
  if mas[i,j] = 1 then
    Caption := 'Закрашенная ячейка с индексами ' + IntToStr(i+1) + IntToStr(j+1);
end;
end;
Будь проще и люди к тебе потянутся
spamer вне форума Ответить с цитированием
Старый 18.03.2010, 18:38   #3
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию

spamer, спасибо большое, но как этот код засунуть в цикл. У меня в цикле проверяется:

Код:
procedure TfrmMain.btnScanClick(Sender: TObject);
var
  I, J, K: integer;
  boolVNot: boolean;
begin
  for I := 1 to 8 do
  begin
    boolVNot := true;
    for J := 1 to 8 do
    begin
      if sgShow.Cells[6, I] = frmInput.arFunctionParts[J] then
        boolVNot := false;
    end;
    if boolVNot = true then
    begin
      for K := 0 to 7 do
        sgShow.Cells[K, I] := 'Not';
    end;
  end;
end;
Вместо := 'Not' хочу закрасить строку
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 18.03.2010, 19:34   #4
Karabash
Форумчанин
 
Регистрация: 26.07.2009
Сообщений: 216
По умолчанию

В StringGrid помимо метода Cells есть метод Objects, в котором можно хранить признак закраски ячейки.
Код:
    //запись признака:
    for I := 1 to SG.RowCount - 1 do begin
      if <условие закраски> then   
        SG.Objects[1, I] := TObject(1)  //устанавливается признак - просто пишем "1" в ячеечный объект
      else                                            
        SG.Objects[1, I] := TObject(0); //или 0, если условие False
    end;

    //чтение признака:
      if Integer(SG.Objects[ACol, ARow]) = 1 then
        SG.Canvas.Font.Color := clRed
      else
        SG.Canvas.Font.Color := clBlack;
Karabash вне форума Ответить с цитированием
Старый 18.03.2010, 19:59   #5
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию

Karabash, спасибо за подсказку, но не пойму, почему не работает:

Код:
procedure TfrmMain.Button1Click(Sender: TObject);
var
  I: integer;
  ACol, ARow: integer;
begin
  ACol := 1;
  ARow := 1;
  for I := 1 to sgShow.RowCount - 1 do
  begin
    if  I mod 2 <> 0 then // написал для проверки только
      sgShow.Objects[1, I] := TObject(1)  //устанавливается признак - просто пишем "1" в ячеечный объект
    else
      sgShow.Objects[1, I] := TObject(0); //или 0, если условие False
  end;

  //чтение признака:
  if Integer(sgShow.Objects[ACol, ARow]) = 1 then
    sgShow.Canvas.Font.Color := clRed
  else
    sgShow.Canvas.Font.Color := clBlack;
end;
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 18.03.2010, 20:08   #6
Karabash
Форумчанин
 
Регистрация: 26.07.2009
Сообщений: 216
По умолчанию

Да, но читать признак надо уже в другом месте. Там где происходит прорисовка ячеек. Зачем в этой процедуре нужна проверка?
Код:
if Integer(sgShow.Objects[ACol, ARow]) = 1 then
Karabash вне форума Ответить с цитированием
Старый 18.03.2010, 20:19   #7
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию

Karabash, имелось в виду что я такое условие задал только чтоб проверить как работает, потому что необходимое мне условие пока не могу задать, эту проблему я в соседней теме изложил.

Значит вот это мне нужно засунуть в прорисовку, т.е. так:

Код:
procedure TfrmMain.sgShowDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if Integer(sgShow.Objects[ACol, ARow]) = 1 then
      sgShow.Canvas.Font.Color := clRed
  else
    sgShow.Canvas.Font.Color := clBlack;
end;
Тогда как потом эту процедуру вызывать? Т.е. :
Код:
for I := 1 to SG.RowCount - 1 do begin
      if <условие закраски> then   
        SG.Objects[1, I] := TObject(1)  //устанавливается признак - просто пишем "1" в ячеечный объект
      else                                            
        SG.Objects[1, I] := TObject(0); //или 0, если условие False
    end;
    Вызываем перерисовку
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 18.03.2010, 20:47   #8
Karabash
Форумчанин
 
Регистрация: 26.07.2009
Сообщений: 216
По умолчанию

Ее не потом надо вызывать, а вначале (как сказать ГДЕ, если неизвестна логика программы; скорее в том месте, где становятся известны условия, по которым ячейки будут закрашиваться по разному).
Т.е. прежде "зарядить" признаком закраски те ячейки, которые будут ПОТОМ закрашиваться иначе, чем остальные.

И прорисовку специально "вызывать" не надо - sgShowDrawCell будет вызваться Windows автоматически тогда когда ей это требуется. Можно, конечно, при изменении признаков закрашивания вызывать sgShow.Invalidate.

Последний раз редактировалось Karabash; 18.03.2010 в 20:50.
Karabash вне форума Ответить с цитированием
Старый 18.03.2010, 20:58   #9
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию

Karabash, вот условие закрашивания:

Код:
procedure TfrmMain.btnScanClick(Sender: TObject);
var
  I, J, K: integer;
  boolVNot: boolean; 
begin
  for I := 1 to 8 do
  begin
    boolVNot := true;
    { Делаю для всей строки 0 }
    for K := 0 to 6 do
      sgShow.Objects[K, I] := TObject(0);
    for J := 1 to 8 do
    begin
      if sgShow.Cells[6, I] = frmInput.arFunctionParts[J] then
        boolVNot := false;
    end;
    { Закрашиваю нужную строку }
    if boolVNot = true then
      begin
        for K := 0 to 6 do
          sgShow.Objects[K, I] := TObject(1);
      end;
  end;

  А как теперь вызвать перерисовку?
end;

procedure TfrmMain.sgShowDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if Integer(sgShow.Objects[ACol, ARow]) = 1 then
      sgShow.Canvas.Font.Color := clRed
  else
    sgShow.Canvas.Font.Color := clBlack;
end;
Остаётся только выяснить, как вызывать перерисовку
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 18.03.2010, 21:11   #10
Karabash
Форумчанин
 
Регистрация: 26.07.2009
Сообщений: 216
По умолчанию

Вы "привязали" событие OnDrawCell к своей таблице, установили свойство таблицы DefaultDrawing в False. Теперь отрисовку всей таблицы необходимо делать "своими руками". Примитивно примерно так:
Код:
procedure TfrmMain.sgShowDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if Integer(sgShow.Objects[ACol, ARow]) = 1 then
     sgShow.Canvas.Brush.Color := clRed
  else
    sgShow.Canvas.Brush.Color := clWhite;
  sgShow.Canvas.FillRect(Rect);

  sgShow.Canvas.TextOut(Rect.Left, Rect.Top, sgShow.Cells[ACol, ARow]);
end;
Повторяю, этот обработчик события (OnDrawCell) Windows вызывает автоматом при условии, что свойство DefaultDrawing установлено в False; усилия к его вызову прилагать не надо.
-----------
Об этом сказано в тысячах форумах.
Karabash вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
из stringgrid'a в sql server kate158 БД в Delphi 3 02.07.2012 09:25
Таблицы в WORD. Перебор ячеек или поиск? sergeos Microsoft Office Word 7 09.06.2009 17:57
Два StringGrid'a ARXangel Общие вопросы Delphi 2 26.05.2009 12:55
как сцепить несколько ячеек чтобы сохранилось выделение цветом или жирным шрифтом gribkow Microsoft Office Excel 7 23.04.2008 09:27