1. 程式人生 > >C# 實現TrackBar控制元件美化換膚

C# 實現TrackBar控制元件美化換膚

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控制元件的美化有所幫助。