如何在标题栏上增加按钮

如何在标题栏上增加按钮

---- 大家在使用某些软件的过程中,有没有注意到有些软件有一些很有趣的东西。比如说在主窗口的标
题栏上居然有一个按钮。在Internet中随处可见这样的小控件。按钮怎么可以加入到非客户区(Client)
呢? 

---- 在这里,最关键的一点就是,大家不要被传统知识误导:真的认为它是一个按钮。有名柄(handle)
的控件当然不能放在标题栏上了。有经验的程序员用Spy++跟踪一下的话,马上就会发现其中的秘密。它
并不是一个按钮,只不过是处理成按钮的样子罢了。 

---- 既然知道了所以然,那么我们为什么不能自己来做一个呢,当然没问题,下面我们就用Delphi来实

它,讲注意我的注解。 

---- 在具体实例之前,我们应该知道几个关于标题栏的重要的消息: 

---- WM_NCPAINT:重画标题栏消息。我们必须截住它,可以在这里重画按钮; 

---- WM_NCLBUTTONDOWN:在标题栏上按下鼠标左键消息。我们可以截住它,在标题栏上画出按钮按下的
样子,并且可以在其中进行自已的单击事件的处理,使得它像一个按钮; 

---- WM_NCLBUTTONUP:在标题栏上释放鼠标左键消息。我们可以截住它,在标题栏上画出按钮弹起的样
子; 

---- WM_NCLBUTTONDBLCLK:在标题栏上双击鼠标左键消息。我们可以截住它,当在按钮区域双击时,
我们就该使其无效,从而避免窗体执行最大化和还原操作。 

---- WM_NCRBUTTONDOWN:在标题栏上按下鼠标右键消息。我们可以截住它,当在按钮区域双击时,我
们就该使其无效,从而避免弹出窗体按制菜单。 

---- WM_NCMOUSEMOVE:在标题栏上移动鼠标消息。我们可以截住它,当鼠标移出按钮区域时,我们就
必须画出按钮没有被按下,即凸起时的样子。 

---- WM_NCACTIVATE:当标题栏在激活与非激活之间切换时收到该消息。我们可以截住它,当该窗口处
理激活状态时,我们可以做一些事情,比如说将我们的标题栏按钮上的字体变灰或变黑来指示该窗口的
当前状态。下面我没有加入该项功能,如果大家感兴趣的话,可以自己完成。 
---- (大家从这里可以发现,标题栏的消息都是WM_NC开头的) 

---- 知道了原理之后,相信大家一定可以做出更漂亮的按钮来。


WinAPI: DrawFrameControl - 绘制控件


//声明:
DrawFrameControl(
  DC: HDC;            {设备环境句柄}
  const Rect: TRect;  {矩形}
  uType, uState: UINT {控件类型与控件状态}
): BOOL;


//控件类型 uType 参数可选值:
DFC_CAPTION   = 1; {标题按钮}
DFC_MENU      = 2; {菜单}
DFC_SCROLL    = 3; {滚动条按钮}
DFC_BUTTON    = 4; {标准按钮}
DFC_POPUPMENU = 5; {弹出菜单}


//控件状态  uState 参数可选值:

{针对 DFC_CAPTION}
DFCS_CAPTIONCLOSE   = 0;
DFCS_CAPTIONMIN     = 1;
DFCS_CAPTIONMAX     = 2;
DFCS_CAPTIONRESTORE = 3;
DFCS_CAPTIONHELP    = 4;

{针对 DFC_MENU}
DFCS_MENUARROW      = 0;
DFCS_MENUCHECK      = 1;
DFCS_MENUBULLET     = 2;
DFCS_MENUARROWRIGHT = 4;

{针对 DFC_SCROLL}
DFCS_SCROLLUP            = 0;
DFCS_SCROLLDOWN          = 1;
DFCS_SCROLLLEFT          = 2;
DFCS_SCROLLRIGHT         = 3;
DFCS_SCROLLCOMBOBOX      = 5;
DFCS_SCROLLSIZEGRIP      = 8;
DFCS_SCROLLSIZEGRIPRIGHT = $10;

