Howto create same style of tMenuItem with AdvancedDrawItem?

1.2k Views Asked by At

I would like to add a Line with a specific color for each MenuItem of popup menu in Tokyo VCL app. The Style is "Amethyst Kamri".

I'm invoked the AdvancedDrawItem event of each MenuItem as below. However, the hilighted box is flat and has not the same 3d shape as the non-ownerdraw look.

The flat background (in Orange): enter image description here While I would like to get it: enter image description here Howto implement it better? Delphi 10.2, VCL.

procedure TForm1.mnuColorAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect; State: TOwnerDrawState);
var
  MenuItem : tMenuItem;
  LStyles  : TCustomStyleServices;
  LDetails : TThemedElementDetails;
begin
  MenuItem := (Sender as TMenuItem);
  LStyles  := StyleServices;

  ACanvas.Brush.Style := bsClear;

  ACanvas.Font.Color  := LStyles.GetStyleFontColor(sfPopupMenuItemTextNormal);

  //check the state
  if odSelected in State then
    begin
      ACanvas.Brush.Color := LStyles.GetSystemColor(clHighlight);
      ACanvas.Font.Color  := LStyles.GetSystemColor(clHighlightText);
    end;

  ACanvas.FillRect(ARect);
  ARect.Left := ARect.Left + 2;
  //draw the text
  ACanvas.TextOut(ARect.Left + 2, ARect.Top, MenuItem.Caption);

end;

Thanks Reron

1

There are 1 best solutions below

0
On BEST ANSWER

I more or less find a solution. The problem was using Canvas FillRect. Assume three PopUp menu items, Red, Green and Blue. The line color for each of them is stored in each Tag field. Each Menu-line is composed from three elements: A Check mark, a Color line and the Caption. All three items have a common event ColorAdvancedDrawItem.

All Owner draw methods are based on Styles and not on direct Canvas drawing, except the new lines. See code:

procedure TForm1.ColorAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect; State: TOwnerDrawState);
const
  CheckBoxWidth = 20;
  LineLen       = 25;
var
  MenuItem : tMenuItem;
  LStyles  : TCustomStyleServices;
  LDetails : TThemedElementDetails;
  CheckBoxRect, LineRect, TextRect: TRect;
  Y: integer;
begin
  MenuItem := (Sender as TMenuItem);
  LStyles  := StyleServices;

  // Draw Check box
  if MenuItem.Checked then
    begin
      LDetails := StyleServices.GetElementDetails(tmPopupCheckNormal);
      CheckBoxRect := ARect;
      CheckBoxRect.Width := CheckBoxWidth;
      LStyles.DrawElement(ACanvas.Handle, LDetails, CheckBoxRect);
    end;

  // Draw text
  // Check the state
  if odSelected in State then
    LDetails := StyleServices.GetElementDetails(tmPopupItemHot)
  else
    LDetails := StyleServices.GetElementDetails(tmPopupItemNormal);

  TextRect      := ARect;
  TextRect.Left := CheckBoxWidth + LineLen;
  LStyles.DrawText(ACanvas.Handle, LDetails, MenuItem.Caption, TextRect, [tfLeft, tfSingleLine, tfVerticalCenter]);

  // Draw Line
  ACanvas.Pen.Color := tColor(MenuItem.Tag);
  ACanvas.Pen.Width := 2;
  LineRect := ARect;
  LineRect.Left := CheckBoxWidth;
  LineRect.Width:= LineLen;
  Y := LineRect.Top + (LineRect.Height div 2);
  ACanvas.MoveTo(LineRect.Left+2, Y);
  ACanvas.LineTo(LineRect.Left + LineRect.Width - 2, Y);
end;

The results looks like: enter image description here