透明皮肤控件设计系列(六):滚动条处理
9 Comments 2013-08-14 admin
滚动条对于界面来说也是非常重要的。修改系统默认滚动条一般有三种方法:
一、覆盖法
覆盖法顾名思义就是创建一个跟滚动条大小一样的控件,覆盖在原来的滚动条上面,当有消息的时候,直接“漏”下去给原来真正的滚动条:
procedure TWinScroll.WMNCHitTest(var Msg: TWMNCHitTest); begin Msg.Result := HTTRANSPARENT; end;
优点:不用自己计算变化范围。
缺点:大小无法改变。例如比系统原来的滚动条小的化,就盖不住原来的了。
二、控件法
自己写一个滚动条控件。
优点:滚动条尺寸可变。
缺点:需要自己计算变化范围。
要点:
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;
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;
代码下载点这里。
分类:界面设计
9 Comments 发表评论
沙发,支持楼主大侠!!!
请问ComboBox的滚动条怎么换肤?
重载文章中列出的ComboBox的所有消息。
楼主,能发一份 QQ用户下拉框 有图片还有个X的按钮那个LISITBOX 给我么? 我只要那个
TAQSkinScrollBar.Create;
m_SkinScrollBar.Control := self;//把这个设置窗口自己报内存错误,求解下
请参考示范代码。很多控件是不能在Create的时候就HOOK的,必须等到原来的创建完毕。
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在点击按扭后还是出错呀。
这个SkinScrollBar是个HOOK,不适合用于窗口的滚动条。原因在于procedure TAQSkinScrollBar.SetControl(Value: TControl);函数:
VScrollWnd := TWinScroll.CreateParented(Control.Parent.Handle);
实质是在其父窗口创建一个滚动条来覆盖原来的,而对于窗口来说,它是没有Parent的。
這個滾動用在listview裏面不能正常滾動,拖動滾動條起不到作用
发表评论
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 for comments on this post.