{针对 DFC_BUTTON}
DFCS_BUTTONCHECK      = 0;
DFCS_BUTTONRADIOIMAGE = 1;
DFCS_BUTTONRADIOMASK  = 2;
DFCS_BUTTONRADIO      = 4;
DFCS_BUTTON3STATE     = 8;
DFCS_BUTTONPUSH       = $10;

{通用状态}
DFCS_INACTIVE    = $100;
DFCS_PUSHED      = $200;
DFCS_CHECKED     = $400;
DFCS_TRANSPARENT = $800;
DFCS_HOT         = $1000;
DFCS_ADJUSTRECT  = $2000;
DFCS_FLAT        = $4000;
DFCS_MONO        = $8000;


//举例:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    RadioGroup1: TRadioGroup;
    RadioGroup2: TRadioGroup;
    RadioGroup3: TRadioGroup;
    RadioGroup4: TRadioGroup;
    RadioGroup5: TRadioGroup;
    RadioGroup6: TRadioGroup;
    Panel1: TPanel;
    procedure RadioGroup1Click(Sender: TObject);
    procedure RadioGroup2Click(Sender: TObject);
    procedure RadioGroup3Click(Sender: TObject);
    procedure RadioGroup4Click(Sender: TObject);
    procedure RadioGroup5Click(Sender: TObject);
    procedure RadioGroup6Click(Sender: TObject);
    procedure Draw;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  DFC  : Integer = 0;
  DFCS1: Integer = 0;
  DFCS2: Integer = 0;

procedure TForm1.Draw;
begin
  Panel1.Refresh;
  DrawFrameControl(GetDC(Panel1.Handle), Rect(10,10,100,50), DFC, DFCS1 or DFCS2);
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  Panel1.Refresh;
  case RadioGroup1.ItemIndex of
    0: begin
      DFC := DFC_CAPTION;
      RadioGroup3.Enabled := True;
      RadioGroup4.Enabled := False;
      RadioGroup5.Enabled := False;
      RadioGroup6.Enabled := False;
    end;
    1: begin
      DFC := DFC_MENU;
      RadioGroup3.Enabled := False;
      RadioGroup4.Enabled := True;
      RadioGroup5.Enabled := False;
      RadioGroup6.Enabled := False;
    end;
    2: begin
      DFC := DFC_SCROLL;
      RadioGroup3.Enabled := False;
      RadioGroup4.Enabled := False;
      RadioGroup5.Enabled := True;
      RadioGroup6.Enabled := False;
    end;
    3: begin
      DFC := DFC_BUTTON;
      RadioGroup3.Enabled := False;
      RadioGroup4.Enabled := False;
      RadioGroup5.Enabled := False;
      RadioGroup6.Enabled := True;
    end;
    4: begin
      DFC := DFC_POPUPMENU;
      RadioGroup3.Enabled := False;
      RadioGroup4.Enabled := True;
      RadioGroup5.Enabled := False;
      RadioGroup6.Enabled := False;
    end;
  end;
end;

procedure TForm1.RadioGroup2Click(Sender: TObject);
begin
  case RadioGroup2.ItemIndex of
    0: DFCS1 := DFCS_INACTIVE;
    1: DFCS1 := DFCS_PUSHED;
    2: DFCS1 := DFCS_CHECKED;
    3: DFCS1 := DFCS_TRANSPARENT;
    4: DFCS1 := DFCS_HOT;
    5: DFCS1 := DFCS_ADJUSTRECT;
    6: DFCS1 := DFCS_FLAT;
    7: DFCS1 := DFCS_MONO;
  end;
  Draw;
end;

procedure TForm1.RadioGroup3Click(Sender: TObject);
begin
  case RadioGroup3.ItemIndex of
    0: DFCS2 := DFCS_CAPTIONCLOSE;
    1: DFCS2 := DFCS_CAPTIONMIN;
    2: DFCS2 := DFCS_CAPTIONMAX;
    3: DFCS2 := DFCS_CAPTIONRESTORE;
    4: DFCS2 := DFCS_CAPTIONHELP;
  end;
  Draw;
