Psh*_*mas 5 delphi vcl delphi-10.4-sydney
我正在尝试制作自己的组件,其主题与应用程序的其余部分相同(主题在 中设置Project > Options > Application > Appearance)。
该控件源自TWinControl(下图红框中)。如何将应用程序主题应用到我的组件?我将在上面使用很多标准控件,如按钮、编辑等。
我试图在谷歌中找到一些东西,但也许我的英语是问正确问题的问题:)
小智 2
没有为您的组件指定特殊的皮肤数据,因此您需要从 VCL 中挑选其他类似组件中与您的组件相似的部分。然后你需要查看这个组件的源代码,并根据你的具体更改实现相同的绘制。\n你没有提供你的组件的详细描述,所以这一切都取决于我们的幻想。比方说:您想要像 TPanel 这样的东西,中间有一个红色矩形的自定义选项卡。\n我们将选择 TCustomControl(而不是 TWinControl)作为父级,因为我们已经为自定义绘图和主题实现了 Canvas支持。我们将重写 UpdateStyleElements 以对主题更改做出反应并为我们的绘图绘制(TCustomPanel 执行相同操作,我们使用其绘制功能的一部分)。
\nunit Component1;\n\ninterface\n\nuses\n System.SysUtils, System.Classes, vcl.Controls, vcl.Styles, WinApi.Windows,\n vcl.Themes, Vcl.Graphics, Vcl.ExtCtrls;\n\ntype\n TComponent1 = class(TCustomControl)\n private\n protected\n procedure Paint; override;\n procedure UpdateStyleElements; override;\n end;\n\nprocedure Register;\n\nimplementation\n\nprocedure Register;\nbegin\n RegisterComponents(\'Samples\', [TComponent1]);\nend;\n\n{ TComponent1 }\n\nprocedure TComponent1.Paint;\nconst\n Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);\n VerticalAlignments: array[TVerticalAlignment] of Longint = (DT_TOP, DT_BOTTOM, DT_VCENTER);\nvar\n Rect: TRect;\n LColor: TColor;\n LStyle: TCustomStyleServices;\n LDetails: TThemedElementDetails;\n TopColor, BottomColor: TColor;\n BaseColor, BaseTopColor, BaseBottomColor: TColor;\n Flags: Longint;\n\n procedure AdjustColors(Bevel: TPanelBevel);\n begin\n TopColor := BaseTopColor;\n if Bevel = bvLowered then\n TopColor := BaseBottomColor;\n BottomColor := BaseBottomColor;\n if Bevel = bvLowered then\n BottomColor := BaseTopColor;\n end;\n\nbegin\n //get rect, where we will drawing\n Rect := GetClientRect;\n\n //initilize colors\n BaseColor := Color;\n BaseTopColor := clBtnHighlight;\n BaseBottomColor := clBtnShadow;\n\n //get style\n LStyle := StyleServices(Self);\n if LStyle.Enabled and (seClient in StyleElements) then\n begin\n //get detail(background) of our style, which we will use\n LDetails := LStyle.GetElementDetails(tpPanelBackground);\n //check, if in this style our color is changed - we take it\n if LStyle.GetElementColor(LDetails, ecFillColor, LColor) and (LColor <> clNone) then\n BaseColor := LColor;\n\n //get detail(border) of our style, which we will use\n LDetails := LStyle.GetElementDetails(tpPanelBevel);\n //check, if in this style our color is changed - we take it\n if LStyle.GetElementColor(LDetails, ecEdgeHighLightColor, LColor) and (LColor <> clNone) then\n BaseTopColor := LColor;\n if LStyle.GetElementColor(LDetails, ecEdgeShadowColor, LColor) and (LColor <> clNone) then\n BaseBottomColor := LColor;\n end;\n\n //draw top border\n if BevelOuter <> bvNone then\n begin\n AdjustColors(BevelOuter);\n Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);\n end;\n\n //if style does not draw borders - do it by ourselves\n if not (LStyle.Enabled and (csParentBackground in ControlStyle)) then\n Frame3D(Canvas, Rect, BaseColor, BaseColor, BorderWidth)\n else\n InflateRect(Rect, -Integer(BorderWidth), -Integer(BorderWidth));\n\n if BevelInner <> bvNone then\n begin\n AdjustColors(BevelInner);\n Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);\n end;\n\n with Canvas do\n begin\n if not LStyle.Enabled or not ParentBackground or not (seClient in StyleElements) or\n (not LStyle.IsSystemStyle and (Parent <> nil) and (Parent is TCustomPanel) and\n TCustomPanel(Parent).DoubleBuffered {and not CheckParentBackground(Parent)})\n then\n begin\n //set curect brush color\n Brush.Color := BaseColor;\n //and fill all client rect with it\n FillRect(Rect);\n end;\n\n //drawing red rectangle\n Brush.Style := bsClear;\n Pen.Color := clRed;\n InflateRect(Rect, -30, -30);\n Rectangle(Rect);\n\n if LStyle.Enabled then begin\n //draw\n //make tab smaller\n InflateRect(Rect, -10, -10);\n //move tab to bottom of recrangle\n OffsetRect(Rect, 0, 10 - 1);\n //get slyled tab\n LDetails := LStyle.GetElementDetails(ttTabItemSelected);\n //draw tab\n LStyle.DrawElement(Handle, LDetails, rect);\n\n //draw some text on tab\n Brush.Style := bsClear;\n Font := Self.Font;\n Flags := DT_EXPANDTABS or DT_SINGLELINE or\n VerticalAlignments[taVerticalCenter] or Alignments[taCenter];\n Flags := DrawTextBiDiModeFlags(Flags);\n if LStyle.Enabled and (seFont in StyleElements) then\n begin\n LDetails := LStyle.GetElementDetails(tpPanelBackground);\n if not LStyle.GetElementColor(LDetails, ecTextColor, LColor) or (LColor = clNone) then\n LColor := Font.Color;\n LStyle.DrawText(Handle, LDetails, \'CustomCaption\', Rect, TTextFormatFlags(Flags), LColor)\n end\n else\n DrawText(Handle, Caption, -1, Rect, Flags);\n end;\n end;\nend;\n\nprocedure TComponent1.UpdateStyleElements;\nbegin\n inherited;\nend;\nend.\nRun Code Online (Sandbox Code Playgroud)\n您可以在模块 \xe2\x80\x98Vcl.Themes\xe2\x80\x99 中找到样式的另一个标准部分。\n源已简化,但您可以从这一点开始。
\nPS 如果您的组件有更高级的绘图 \xe2\x80\x93 您可以使用与其他高级组件相同的样式挂钩。查看 \xe2\x80\x98 类构造函数\xe2\x80\x99 和 \xe2\x80\x98 类析构函数\xe2\x80\x99。\n