Word 2010中的“选项”对话框通过一组白色“切换”按钮实现类别选择器,当按下(选择)按钮时,该对象将变为橙色.
在Delphi中如何重新实现这种行为?需要符合当前的Windows主题(即,必须可以将按钮颜色指定为clWindow,而不是clWhite).
编辑:澄清 – 我只在左边的类别选择器有问题.一切都很简单.
解决方法
您可以使用
TButtonGroup组件.
使用VCL风格是迄今为止最简单的解决方案,但就像您所说,使用XE2中的风格非常不舒服,在我看来,这个功能在XE3中真的变得可行.
该项目需要一个图像,图像与项目一起压缩.
在XE4编译测试.
type TButtonGroup = class(Vcl.ButtonGroup.TButtonGroup) protected procedure Paint; override; end; TForm1 = class(TForm) ButtonGroup1: TButtonGroup; Panel1: TPanel; procedure ButtonGroup1DrawButton(Sender: TObject; Index: Integer; Canvas: TCanvas; Rect: TRect; State: TButtonDrawState); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; MBitmap : TBitmap; implementation {$R *.dfm} procedure TButtonGroup.Paint; var R : TRect; begin inherited; R := GetClientRect; R.Top := Self.Items.Count * Self.ButtonHeight; {Remove the clBtnFace background default Painting} Self.Canvas.FillRect(R); end; procedure TForm1.ButtonGroup1DrawButton(Sender: TObject; Index: Integer; Canvas: TCanvas; Rect: TRect; State: TButtonDrawState); var TextLeft,TextTop: Integer; RectHeight: Integer; ImgTop: Integer; Text : String; TextOffset: Integer; ButtonItem: TGrpButtonItem; InsertIndication: TRect; DrawSkipLine : TRect; TextRect: TRect; OrgRect: TRect; begin //OrgRect := Rect; //icon Canvas.Font := TButtonGroup(Sender).Font; if bdsSelected in State then begin Canvas.CopyRect(Rect,MBitmap.Canvas,System.Classes.Rect(0,MBitmap.Width,MBitmap.Height)); Canvas.Brush.Color := RGB(255,228,138); end else if bdsHot in State then begin Canvas.Brush.Color := RGB(194,221,244); Canvas.Font.Color := clBlack; end else Canvas.Brush.color := clWhite; if not (bdsSelected in State) then Canvas.FillRect(Rect); InflateRect(Rect,-2,-1); { Compute the text location } TextLeft := Rect.Left + 4; RectHeight := Rect.Bottom - Rect.Top; TextTop := Rect.Top + (RectHeight - Canvas.TextHeight('Wg')) div 2; { Do not localize } if TextTop < Rect.Top then TextTop := Rect.Top; if bdsDown in State then begin Inc(TextTop); Inc(TextLeft); end; ButtonItem := TButtonGroup(Sender).Items.Items[Index]; TextOffset := 0; { Draw the icon - if you need to display icons} // if (FImages <> nil) and (ButtonItem.ImageIndex > -1) and // (ButtonItem.ImageIndex < FImages.Count) then // begin // ImgTop := Rect.Top + (RectHeight - FImages.Height) div 2; // if ImgTop < Rect.Top then // ImgTop := Rect.Top; // if bdsDown in State then // Inc(ImgTop); // FImages.Draw(Canvas,TextLeft - 1,ImgTop,ButtonItem.ImageIndex); // TextOffset := FImages.Width + 1; // end; { Show insert indications } if [bdsInsertLeft,bdsInsertTop,bdsInsertRight,bdsInsertBottom] * State <> [] then begin Canvas.Brush.Color := clSkyBlue; InsertIndication := Rect; if bdsInsertLeft in State then begin Dec(InsertIndication.Left,2); InsertIndication.Right := InsertIndication.Left + 2; end else if bdsInsertTop in State then begin Dec(InsertIndication.Top); InsertIndication.Bottom := InsertIndication.Top + 2; end else if bdsInsertRight in State then begin Inc(InsertIndication.Right,2); InsertIndication.Left := InsertIndication.Right - 2; end else if bdsInsertBottom in State then begin Inc(InsertIndication.Bottom); InsertIndication.Top := InsertIndication.Bottom - 2; end; Canvas.FillRect(InsertIndication); //Canvas.Brush.Color := FillColor; end; if gboShowCaptions in TButtonGroup(Sender).ButtonOptions then begin { Avoid clipping the image } Inc(TextLeft,TextOffset); TextRect.Left := TextLeft; TextRect.Right := Rect.Right - 1; TextRect.Top := TextTop; TextRect.Bottom := Rect.Bottom -1; Text := ButtonItem.Caption; Canvas.TextRect(TextRect,Text,[tfEndEllipsis]); end; end; procedure TForm1.FormCreate(Sender: TObject); begin MBitmap := TBitmap.Create; try MBitmap.LoadFromFile('bg.bmp'); except on E : Exception do ShowMessage(E.ClassName+' error raised,with message : '+E.Message); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin MBitmap.Free; end;
DFM:
object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 398 ClientWidth = 287 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False Position = poScreenCenter StyleElements = [] OnCreate = FormCreate OnDestroy = FormDestroy PixelsPerInch = 96 TextHeight = 13 object Panel1: TPanel AlignWithMargins = True Left = 5 Top = 5 Width = 137 Height = 388 Margins.Left = 5 Margins.Top = 5 Margins.Right = 5 Margins.Bottom = 5 Align = alLeft BevelKind = bkFlat BevelOuter = bvNone Color = clWhite ParentBackground = False TabOrder = 0 StyleElements = [seFont] object ButtonGroup1: TButtonGroup AlignWithMargins = True Left = 4 Top = 4 Width = 125 Height = 378 Margins.Left = 4 Margins.Top = 4 Margins.Right = 4 Margins.Bottom = 2 Align = alClient BevelInner = bvNone BevelOuter = bvNone BorderStyle = bsNone ButtonOptions = [gboFullSize,gboGroupStyle,gboShowCaptions] DoubleBuffered = True Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Segoe UI' Font.Style = [] Items = < item Caption = 'General' end item Caption = 'Display' end item Caption = 'Proofing' end item Caption = 'Save' end item Caption = 'Language' end item Caption = 'Advanced' end> ParentDoubleBuffered = False TabOrder = 0 OnDrawButton = ButtonGroup1DrawButton end end end
有一个面板容器在那里托管TButtonGroup,它不是必需的,只是添加为视觉改善.
如果要在运行时更改选择的颜色,建议您使用efg’s Hue/Saturation method更改图像的色相,颜色面板保持不变,但颜色将发生变化.
要获得对VCL样式的支持,只需从TButtonGroup组件中分离ButtonGroup1DrawButton事件,那么默认的DrawButton事件就可以启动,这样可以增加对它的支持.