如何使用 Advanced DrawItem 创建相同样式的 tMenuItem?
Howto create same style of tMenuItem with AdvancedDrawItem?
我想为 Tokyo VCL 应用程序中弹出菜单的每个 MenuItem 添加一条具有特定颜色的线。样式是 "Amethyst Kamri".
我调用了每个 MenuItem 的 AdvancedDrawItem 事件,如下所示。但是,高亮框是扁平的,并且与非 ownerdraw 外观的 3d 形状不同。
平面背景(橙色):
虽然我想得到它:
如何更好地实施? Delphi10.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;
谢谢
雷伦
我或多或少找到了解决办法。问题是使用 Canvas FillRect。
假设有三个 PopUp 菜单项,红色、绿色和蓝色。它们各自的线条颜色存储在每个标签字段中。每个 Menu-line 由三个元素组成:复选标记、颜色线和标题。
所有三个项目都有一个共同的事件 ColorAdvancedDrawItem。
所有 Owner 绘图方法都基于样式而不是直接 Canvas 绘图,新线条除外。见代码:
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;
我想为 Tokyo VCL 应用程序中弹出菜单的每个 MenuItem 添加一条具有特定颜色的线。样式是 "Amethyst Kamri".
我调用了每个 MenuItem 的 AdvancedDrawItem 事件,如下所示。但是,高亮框是扁平的,并且与非 ownerdraw 外观的 3d 形状不同。
平面背景(橙色):
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;
谢谢 雷伦
我或多或少找到了解决办法。问题是使用 Canvas FillRect。 假设有三个 PopUp 菜单项,红色、绿色和蓝色。它们各自的线条颜色存储在每个标签字段中。每个 Menu-line 由三个元素组成:复选标记、颜色线和标题。 所有三个项目都有一个共同的事件 ColorAdvancedDrawItem。
所有 Owner 绘图方法都基于样式而不是直接 Canvas 绘图,新线条除外。见代码:
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;