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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.04.2025, 19:10   #1
Nester
Форумчанин
 
Аватар для Nester
 
Регистрация: 22.10.2008
Сообщений: 127
По умолчанию Проблема с выбором цвета ячейки StringGrid

На форме StringGrid
Отрисовка ячеек пользовательская.
Задача состоит в том что бы в ячейке рисовать прямоугольник нужного мне цвета.
Выбор цвета осуществляется по клику на этой ячейке (ColorDialog).
Всё работает как нужно кроме случая когда выбран чёрный цвет.
Выбор этого цвета игнорируется.

Код:
 //Пользовательская отрисовка ячеек StringGrid
 Procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);
  Var Grid: TStringGrid;
      CellRect: TRect;
      BrushColor: TColor;
  Begin
   Grid := Sender as TStringGrid;
   CellRect := Rect;
   Inc(CellRect.Left);   // Небольшие отступы для красоты
   Inc(CellRect.Top);
   Dec(CellRect.Right);
   Dec(CellRect.Bottom);

   // Получение цвета ячейки из Tags (по умолчанию clWhite)
   If Grid.Objects[ACol, ARow] <> nil Then
    BrushColor := TColor(Grid.Objects[ACol, ARow])
   Else
    BrushColor := clWhite;

  // Рисуем прямоугольник
  With Grid.Canvas Do
   Begin
    Brush.Color := BrushColor;
    FillRect(CellRect);
   End;

 End;

 //Обработка пользовательских кликов мышью на StringGrid
 Procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  Var Grid: TStringGrid;
      ACol, ARow: Integer;
      NewColor: TColor;
  Begin
   Grid := Sender as TStringGrid;
   Grid.MouseToCell(X, Y, ACol, ARow);

   If (ACol >= 0) and (ARow >= 0) Then
    Begin
     // Открываем диалог выбора цвета
     If ColorDialog1.Execute Then
      Begin
       NewColor := ColorDialog1.Color;
       // Сохраняем цвет в Objects
       Grid.Objects[ACol, ARow] := Pointer(NewColor);
       // Перерисовываем сетку
       Grid.Invalidate;
      End;
    End;
  End;

Вероятно проблема тут при NewColor=0

Код:
 Grid.Objects[ACol, ARow] := Pointer(NewColor);
Color 0 записывается как nil

как победить?
Никто не знает больше чем не знаю я

Последний раз редактировалось Nester; 06.04.2025 в 19:18.
Nester вне форума Ответить с цитированием
Старый 06.04.2025, 20:48   #2
cllc
Пользователь
 
Регистрация: 17.01.2020
Сообщений: 14
По умолчанию

Ксорить знаковый бит:
Код:
Grid.Objects[ACol, ARow] := Pointer(Cardinal(NewColor) xor $80000000);
Код:
BrushColor := TColor(Cardinal(Grid.Objects[ACol, ARow]) xor $80000000)
cllc вне форума Ответить с цитированием
Старый 07.04.2025, 06:35   #3
Nester
Форумчанин
 
Аватар для Nester
 
Регистрация: 22.10.2008
Сообщений: 127
По умолчанию

Цитата:
Сообщение от cllc Посмотреть сообщение
Ксорить знаковый бит:
Код:
Grid.Objects[ACol, ARow] := Pointer(Cardinal(NewColor) xor $80000000);
Код:
BrushColor := TColor(Cardinal(Grid.Objects[ACol, ARow]) xor $80000000)
Жму руку за такое решение! Проблема решена!!!
Никто не знает больше чем не знаю я
Nester вне форума Ответить с цитированием
Старый 07.04.2025, 13:44   #4
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Почему бы просто не убрать условие:
Код:
If Grid.Objects[ACol, ARow] <> nil Then
    BrushColor := TColor(Grid.Objects[ACol, ARow]) // 2 строка
   Else
    BrushColor := clWhite;
здесь срабатывает проверка на нил и по ветке элс ставится белый цвет, вот и оставить только 2ю строку из всего этого кода

EDIT: все клетки на старте тогда будут черные, я полагаю? тогда для черного или для всех цветов вообще действительно можно использовать старший байт Int32, поскольку в Tag хранится 4хбайтное значение Int32 а TColor занимает 3 байта (RGB), но, по идее, не обязательно использовать XOR (хотя удобно в целом), а можно любую операцию, и SHL/SHR и банально +/- 10Е9,
или вообще просто сделать вот такой код (который использует идею с заменой кода выше только на строку 2)
Код:
if NewColor = clBlack then NewColor := TColor(1); // на глаз ровно такой же черный
Grid.Objects[ACol, ARow] := Pointer(NewColor);

Последний раз редактировалось phomm; 07.04.2025 в 13:59.
phomm вне форума Ответить с цитированием
Старый 08.04.2025, 19:06   #5
Nester
Форумчанин
 
Аватар для Nester
 
Регистрация: 22.10.2008
Сообщений: 127
По умолчанию

Немного подумав сделал так:

Код:
Grid.Objects [ ACol, ARow ] := Pointer( Cardinal ( NewColor+1 ) );

BrushColor := TColor ( Cardinal ( Grid.Objects [ ACol, ARow ] ) ) -1;
Никто не знает больше чем не знаю я
Nester вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
определение цвета ячейки в RGB Bape}l{ka Microsoft Office Excel 3 26.01.2012 23:29
два цвета в одной ячейки terakorn HTML и CSS 10 22.06.2009 16:05
If в зависимости от цвета ячейки tae1980 Microsoft Office Excel 2 16.03.2009 16:19
проблема с выбором значения ячейки ssh Общие вопросы .NET 0 17.01.2009 00:17
Как раскрасить ячейки StringGrid'а в разные цвета в соответствии с условием? monushka Компоненты Delphi 12 05.11.2007 23:44