编写Flat风格的Button

2024-01-10 13:48
文章标签 编写 风格 button flat

本文主要是介绍编写Flat风格的Button,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


  • Delphi标准的组件中的Button组件都是3D风格的组件,即使像SpeedButton组件具有Flat属性,但是确没有了Border。因此我们需要一个简单功能的Flat风格组件又不想使用第三方组件,该怎么办呢?通过阅读delphi源代码和反复尝试,我们发现组件的风格主要通过重载    procedure CreateParams(var Params: TCreateParams); override;方法来实现,这也是delphi组件和windows标准组件结合的位置。我们看一下源代码:
    procedure TButton.CreateParams(var Params: TCreateParams);
    const
      ButtonStyles: array[Boolean] of DWORD = (BS_PUSHBUTTON, BS_DEFPUSHBUTTON);
    begin
      inherited CreateParams(Params);  //继承祖先的方法
      CreateSubClass(Params, 'BUTTON'); //创建windows组件button类
      Params.Style := Params.Style or ButtonStyles[FDefault];  //设置button类型
    end;
    我们继续跟踪发现ButtonStyles控制了他的border外观,同时由FDefault来确定。我们继续跟踪,就来到了Windows单元,组件风格的秘密就全在这里了。我们来看看:
    BS_PUSHBUTTON,
    BS_DEFPUSHBUTTON
    通过字面意思不难理解,BS_FLAT就是我们要找的。好了,接下来我们实现它就OK了。
    代码及测试代码实现如下:
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Buttons, StdCtrls, Themes;
     
    type
      TFlatButton = class(TButtonControl)
      private
        FCancel: Boolean;
        FDefault: Boolean;
        FActive: Boolean;
        FModalResult: TModalResult;
        procedure SetDefault(const Value: Boolean);
        procedure CNCtlColorBtn(var Message: TWMCtlColorBtn); message CN_CTLCOLORBTN;
        procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
      protected
        procedure CreateParams(var Params: TCreateParams); override;
        procedure CreateWnd; override;
      public
        constructor Create(AOwner: TComponent); override;
        procedure Click; override;
        function UseRightToLeftAlignment: Boolean; override;
      published
        property Action;
        property Anchors;
        property BiDiMode;
        property Cancel: Boolean read FCancel write FCancel default False;
        property Caption;
        property Constraints;
        property Default: Boolean read FDefault write SetDefault default False;
        property DragCursor;
        property DragKind;
        property DragMode;
        property Enabled;
        property Font;
        property ModalResult: TModalResult read FModalResult write FModalResult default 0;
        property ParentBiDiMode;
        property ParentFont;
        property ParentShowHint;
        property PopupMenu;
        property ShowHint;
        property TabOrder;
        property TabStop default True;
        property Visible;
        property WordWrap;
        property OnClick;
        property OnContextPopup;
        property OnDragDrop;
        property OnDragOver;
        property OnEndDock;
        property OnEndDrag;
        property OnEnter;
        property OnExit;
        property OnKeyDown;
        property OnKeyPress;
        property OnKeyUp;
        property OnMouseDown;
        property OnMouseMove;
        property OnMouseUp;
        property OnStartDock;
        property OnStartDrag;
      end;
     
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        procedure MyClick(Sender: TObject);
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    { TFlatButton }
     
    procedure TFlatButton.Click;
    var
      Form: TCustomForm;
    begin
      Form := GetParentForm(Self);
      if Form <> nil then Form.ModalResult := ModalResult;
      inherited Click;
    end;
     
    procedure TFlatButton.CNCtlColorBtn(var Message: TWMCtlColorBtn);
    begin
      with ThemeServices do
        if ThemesEnabled then
        begin
          DrawParentBackground(Handle, Message.ChildDC, nil, False);
          { Return an empty brush to prevent Windows from overpainting we just have created. }
          Message.Result := GetStockObject(NULL_BRUSH);
        end
        else
          inherited;
    end;
     
    constructor TFlatButton.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      Width := 75;
      Height := 25;
      TabStop := True;
    end;
     
    procedure TFlatButton.CreateParams(var Params: TCreateParams);
    const
      ButtonStyles: array[Boolean] of DWORD = (BS_FLAT, BS_DEFPUSHBUTTON);
    begin
      inherited CreateParams(Params);
      CreateSubClass(Params, 'BUTTON');
      Params.Style := Params.Style or BS_FLAT;//ButtonStyles[FDefault];
    end;
     
    procedure TFlatButton.CreateWnd;
    begin
      inherited CreateWnd;
      FActive := FDefault;
    end;
     
    procedure TFlatButton.SetDefault(const Value: Boolean);
    begin
      FDefault := Value;
    end;
     
    function TFlatButton.UseRightToLeftAlignment: Boolean;
    begin
      Result := False;
    end;
     
    procedure TFlatButton.WMEraseBkgnd(var Message: TWMEraseBkgnd);
    begin
      if ThemeServices.ThemesEnabled then
        Message.Result := 1
      else
        DefaultHandler(Message);
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      button: TFlatButton;
    begin
      button := TFlatButton.Create(self);
      button.Parent := self;
      button.Caption := '&OK';
      button.SetBounds(10, 10, 75, 25);
      button.OnClick := myClick;
    end;
     
    procedure TForm1.MyClick(Sender: TObject);
    begin
      showmessage('you clicked me!');
    end;
     
    end.

