手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>delphi>列表

Delphi 完全时尚手册之 CoolBar 篇---实现 CoolBar 的新特性 Chevron

来源:互联网 作者:西部数码 时间:2008-04-10
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
Delphi 完全时尚手册之 CoolBar 篇
---实现 CoolBar 的新特性 Chevron

我们发现到从 IE 5.0 以后,IE 的工具栏具有了一个新特性:当 IE 窗口缩小,使得工具栏上的按钮不能完全显示时,工具栏右边会出现一个小按钮(M$ 叫它 Chevron,实际上这是 CoolBar 的新特性),点击后出现一下拉列表,显示出被隐藏的按钮。这大大方便了我们对工具栏的使用。


那我们如何使 Delphi 的 TCoolBar 控件具有这个特性呢?经过我一个通宵的查阅资料(MSDN)、“潜心研究”(啊,谁扔我鸡蛋...),终于做出来了!好东西不敢独吞,拿出来与大家分享。下面就说说怎么具体实现它。(以下代码在 Delphi 6 下完成)

第一步:改造 Delphi 的 TCoolBand 类

建议在进行这步前先备份 ComCtrls.pas 文件。如果将 CoolBar 中某个 Band 的 Style 中加上 RBBS_USECHEVRON 这个值,那么当这个 Band 的宽度小于某个给定的值时它就会显示一个下拉按钮(Chevron)。下面来改 ComCtrls.pas 这个文件来实现这个功能。

在 TCoolBand 的 Published 部分增加两个属性(Property):

  //Modified by Joe Huang
  property DealWidth: Integer read FDealWidth write SetDealWidth; {用来告诉 Band 当 Band 的宽度小于多少时显示下拉按钮(Chevron)}
  property UseChevron: Boolean read FUseChevron write SetUseChevron; {用来决定 Band 是否使用这个功能}
  //End

两个属性的写方法如下:

  procedure TCoolBand.SetUseChevron(const Value: Boolean);
  begin
    FUseChevron := Value;
    CoolBar.UpdateBands;
  end;
  procedure TCoolBand.SetDealWidth(const Value: Integer);
  begin
    FDealWidth := Value;
    CoolBar.UpdateBands;
  end;

对 TCoolBand 的改动完成,但有一点要提醒的,这两个属性虽然在 Publish 部分,但在设计期并不能看到(我也不知道是怎么搞的)。所以我们只能在运行期间访问到它们。

第二步:改造 Delphi 的 TCoolBar 控件

在 ComCtrls.pas 中找到 TCoolBar.UpdateItem 方法,先为这个方法加个常数如下:

  //Modified by Joe Huang
  RBBS_USECHEVRON = $00000200;
  //End

然后在这个方法中找到这一行(第一次出现 fMask := 的地方):

  fMask := RBBIM_STYLE or RBBIM_COLORS or RBBIM_SIZE or RBBIM_BACKGROUND or RBBIM_IMAGE or RBBIM_ID;

在这行下加入下段代码:

  //Modified by Joe Huang
  if (GetComCtlVersion >= ComCtlVersionIE5) and Band.UseChevron then {这个功能只在 IE5 后才有}
  begin
    fStyle := fStyle or RBBS_USECHEVRON;
    if Band.DealWidth > 0 then
    begin
      fMask := fMask or RBBIM_IDEALSIZE;
      cxIdeal := Band.DealWidth;
    end;
  end;
  //End

OK! TCoolBar改造完成。为 ComCtrls.pas 生成 .dcu 文件,方法:把 ComCtrls.pas 文件拷贝到一个现有工程的目录下,把它加到这个工程中,编译这个工程就会得到它的 .dcu 文件,将个 .dcu 文件覆盖(注意备份) Delphi 原来的,在 Delphi6\Lib 目录下。

第三步:在一工程中具体实现。

打开 Delphi6,新建一工程,在 Form1 上放入 CoolBar1,再在 CoolBar1 上面放入 ToolBar1,CoolBar1 会自动产生一 Band。设置 ToolBar1 的 AutoSize 为 True,Wrapable 为 False 并在其上放入你的按钮。设置 CoolBar1 的 AutoSize 为 True, ShowText 为 False(注意:将这属性置为 False 可以为我提供一个利用 Band.Text 属性定位 Band 的方法。在 CoolBar1 上有多个 Band 时定位 Band 是必须的。你也可以采用你自己的定位方式。),设置放有 ToolBar1 的 Band 的 Text 为 MyToolBand。下面开始写代码。


在 Form1 单元的 uses 后加入 CommCtrl 单元;在 Implementation 部分写两个自定义方法:

  {用来取得 ToolBar1 上所有可见按钮的总宽度。
  用来为我们前面给 TCoolBand 增加的属性 DealWidth 赋值,
  即是当 Band 的宽度小于所有按钮的总宽度时显示下拉按钮(Chevron)。}
  function GetTBButtonsWidth(AToolBar: TToolBar): Cardinal;
  var
    ARect, ButtonRect: TRect;
    TBCount, I: Integer;
  begin
ARect := Rect(0, 0, 0, 0); TBCount := AToolBar.Perform(TB_BUTTONCOUNT, 0, 0); for I := 0 to TBCount - 1 do begin AToolBar.Perform(TB_GETITEMRECT, I, Integer(@ButtonRect)); ARect.Right := ARect.Right (ButtonRect.Right - ButtonRect.Left); end; Result := Abs(ARect.Right - ARect.Left); end; {用来定位 Band 参数 BandText 为你所要定位 Band 的 Text 属性} function GetCoolBand(BandText: string; ACoolBar: TCoolBar): Integer; var I: Integer; begin Result := -1; for I := 0 to ACoolBar.Bands.Count - 1 do begin if ACoolBar.Bands.Items[I].Text = BandText then begin Result := I; Break; end; end; end;

由于 CoolBar1 上 Band 可以改变位置(当有多个 Band 时),所以我们需要一个变量来存储放有 ToolBar1 的 Band 的当前位置(后面会提到如何捕捉到 Band 的位置变化)。

在 Private 部分定义一变量:

  private
    CoolBandIndex: Integer;

在 Form1 的 OnShow 事件加入如下代码:

  CoolBandIndex := GetCoolBand(''''MyToolBand'''', CoolBar1);   {定位 Band 的位置}
  CoolBar1.Bands.Items[CoolBandIndex].UseChevron := True;   {我们自己加的属性}
  CoolBar1.Bands.Items[CoolBandIndex].DealWidth := GetTBButtonsWidth(ToolBar1);    {我们自己加的属性}

现在大家可以运行一下程序了,然后缩放 Form1 使 ToolBar1 上部分按钮被遮住,看下拉按钮(Chevron)是不是出来了!(什么?没有!赶快检查一下前面各步做得是否正确)

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!