您的位置:首页 > 其它

如何在标题栏上增加按钮

2012-11-05 09:56 281 查看

如何在标题栏上增加按钮

---- 大家在使用某些软件的过程中,有没有注意到有些软件有一些很有趣的东西。比如说在主窗口的标

题栏上居然有一个按钮。在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.

//效果图:[/code]



附上窗体结构代码:

附上窗体结构代码:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: