Прозрачный цвет в StringGrid

Заполняю ячейки в StringGrid зеленым цветом

procedure TForm1.StringGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin

StringGrid.Canvas.Brush.Color := clGreen;
StringGrid.Canvas.FillRect(Rect);

StringGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, AGrid.Cells[ACol, ARow]);

end;

Мой StringGrid имеет черный цвет. Я хотел бы заполнить ячейку прозрачным цветом (например, 50%).

Как я могу это сделать?

Я должен нарисовать прямоугольник? Или я должен создать растровое изображение и вставить его в ячейку?

Можешь мне помочь?:)

Имейте в виду такой эффект: .png" alt="введите здесь описание изображения">


person Mlody87    schedule 12.10.2016    source источник
comment
Я не понимаю, что у вас есть и что вы хотите сделать....   -  person Arioch 'The    schedule 12.10.2016
comment
Я бы хотел, чтобы цвет ячейки был прозрачным - альфа, что угодно ;)   -  person Mlody87    schedule 12.10.2016
comment
Вы имеете в виду, что хотите частично видеть фон формы/панели или чего-то еще, в которое вставляется сетка?   -  person wp_1233996    schedule 12.10.2016
comment
В конечном итоге фон StringGrid, когда StringGrid.Color:=whatever; а у меня цветная клетка.   -  person Mlody87    schedule 12.10.2016
comment
Взгляните на этот вопрос-ответ. Используйте комбинацию ответов AR и NGLN.   -  person Tom Brunberg    schedule 12.10.2016
comment
Я провел некоторое тестирование и опубликую ответ сегодня позже, но, пожалуйста, скажите мне: какая версия Delphi? Планируете ли вы использовать стили (начиная с XE2)? Поскольку вы также отметили freepascal, я предполагаю, что вы ориентируетесь на Windows (IOW, VCL), а не на мобильные устройства (FMX)?   -  person Tom Brunberg    schedule 14.10.2016
comment
Интересно, почему так сложно ответить на несколько простых вопросов в моем предыдущем комментарии. Я знаю, что с тех пор ты был здесь как минимум дважды. Возможно, вам это больше не интересно.   -  person Tom Brunberg    schedule 14.10.2016


Ответы (1)


Вдохновившись этим постом, я сначала создал TStringGrid с фоновым изображением. . Затем я добавил прозрачный цвет, используя WinApi.Windows.AlphaBlend() для выбранных ячеек и аналогичным образом для фиксированных ячеек. Конечный результат таков:

введите здесь описание изображения

Прозрачный «выбранный» цвет выполнен в виде растрового изображения размером 1 пиксель:

type
  TStringGrid = class(Vcl.Grids.TStringGrid)
  private
    FBackG: TBitmap;
    FForeG: TBitmap;
  ...

procedure TForm5.Button1Click(Sender: TObject);
begin
  sg.FForeG.Free;
  sg.FForeG := TBitmap.Create;
  sg.FForeG.SetSize(1, 1);
  sg.FForeG.PixelFormat := pf32bit;
  sg.FForeG.Canvas.Pixels[0, 0] := $00FF00;  // BGR
end;

И растровое изображение применяется для «выбранных» ячеек (gdSelected in State) в событии OnDrawCell

procedure TForm5.sgDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
var
  sg: TStringGrid;
  r: TRect;
  success:boolean;
begin
  if not (Sender is TStringGrid) then Exit;
  sg := Sender as TStringGrid;

  r := Rect;
  r.Left := r.Left-4; // Might not be needed, depending on Delphi version?

  // Clear the cell
  sg.Canvas.Brush.Color := clBlack;
  sg.Canvas.FillRect(r);

  // Copy background to cell
  BitBlt(sg.Canvas.Handle,
    r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top,
    sg.FBackG.Canvas.Handle, r.Left, r.Top, SRCCOPY);

    // Draw fixed column or row cell(s)
  if gdFixed in State then
  begin
    success := Winapi.Windows.AlphaBlend(sg.Canvas.Handle,
      r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top,
      sg.FHeadG.Canvas.Handle, 0, 0, 1, 23, BlendFunc);
  end;

  // Draw selected cell(s)
  if gdSelected in State then
  begin
    success := Winapi.Windows.AlphaBlend(sg.Canvas.Handle,
      r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top,
      sg.FForeG.Canvas.Handle, 0, 0, 1, 1, BlendFunc);
  end;

  // Draw the text
  r := Rect;
  sg.Canvas.Brush.Style := bsClear;
  DrawText(sg.Canvas.Handle, sg.Cells[ACol, ARow],
    length(sg.Cells[ACol, ARow]), r,
    DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS);
end;

Структура BlendFunc: _BLENDFUNCTION; может быть объявлена ​​в подклассе TStringGrid или где-либо еще, где она доступна, я объявил ее в форме и инициализировал в событии формы OnCreate:

  BlendFunc.BlendOp := AC_SRC_OVER;
  BlendFunc.BlendFlags := 0;
  BlendFunc.SourceConstantAlpha := 128;  // This determines opacity
  BlendFunc.AlphaFormat := AC_SRC_ALPHA;

Теперь вы можете спросить, как получилось, что 1-пиксельное растровое изображение работает, и ответ находится в документация для AlphaBlend():

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

Это полезно, поскольку прямоугольники ячеек обычно различаются по размеру.

Строка и столбец заголовка рисуются аналогичным образом в OnDrawCell при условии if gdFixed in State, и здесь используется другое растровое изображение. Это растровое изображение шириной 1 пиксель и высотой 23 пикселя, которое я сделал отдельно в программе для рисования графики.

введите здесь описание изображения

Да! Крошечная вещь выше — это изображение.

person Tom Brunberg    schedule 14.10.2016