C# 实现TrackBar控件美化换肤

http://www.vspub.com/viewthread.php?tid=6043

 

TrackBar控件没有像其他控件那样,直接提供给用户重绘的函数,要实现个性化的TrackBar控件,一种方法是继承Control完全的自己实现,这种方法就是实现标准的Windows控件功能需要自己处理很多东西,例如:实现一样的属性、键盘的操作、鼠标滚动改变TrackBar的值等;另一种方法就是直接继承TrackBar控件,利用TrackBar的一些Windows消息,获取TrackBar控件的信息,然后自己完全重绘,这种方法的好处是保留TrackBar控件的标准操作和属性,但是需要比较清楚的了解TrackBar控件的Windows消息。本文将介绍使用第二种方法实现对TrackBar控件的美化。

下面来了解一下实现TrackBar控件美化需要的一些API消息。TrackBar控件相关的一些消息都是以TBM(TackBar Message)开头的,在TrackBar控件的美化中,主要用到了以下三个消息:
        TBM_GETCHANNELRECT  获取轨道的位置和大小。
        TBM_GETTHUMBRECT  获取滑块的位置和大小。
        TBM_GETNUMTICS  获取刻度的总个数。

要获取这些信息,只需要向TrackBar控件发送相应的消息即可,例如需要获取取轨道的位置和大小:SendMessage(hWnd, TBM.TBM_GETCHANNELRECT, 0, ref trackRect)。

有了上面的知识,接下来就是重绘TrackBar控件了。重绘TrackBar控件,需要重写WndProc函数,在WM_PAINT消息实现重绘就行了:

  1. protected override void WndProc(ref Message m)
  2.         {
  3.             switch (m.Msg)
  4.             {
  5.                 case WM.WM_PAINT:
  6.                     if (!_bPainting)
  7.                     {
  8.                         _bPainting = true;

  9.                         PAINTSTRUCT ps = new PAINTSTRUCT();

  10.                         NativeMethods.BeginPaint(m.HWnd, ref ps);
  11.                         DrawTrackBar(m.HWnd);
  12.                         NativeMethods.ValidateRect(m.HWnd, ref ps.rcPaint);
  13.                         NativeMethods.EndPaint(m.HWnd, ref ps);

  14.                         _bPainting = false;
  15.                         m.Result = Result.TRUE;
  16.                     }
  17.                     else
  18.                     {
  19.                         base.WndProc(ref m);
  20.                     }
  21.                     break;
  22.                 default:
  23.                     base.WndProc(ref m);
  24.                     break;
  25.             }
  26.         }
复制代码

来看看DrawTrackBar函数,DrawTrackBar函数的功能就是获取TrackBar控件的一些信息,然后分别调用四个函数来绘制TrackBar控件:

         OnRenderBackground函数,绘制TrackBar控件的背景。
         OnRenderTick函数,绘制TrackBar控件的刻度。
         OnRenderTrack函数,绘制TrackBar控件的轨道。
         OnRenderThumb函数,绘制TrackBar控件的滑块。
这四个函数都是可以重写的,如果想实现不同样式的TrackBar控件,重写这四个函数,进行相应的绘制即可。看看DrawTrackBar函数的具体代码:

  1.         private void DrawTrackBar(IntPtr hWnd)
  2.         {
  3.             ControlState state = ControlState.Normal;
  4.             bool horizontal = base.Orientation == Orientation.Horizontal;
  5.             ImageDc tempDc = new ImageDc(base.Width, base.Height);
  6.             RECT trackRect = new RECT();
  7.             RECT thumbRect = new RECT();
  8.             Graphics g = Graphics.FromHdc(tempDc.Hdc);

  9.             NativeMethods.SendMessage(hWnd, TBM.TBM_GETCHANNELRECT, 0, ref trackRect);
  10.             NativeMethods.SendMessage(hWnd, TBM.TBM_GETTHUMBRECT, 0, ref thumbRect);

  11.             Rectangle trackRectangle = horizontal ? trackRect.Rect :Rectangle.FromLTRB(trackRect.Top, trackRect.Left,trackRect.Bottom, trackRect.Right);

  12.             if (ThumbHovering(thumbRect))
  13.             {
  14.                 if (Helper.LeftKeyPressed())
  15.                 {
  16.                     state = ControlState.Pressed;
  17.                 }
  18.                 else
  19.                 {
  20.                     state = ControlState.Hover;
  21.                 }
  22.             }

  23.             using (PaintEventArgs pe = new PaintEventArgs(g, ClientRectangle))
  24.             {
  25.                 OnRenderBackground(pe);
  26.             }

  27.             int ticks = NativeMethods.SendMessage(hWnd, TBM.TBM_GETNUMTICS, 0, 0);
  28.             if (ticks > 0)
  29.             {
  30.                 List<float> tickPosList = new List<float>(ticks);

  31.                 int thumbOffset = horizontal ?thumbRect.Rect.Width : thumbRect.Rect.Height;
  32.                 int trackWidth = trackRect.Right - trackRect.Left;

  33.                 float tickSpace = (trackWidth - thumbOffset) / (float)(ticks - 1);
  34.                 float offset = trackRect.Left + thumbOffset / 2f;

  35.                 for (int pos = 0; pos < ticks; pos++)
  36.                 {
  37.                     tickPosList.Add(offset + tickSpace * pos);
  38.                 }

  39.                 using (PaintTickEventArgs pte = new PaintTickEventArgs(g, trackRectangle, tickPosList))
  40.                 {
  41.                     OnRenderTick(pte);
  42.                 }

  43.             }
  44.             using (PaintEventArgs pe = new PaintEventArgs( g, trackRectangle))
  45.             {
  46.                 OnRenderTrack(pe);
  47.             }

  48.             using (PaintThumbEventArgs pe = new PaintThumbEventArgs( g, thumbRect.Rect, state))
  49.             {
  50.                 OnRenderThumb(pe);
  51.             }
  52.             g.Dispose();

  53.             IntPtr hDC = NativeMethods.GetDC(hWnd);

  54.             NativeMethods.BitBlt( hDC, 0, 0, base.Width, base.Height,tempDc.Hdc, 0, 0, 0xCC0020);
  55.             NativeMethods.ReleaseDC(hWnd, hDC);

  56.             tempDc.Dispose();
  57.         }
复制代码

最后需要说明的是,扩展后的TrackBar控件还实现了一个ColorTable属性,只要通过ColorTable设置相应的颜色,就可以得到不同颜色效果的TrackBar控件了。
    TrackBar控件的美化换肤到此就实现了,希望对你了解TrackBar控件的美化有所帮助。

你可能感兴趣的:(windows,api,C#,扩展,float)