end;

procedure TForm1.RadioGroup4Click(Sender: TObject);
begin
  case RadioGroup4.ItemIndex of
    0: DFCS2 := DFCS_MENUARROW;
    1: DFCS2 := DFCS_MENUCHECK;
    2: DFCS2 := DFCS_MENUBULLET;
    3: DFCS2 := DFCS_MENUARROWRIGHT;
  end;
  Draw;
end;

procedure TForm1.RadioGroup5Click(Sender: TObject);
begin
  case RadioGroup5.ItemIndex of
    0: DFCS2 := DFCS_SCROLLUP;
    1: DFCS2 := DFCS_SCROLLDOWN;
    2: DFCS2 := DFCS_SCROLLLEFT;
    3: DFCS2 := DFCS_SCROLLRIGHT;
    4: DFCS2 := DFCS_SCROLLCOMBOBOX;
    5: DFCS2 := DFCS_SCROLLSIZEGRIP;
    6: DFCS2 := DFCS_SCROLLSIZEGRIPRIGHT;
  end;
  Draw;
end;

procedure TForm1.RadioGroup6Click(Sender: TObject);
begin
  case RadioGroup6.ItemIndex of
    0: DFCS2 := DFCS_BUTTONCHECK;
    1: DFCS2 := DFCS_BUTTONRADIOIMAGE;
    2: DFCS2 := DFCS_BUTTONRADIOMASK;
    3: DFCS2 := DFCS_BUTTONRADIO;
    4: DFCS2 := DFCS_BUTTON3STATE;
    5: DFCS2 := DFCS_BUTTONPUSH;
  end;
  Draw;
end;

end.

//效果图:

附上窗体结构代码:

附上窗体结构代码:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 386
  ClientWidth = 499
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object RadioGroup1: TRadioGroup
    Left = 0
    Top = 8
    Width = 137
    Height = 129
    Caption = 'RadioGroup1'
    Items.Strings = (
      'DFC_CAPTION   '
      'DFC_MENU      '
      'DFC_SCROLL    '
      'DFC_BUTTON    '
      'DFC_POPUPMENU ')
    TabOrder = 0
    OnClick = RadioGroup1Click
  end
  object RadioGroup2: TRadioGroup
    Left = 0
    Top = 143
    Width = 137
    Height = 170
    Caption = 'RadioGroup2'
    Items.Strings = (
      'DFCS_INACTIVE'
      'DFCS_PUSHED'
      'DFCS_CHECKED'
      'DFCS_TRANSPARENT'
      'DFCS_HOT'
      'DFCS_ADJUSTRECT'
      'DFCS_FLAT'
      'DFCS_MONO')
    TabOrder = 1
    OnClick = RadioGroup2Click
  end
  object RadioGroup3: TRadioGroup
    Left = 143
    Top = 8
    Width = 178
    Height = 129
    Caption = 'RadioGroup3'
    Items.Strings = (
      'DFCS_CAPTIONCLOSE   '
      'DFCS_CAPTIONMIN'
      'DFCS_CAPTIONMAX'
      'DFCS_CAPTIONRESTORE'
      'DFCS_CAPTIONHELP')
    TabOrder = 2
    OnClick = RadioGroup3Click
  end
  object RadioGroup4: TRadioGroup
    Left = 327
    Top = 8
    Width = 170
    Height = 129
    Caption = 'RadioGroup4'
    Items.Strings = (
      'DFCS_MENUARROW'
      'DFCS_MENUCHECK'
      'DFCS_MENUBULLET'
      'DFCS_MENUARROWRIGHT')
    TabOrder = 3
    OnClick = RadioGroup4Click
  end
  object RadioGroup5: TRadioGroup
    Left = 143
    Top = 143
    Width = 178
    Height = 170
    Caption = 'RadioGroup5'
    Items.Strings = (
      'DFCS_SCROLLUP'
      'DFCS_SCROLLDOWN'
      'DFCS_SCROLLLEFT'
      'DFCS_SCROLLRIGHT'
      'DFCS_SCROLLCOMBOBOX'
      'DFCS_SCROLLSIZEGRIP'
      'DFCS_SCROLLSIZEGRIPRIGHT')
    TabOrder = 4
    OnClick = RadioGroup5Click
  end
  object RadioGroup6: TRadioGroup
    Left = 327
    Top = 143
    Width = 170
    Height = 170
    Caption = 'RadioGroup6'
    Items.Strings = (
      'DFCS_BUTTONCHECK'
      'DFCS_BUTTONRADIOIMAGE'
      'DFCS_BUTTONRADIOMASK'
      'DFCS_BUTTONRADIO'
      'DFCS_BUTTON3STATE'
      'DFCS_BUTTONPUSH')
    TabOrder = 5
    OnClick = RadioGroup6Click
  end
  object Panel1: TPanel
    Left = 0
    Top = 319
    Width = 499
    Height = 67
    Align = alBottom
    Caption = 'Panel1'
    TabOrder = 6
  end