这篇关于编写Flat风格的Button的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/591019

相关文章

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

Flutter Button使用

Material 组件库中有多种按钮组件如ElevatedButton、TextButton、OutlineButton等,它们的父类是于ButtonStyleButton。         基本的按钮特点:         1.按下时都会有“水波文动画”。         2.onPressed属性设置点击回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。

Wondows dos下怎么编写bat批处理文件

最近搞php,在运行时,以Nginx+php-cgi.exe方式运行Wordpress项目 打开dos,先cd到php-cgi.exe文件当前目录下执行启动命令:php-cgi.exe -b 127.0.0.1:9001再打开一个dos,再cd到nginx.exe文件当前目录下执行启动命令:start nginx 大概过程要经过这些步骤,觉得很麻烦,就学下怎么编写一个bat文件,以双击运行代替

小程序button控件上下边框的显示和隐藏

问题 想使用button自带的loading图标功能,但又不需要button显示边框线 button控件有一条淡灰色的边框,在控件上了样式 border:none; 无法让button边框隐藏 代码如下: <button class="btn">.btn{border:none; /*一般使用这个就是可以去掉边框了*/} 解决方案 发现button控件有一个伪元素(::after

用Python编写倒计时程序:详细教程

目录 引言 环境准备 基本概念 代码实现 步骤一:导入必要的库 步骤二:获取用户输入 步骤三:实现倒计时逻辑 步骤四:整合代码 运行程序 高级功能 扩展功能示例:支持分钟和小时输入 扩展功能示例:图形用户界面 (GUI) 总结 引言 倒计时程序是一个非常常见的小工具,广泛用于各种应用场景中,例如考试时间提醒、烹饪计时器、会议倒计时等。Python 作为一种

glShadeModel函数 GL_SMOOTH与GL_FLAT的区别

glShadeModel函数用于控制opengl中绘制指定两点间其他点颜色的过渡模式 参数一般为GL_SMOOTH(默认),GL_FLAT opengl默认是将制定的两点颜色进行插值,绘制之间的其他点 如果两点的颜色相同,使用两个参数效果相同 如果两点颜色不同,GL_SMOOTH会出现过渡效果,GL_FLAT 则只是以指定的某一点的单一色绘制其他所有点 如图可以对比GL_SM

在 Qt Creator 中,输入 /** 并按下Enter可以自动生成 Doxygen 风格的注释

在 Qt Creator 中,当你输入 /** 时,确实会自动补全标准的 Doxygen 风格注释。这是因为 Qt Creator 支持 Doxygen 以及类似的文档注释风格,并且提供了代码自动补全功能。 以下是如何在 Qt Creator 中使用和显示这些注释标记的步骤: 1. 自动补全 Doxygen 风格注释 在 Qt Creator 中,你可以这样操作: 在你的代码中,将光标放在

一个图形引擎的画面风格是由那些因素(技术)决定的?

可能很多人第一直覺會認為shader決定了視覺風格,但我認為可以從多個方面去考慮。 1. 幾何模型 一個畫面由多個成分組成,最基本的應該是其結構,在圖形學中通常稱為幾何模型。 一些引擎,如Quake/UE,有比較強的Brush建模功能(或應稱作CSG),製作建築比較方便。而CE則有較強的大型地表、植被、水體等功能,做室外自然環境十分出色。而另一些遊戲類型專用的引擎,例

风格控制水平创新高!南理工InstantX小红书发布CSGO:简单高效的端到端风格迁移框架

论文链接:https://arxiv.org/pdf/2408.16766 项目链接:https://csgo-gen.github.io/ 亮点直击 构建了一个专门用于风格迁移的数据集设计了一个简单但有效的端到端训练的风格迁移框架CSGO框架,以验证这个大规模数据集在风格迁移中的有益效果。引入了内容对齐评分(Content Alignment Score,简称CAS)来评估风格迁移

【Spring boot】编写代码及测试用例入门之 Hello Spring boot _踩坑记

先贴下目录: 这是我从 start.spring.io 里下载的依赖Web的模板 // DemoApplication.javapackage com.abloume.springboot.blog.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autocon