透明皮肤控件设计系列(六):滚动条处理

9条评论 2013-08-14 admin

滚动条对于界面来说也是非常重要的。修改系统默认滚动条一般有三种方法:

一、覆盖法

覆盖法顾名思义就是创建一个跟滚动条大小一样的控件,覆盖在原来的滚动条上面,当有消息的时候,直接“漏”下去给原来真正的滚动条:

procedure TWinScroll.WMNCHitTest(var Msg: TWMNCHitTest);
begin
  Msg.Result := HTTRANSPARENT;
end;

优点:不用自己计算变化范围。

缺点:大小无法改变。例如比系统原来的滚动条小的化,就盖不住原来的了。

SkinScrollBar1

二、控件法

自己写一个滚动条控件。

优点:滚动条尺寸可变。

缺点:需要自己计算变化范围。

要点:

1、重载WM_NCCALCSIZE消息,不让系统出现原来的滚动条:

procedure TAQMemo.WMNCCALCSIZE(var Message: TWMNCCalcSize);
begin

//nothing

end;

2、要和控件结合为一体的话,可以先创建一个容器,在上面摆放原来的控件和滚动条控件。

constructor TAQMemo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ParentFont := True;
  Color := clWhite;
  DoubleBuffered := True;
  BevelInner := bvRaised; //bvNone;
  BevelOuter := bvLowered; //bvNone;
  FAQSkinMemo := TAQSkinMemo.Create(Self);
  FAQSkinMemo.FAQMemo := Self;
  FAQSkinMemo.Parent := Self;
  FAQSkinMemo.Align := alClient;
  FAQSkinMemo.BorderStyle := bsNone;
  FAQSkinMemo.HideSelection := False;
  FAQSkinMemo.Transparent := True;

  FVScrollBar := TAQScrollBar.Create(Self);
  FVScrollBar.Parent := Self;
  FVScrollBar.Align := alRight;
  FVScrollBar.Kind := sbVertical;

  FVScrollBar.DoubleBuffered := True;
  FVScrollBar.Min := 0;
  FVScrollBar.Max := 0;
  FVScrollBar.Position := 0;
  FVScrollBar.Transparent := True;

  FHScrollBar := TAQScrollBar.Create(Self);
  FHScrollBar.Parent := Self;
  FHScrollBar.Align := alBottom;
  FHScrollBar.Kind := sbHorizontal;
  FHScrollBar.DoubleBuffered := True;
  FHScrollBar.Min := 0;
  FHScrollBar.Max := 0;
  FHScrollBar.Position := 0;
  FHScrollBar.Transparent := True;

  FAQSkinMemo.SetVScrollBar(FVScrollBar);
  FAQSkinMemo.SetHScrollBar(FHScrollBar);
end;

SkinScrollBar2

3、消息法

对于某些控件,上面两种方法都是无法使用的,例如ComboBox控件,只有重载消息处理。

优缺点:仅有此方法,没有优缺点可言。

procedure TComboBoxListScrollBar.ListBoxWndProc(var Message: TMessage);
var
b: Boolean;
begin
  b := False;
  case Message.Msg of
   WM_MOUSEWHEEL: b := WMMouseWheel(TWMMouseWheel(Message));
   WM_PAINT: b := WMPaint(Message);
   WM_NCPAINT: b := WMNCPaint(TWMNCPaint(Message));
   WM_NCLBUTTONDBLCLK: b := WMNCLButtonDblClk(TWMMouse(Message));
   WM_LBUTTONDOWN: b := WMLButtonDown(TWMMouse(Message));
   WM_LBUTTONUP: b := WMLButtonUp(TWMMouse(Message));
   WM_NCLBUTTONDOWN: b := WMNCLButtonDown(TWMMouse(Message));
   WM_MOUSEMOVE: b := WMMouseMove(TWMMouse(Message));
   WM_PRINT: b := WMPrint(Message);
   WM_PRINTCLIENT: b := WMPrintClient(Message);
   WM_NCCALCSIZE: b := WMNCCalcSize(TWMNCCalcSize(Message));
   WM_KEYDOWN: b := WMKeyDown(TWMKeyDown(Message));
   WM_KEYUP: b := WMKeyUp(TWMKeyUp(Message));
   WM_CHAR: b := WMChar(TWMKeyUp(Message));
   LB_SETTOPINDEX: b := LBSETTOPINDEX(Message);
  end;
  if not b then CallDefaultProc(Message);
end;

SkinScrollBar3

 

 

代码下载点这里

分类:界面设计

9条评论 发表评论

  • 支持楼主大侠说道:

    沙发,支持楼主大侠!!!

  • HelloWorld说道:

    请问ComboBox的滚动条怎么换肤?

  • Tag说道:

    楼主,能发一份 QQ用户下拉框 有图片还有个X的按钮那个LISITBOX 给我么? 我只要那个

  • delphier说道:

    TAQSkinScrollBar.Create;
    m_SkinScrollBar.Control := self;//把这个设置窗口自己报内存错误,求解下

    • admin说道:

      请参考示范代码。很多控件是不能在Create的时候就HOOK的,必须等到原来的创建完毕。

  • delphier说道:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    m_SkinScrollBar := TAQSkinScrollBar.Create;
    m_SkinScrollBar.Control := ListBox1;
    //——————-
    m_SkinScrollBar1 := TAQSkinScrollBar.Create;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    m_SkinScrollBar1.Control := Form1;
    end;
    试了下即使是创建在CREATE事件中,CONTROL在点击按扭后还是出错呀。

    • admin说道:

      这个SkinScrollBar是个HOOK,不适合用于窗口的滚动条。原因在于procedure TAQSkinScrollBar.SetControl(Value: TControl);函数:
      VScrollWnd := TWinScroll.CreateParented(Control.Parent.Handle);
      实质是在其父窗口创建一个滚动条来覆盖原来的,而对于窗口来说,它是没有Parent的。

  • 黃衛光说道:

    這個滾動用在listview裏面不能正常滾動,拖動滾動條起不到作用

发表评论

(必填)

(必填), (Hidden)

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

TrackBack URL  |  这篇文章上的评论的RSS feed


近期文章

近期评论

文章归档

分类目录