end

/
另一个例子
unit Unit1;

interface

uses
  Windows, Buttons, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormResize(Sender: TObject);
  private
    { Private declarations }
    CaptionBtn:TRect;
    procedure DrawCaptButton;
    procedure WMNCPaint(var Msg:TWMNCPaint);message WM_NCPaint;
    procedure WMNCActivate(var Msg:TWMNCActivate);message WM_NCActivate;
    procedure WMSetText(var Msg:TWMSetText);message WM_SetText;
    procedure WMNCHitTest(var Msg:TWMNCHitTest);message WM_NCHittest;
    procedure WMNCLButtonDown(var Msg:TWMNCLButtonDown);message WM_NCLButtonDown;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

const
  htCaptionBtn=htSizeLast+1;

{$R *.DFM}

procedure TForm1.DrawCaptButton;{绘制按钮}
var
  xFrame,yFrame,xSize,ySize:Integer;
  R:TRect;
begin
  xFrame:=GetSystemMetrics(SM_CXFRAME);
  yFrame:=GetSystemMetrics(SM_CYFRAME);
  xSize:=GetSystemMetrics(SM_CXSIZE);
  ySize:=GetSystemMetrics(SM_CYSIZE);
  CaptionBtn:=Bounds(Width-xFrame-5*xSize+2,yFrame+2,xSize+13,ySize-4);
  Canvas.Handle:=GetWindowDC(Self.Handle);
  Canvas.Font.Name:='宋体';
  Canvas.Font.Color:=clRed;
  Canvas.Pen.Color:=clYellow;
  Canvas.Brush.Color:=clBtnFace;
  try
    DrawButtonFace(Canvas,CaptionBtn,1,bsAutoDetect,False,False,False);
    R:=Bounds(Width-xFrame-5*xSize+3,yFrame+3,xSize+10,ySize-7);
    with CaptionBtn do
      Canvas.TextRect(R,R.Left+2,R.Top,'按钮');
  finally
    ReleaseDC(Self.Handle,Canvas.Handle);
    Canvas.Handle:=0;
  end;
end;

procedure TForm1.WMNCActivate(var Msg: TWMNCActivate);
begin
inherited;
  DrawCaptButton;
end;

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
inherited;
  with Msg do
    if PtInRect(CaptionBtn,Point(xPos-Left,yPos-Top)) then
    Result:=htCaptionBtn;
end;

procedure TForm1.WMNCLButtonDown(var Msg: TWMNCLButtonDown);{标题栏按钮响应事件}
begin
inherited;
  if(Msg.HitTest=htCaptionBtn)then
    showmessage('检验成功');
end;

procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
begin
inherited;
  DrawCaptButton;
end;

procedure TForm1.WMSetText(var Msg: TWMSetText);
begin
inherited;
  DrawCaptButton;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Perform(WM_NCACTIVATE,Word(Active),0);
end;

end.

///
object Form1: TForm1
  Left = 219
  Top = 160
  Width = 306
  Height = 218
  Caption = 'Form1'
  Color = clTeal
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnResize = FormResize
  PixelsPerInch = 96
  TextHeight = 13
end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值