ScrollBarEx.cs
上传用户:nnpulika
上传日期:2013-02-15
资源大小:597k
文件大小:17k
源码类别:

状态条

开发平台:

C#

  1. using System;
  2. using System.Drawing;
  3. using System.Diagnostics;
  4. using System.Runtime.InteropServices;
  5. using System.ComponentModel;
  6. using System.Windows.Forms;
  7. using System.Collections;
  8. using System.Drawing.Drawing2D;
  9. using UtilityLibrary.Win32;
  10. using UtilityLibrary.General;
  11. namespace UtilityLibrary.WinControls
  12. {
  13. #region Enumerations
  14. public enum ThumbDraggedFireFrequency
  15. {
  16. MouseMove,
  17. MouseUp
  18. }
  19. #endregion
  20. #region Delegates
  21. public delegate void ThumbHandler(object sender, int delta);
  22. #endregion
  23. /// <summary>
  24. /// 
  25. /// </summary>
  26. [ToolboxItem(false)]
  27. // I wanted to create this class as an abstract base class
  28. // for the VScroolBarEx and the HScrollBarEx but the designer
  29. // has problems creating derived classes that have as their base
  30. // classes anything other than public classes
  31. // --It is frustrating that you cannot fully apply the idioms of the languages
  32. // because the IDE Designer and the reflection implementation fail to
  33. // honor those idioms--
  34. public class ScrollBarEx : System.Windows.Forms.Control
  35. {
  36. #region Events
  37. public event EventHandler StartingAutomaticScrolling = null;
  38. public event EventHandler StoppingAutomaticScrolling = null;
  39. public event EventHandler ThumbReleased = null;
  40. #endregion
  41. #region Class Variables
  42.         
  43. // Constants
  44. protected const int GRIPPER_WIDTH = 8;
  45. protected const int GRIPPER_HEIGHT = 8;
  46. protected const int MINIMUM_THUMB_WITH_GRIPPER_SIZE = 12;
  47. protected const int TIMER_INTERVAL = 200;
  48.         
  49. // Parent control for the scrollbar
  50. protected Control parentWindow;
  51. // property backing variables
  52. int hThumb = -1;
  53. int vThumb = -1;
  54. int borderGap = 0;
  55. protected int min = 0;
  56. protected int max = 100;
  57. protected double pos = 0;
  58. protected double previousPos = 0;
  59. protected int smallChange = 10;
  60. protected int largeChange = 20;
  61. protected ThumbDraggedFireFrequency dragFrequency = ThumbDraggedFireFrequency.MouseMove;
  62. // Standard scrollbars properties
  63. protected Color backgroundColor = Color.Empty;
  64. protected Color foregroundColor = Color.Empty;
  65. protected Color borderColor = Color.Empty;
  66. protected Color arrowColor = Color.Empty;
  67. protected Color gripperLightColor = Color.Empty;
  68. protected Color gripperDarkColor = Color.Empty;
  69. protected Color hoverColor = Color.Empty;
  70. protected Color pressedColor = Color.Empty;
  71. protected Color gradientStartBackgroundColor = Color.Empty;
  72. protected Color gradientEndBackgroundColor = Color.Empty;
  73. protected Color gradientStartForegroundColor = Color.Empty;
  74. protected Color gradientEndForegroundColor = Color.Empty;
  75. // Skin support
  76. protected ImageList thumbImageList = null;
  77. protected Image scrollShaftImage = null;
  78. protected ImageList upArrowImageList = null;
  79. protected ImageList downArrowImageList = null;
  80.                 
  81. // Keep track of the UI element state
  82. protected DrawState thumbDrawState = DrawState.Normal;
  83. // Other helper variables
  84. protected bool stopAutomaticScrolling = false;
  85. // Keeps track of the ScrollBar objects constructed
  86. // so that we can transparently--to the user--check if
  87. // an horizontal and vertical bars are both being used
  88. // on the same parent window to be able to leave the 
  89. // lower right corner empty space that avoids the two
  90. // scrollbars overlapping on the arrow button
  91. static ArrayList scrollBarList = new ArrayList();
  92. protected bool usingBothScrollBars = false;
  93. // Miscellaneous
  94. protected bool drawGripper = true;
  95.                 
  96. #endregion
  97. #region Constructors
  98. public ScrollBarEx()
  99. {
  100. }
  101. public ScrollBarEx(Control parentControl)
  102. {
  103. // We are going to do all of the painting so better 
  104. // setup the control to use double buffering
  105. SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.ResizeRedraw|
  106. ControlStyles.Opaque|ControlStyles.UserPaint|ControlStyles.DoubleBuffer, true);
  107. TabStop = false;
  108. hThumb = WindowsAPI.GetSystemMetrics(SystemMetricsCodes.SM_CXHTHUMB);
  109. vThumb = WindowsAPI.GetSystemMetrics(SystemMetricsCodes.SM_CYVTHUMB);
  110. parentWindow = parentControl;
  111. parentWindow.SizeChanged += new EventHandler(ParentSizeChanged);
  112. // Need to check setting of flag
  113. CheckForUsingBothScrollBarsFlag(this);
  114. scrollBarList.Add(this);
  115. }
  116. #endregion
  117. #region Overrides
  118. protected override void OnHandleCreated(EventArgs e)
  119. {
  120. base.OnHandleCreated(e);
  121. // Set the parent for the scrollBar
  122. WindowsAPI.SetParent(Handle, parentWindow.Handle);
  123. SizeScrollBar();
  124. }
  125. protected override void OnPaint(PaintEventArgs pe)
  126. {
  127. base.OnPaint(pe);
  128. Graphics g = pe.Graphics;
  129. DrawScrollBar(g);
  130. }
  131. protected override  void WndProc(ref Message message)
  132. {
  133. base.WndProc(ref message);
  134. switch (message.Msg)
  135. {
  136. case (int)Msg.WM_LBUTTONUP:
  137. stopAutomaticScrolling = true;
  138. break;
  139. default:
  140. break;
  141. }
  142. }
  143. #endregion
  144. #region Virtuals
  145. // Need to be implemented by a derived class
  146. // This shoud have been abstract methods but 
  147. // because of the comments at the class declaration
  148. // above, this could not be
  149. protected virtual void SizeScrollBar()
  150. {
  151.             
  152. }
  153. protected virtual void DrawScrollBar(Graphics g)
  154. {
  155. }
  156. protected virtual Rectangle GetThumbRect()
  157. {
  158. return Rectangle.Empty;
  159. }
  160. protected virtual void DrawBackground(Graphics g)
  161. {
  162. Rectangle rc = ClientRectangle;
  163. Color backColor = SystemColors.ControlLight;
  164. if ( backgroundColor != Color.Empty )
  165. backColor = BackgroundColor;
  166. if ( scrollShaftImage != null )
  167. {
  168. // Draw background bitmap
  169. g.DrawImage(scrollShaftImage, rc);
  170. }
  171. else if ( gradientStartBackgroundColor != Color.Empty && gradientEndBackgroundColor != Color.Empty )
  172. {
  173. LinearGradientMode mode = LinearGradientMode.Horizontal;
  174. HScrollBarEx hs = this as HScrollBarEx;
  175. if ( hs != null )
  176. mode = LinearGradientMode.Vertical;
  177. using ( LinearGradientBrush b = new LinearGradientBrush( rc, gradientStartBackgroundColor, 
  178. gradientEndBackgroundColor, mode) )
  179. {
  180. g.FillRectangle(b, rc);
  181. }
  182. }
  183. else
  184. {
  185. using ( Brush b = new SolidBrush(backColor) )
  186. {
  187. // Fill background;
  188. g.FillRectangle(b, rc);
  189. }
  190. }
  191. }
  192. protected virtual void DrawFlatArrowButton(Graphics g, Rectangle rc, ArrowGlyph arrowGlyph, DrawState drawState)
  193. {
  194. // Make rectangle 1 pixel smaller
  195. // makes it look nicer
  196. rc.Inflate(-1, -1);
  197. Color border = Color.Empty;
  198. Color background = Color.Empty;
  199. if ( drawState == DrawState.Normal )
  200. {
  201. border = ColorUtil.VSNetBorderColor;
  202. background = ColorUtil.VSNetControlColor;
  203. if ( backgroundColor != Color.Empty )
  204. background = foregroundColor;
  205. }
  206. else if ( drawState == DrawState.Hot )
  207. {
  208. border = ColorUtil.VSNetBorderColor;
  209. background = ColorUtil.VSNetSelectionColor;
  210. if ( hoverColor != Color.Empty )
  211. background = hoverColor;
  212. }
  213. else if ( drawState == DrawState.Pressed )
  214. {
  215. border = ColorUtil.VSNetBorderColor;
  216. background = ColorUtil.VSNetPressedColor;
  217. if ( pressedColor != Color.Empty )
  218. background = pressedColor;
  219. }
  220. // Which arrow gyph we need to draw
  221. bool upArrow = (arrowGlyph == ArrowGlyph.Up || arrowGlyph == ArrowGlyph.Left);
  222. bool paintBorder = true;
  223.             
  224. if ( (upArrow && upArrowImageList != null && upArrowImageList.Images.Count > (int)drawState)
  225. || (!upArrow && downArrowImageList != null && downArrowImageList.Images.Count > (int)drawState) )
  226. {
  227. if ( upArrow )
  228. g.DrawImage(upArrowImageList.Images[(int)drawState], rc);
  229. else
  230. g.DrawImage(downArrowImageList.Images[(int)drawState], rc);
  231. paintBorder = false;
  232. }
  233. else if ( gradientStartForegroundColor != Color.Empty && gradientEndForegroundColor != Color.Empty 
  234. && drawState == DrawState.Normal )
  235. {
  236. using ( LinearGradientBrush b = new LinearGradientBrush( rc, gradientStartForegroundColor, 
  237. gradientEndForegroundColor, LinearGradientMode.Horizontal) )
  238. {
  239. g.FillRectangle(b, rc);
  240. }
  241. }
  242. else
  243. {
  244. using ( Brush b = new SolidBrush(background) )
  245. {
  246. // Fill background;
  247. g.FillRectangle(b, rc);
  248. }
  249. }
  250. // Check if the user set custom colors
  251. if ( borderColor != Color.Empty )
  252. border = borderColor;
  253. using ( Pen p = new Pen(border) )
  254. {
  255. if ( paintBorder )
  256.                     g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
  257. Color arrow = Color.Black;
  258. if ( arrowColor != Color.Empty )
  259. arrow = arrowColor;
  260. using ( Brush b = new SolidBrush(arrow) ) 
  261. {
  262. GDIUtil.DrawArrowGlyph(g, rc, 7, 4, arrowGlyph, b);
  263. }
  264. }
  265. }
  266. protected virtual void DrawThumb(Graphics g, DrawState drawState)
  267. {
  268. Rectangle rc = GetThumbRect();
  269. Color border = Color.Empty;
  270. Color background = Color.Empty;
  271. if ( drawState == DrawState.Normal )
  272. {
  273. border = ColorUtil.VSNetBorderColor;
  274. background = ColorUtil.VSNetControlColor;
  275. if ( backgroundColor != Color.Empty )
  276. background = foregroundColor;
  277. }
  278. else if ( drawState == DrawState.Hot )
  279. {
  280. border = ColorUtil.VSNetBorderColor;
  281. background = ColorUtil.VSNetSelectionColor;
  282. if ( hoverColor != Color.Empty )
  283. background = hoverColor;
  284. }
  285. else if ( drawState == DrawState.Pressed )
  286. {
  287. border = ColorUtil.VSNetBorderColor;
  288. background = ColorUtil.VSNetPressedColor;
  289. if ( pressedColor != Color.Empty )
  290. background = pressedColor;
  291. }
  292. // Paint border by default
  293. bool paintBorder = true;
  294.             
  295. if ( thumbImageList != null && thumbImageList.Images.Count > (int)drawState )
  296. {
  297. VScrollBarEx vScrollBarEx = this as VScrollBarEx;
  298. bool verticalScrollBar = ( vScrollBarEx != null);
  299. Image image = thumbImageList.Images[(int)drawState];
  300. // We need to draw the thumb in chunks to avoid distorting the thumb image
  301. // We are assuming that the corners of the image require at most 10 pixel
  302. // on both size, the rest will be the area we strech
  303. if ( !verticalScrollBar )
  304. {
  305. // Draw start corner
  306. if ( rc.Width > GRIPPER_WIDTH*2 )
  307. {
  308. g.DrawImage(image, new Rectangle(rc.Left, rc.Top, 10, rc.Height), 
  309. 0, 0, 10, rc.Height, GraphicsUnit.Pixel);
  310. // Draw middle part
  311. g.DrawImage(image, new Rectangle(rc.Left+10, rc.Top, rc.Width-20, rc.Height), 
  312. 10, 0, image.Width-20, rc.Height, GraphicsUnit.Pixel);
  313. // Draw end corner
  314. g.DrawImage(image, new Rectangle(rc.Right-10, rc.Top, 10, rc.Height), 
  315. image.Width-10, 0, 10, rc.Height, GraphicsUnit.Pixel);
  316. }
  317. else
  318. {
  319. // Width is too small, just draw the image
  320.                         g.DrawImage(image, rc);
  321. }
  322. }
  323. else
  324. {
  325. if ( rc.Height > GRIPPER_HEIGHT*2 )
  326. {
  327. // Draw start corner
  328. g.DrawImage(image, new Rectangle(rc.Left, rc.Top, rc.Width, 10), 
  329. 0, 0, rc.Width, 10, GraphicsUnit.Pixel);
  330. // Draw middle part
  331. g.DrawImage(image, new Rectangle(rc.Left, rc.Top+10, rc.Width, rc.Height-20), 
  332. 0, 10, rc.Width, image.Height - 20, GraphicsUnit.Pixel);
  333. // Draw end corner
  334. g.DrawImage(image, new Rectangle(rc.Left, rc.Bottom-10, rc.Width, 10), 
  335. 0, image.Height-10, rc.Width, 10, GraphicsUnit.Pixel);
  336. }
  337. else
  338. {
  339. // Height is too small, just draw the image
  340. g.DrawImage(image, rc);
  341. }
  342. }
  343.                 paintBorder = false;
  344. }
  345. else if ( gradientStartForegroundColor != Color.Empty && gradientEndForegroundColor != Color.Empty )
  346. {
  347. Color startColor = gradientStartForegroundColor;
  348. if ( drawState == DrawState.Hot || drawState == DrawState.Pressed )
  349. startColor = background;
  350. LinearGradientMode mode = LinearGradientMode.Horizontal;
  351. HScrollBarEx hs = this as HScrollBarEx;
  352. if ( hs != null )
  353. mode = LinearGradientMode.Vertical;
  354. using ( LinearGradientBrush b = new LinearGradientBrush( rc, startColor, 
  355. gradientEndForegroundColor, mode) )
  356. {
  357. g.FillRectangle(b, rc);
  358. }
  359. }
  360. else
  361. {
  362. using ( Brush b = new SolidBrush(background) )
  363. {
  364. // Fill background;
  365. g.FillRectangle(b, rc);
  366. }
  367. }
  368. if ( paintBorder )
  369. {
  370. // If border color was set by the user
  371. if ( borderColor != Color.Empty )
  372. border = borderColor;
  373. using ( Pen p = new Pen(border) )
  374. {
  375. g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
  376. }
  377. }
  378. }
  379. #endregion
  380. #region Properties 
  381. public int Position
  382. {
  383. set
  384. {
  385. if ( pos != value )
  386. {
  387. previousPos = pos;
  388. int newValue = value;
  389. if ( newValue >= max-largeChange ) 
  390. {
  391. // Position cannot be larger than
  392. // max-largeChange
  393. pos = max-largeChange;
  394. }
  395. else if ( newValue < 0 )
  396. {
  397. // Negative values don't make sense
  398. pos = 0;
  399. }
  400. else
  401. pos = newValue;
  402. if ( previousPos != pos )
  403. Invalidate();
  404. }
  405. else
  406. previousPos = pos;
  407. }
  408. get 
  409. {
  410. return (int)pos;
  411. }
  412. }
  413. public int VThumb
  414. {
  415. get { return vThumb;}
  416. }
  417. public int HThumb
  418. {
  419. get { return hThumb;}
  420. }
  421. public int BorderGap
  422. {
  423. set { borderGap = value;}
  424. get { return borderGap; }
  425. }
  426. public int SmallChange
  427. {
  428. set 
  429. {
  430. if ( value < min || value > max)
  431. smallChange = 1;
  432. smallChange = value;
  433. }
  434. get { return smallChange;}
  435. }
  436. public int LargeChange
  437. {
  438. set 
  439. {
  440. if ( value < min || value > max )
  441. largeChange = 1;
  442. largeChange = value;
  443. }
  444. get { return largeChange;}
  445. }
  446. public int Minimum
  447. {
  448. set { min = value;}
  449. get { return min; }
  450. }
  451. public int Maximum
  452. {
  453. set { max = value;}
  454. get { return max; }
  455. }
  456. public int PreviousPosition
  457. {
  458. get { return (int)previousPos; }
  459. }
  460. public ThumbDraggedFireFrequency ThumbDraggedFireFrequency
  461. {
  462. set { dragFrequency = value; }
  463. get { return dragFrequency; }
  464. }
  465. public Color BackgroundColor
  466. {
  467. set { backgroundColor = value;}
  468. get { return backgroundColor; }
  469. }
  470. public Color ForegroundColor
  471. {
  472. set { foregroundColor = value;}
  473. get { return foregroundColor; }
  474. }
  475. public Color BorderColor
  476. {
  477. set { borderColor = value;}
  478. get { return borderColor; }
  479. }
  480. public Color PressedColor
  481. {
  482. set { pressedColor = value;}
  483. get { return pressedColor; }
  484. }
  485. public Color HoverColor
  486. {
  487. set { hoverColor = value;}
  488. get { return hoverColor; }
  489. }
  490. public Color ArrowColor
  491. {
  492. set { arrowColor = value;}
  493. get { return arrowColor; }
  494. }
  495. public Color GripperLightColor
  496. {
  497. set { gripperLightColor = value;}
  498. get { return gripperLightColor; }
  499. }
  500. public Color GripperDarkColor
  501. {
  502. set { gripperDarkColor = value;}
  503. get { return gripperDarkColor; }
  504. }
  505.                 
  506. public bool UsingBothScrollBars
  507. {
  508. set { usingBothScrollBars = value; }
  509. get { return usingBothScrollBars; }
  510. }
  511. public bool DrawGripper
  512. {
  513. set { 
  514. drawGripper = value;
  515. Invalidate();
  516. }
  517. get { return drawGripper; }
  518. }
  519. public Color GradientStartBackgroundColor
  520. {
  521. set { gradientStartBackgroundColor = value;}
  522. get { return gradientStartBackgroundColor; }
  523. }
  524. public Color GradientEndBackgroundColor
  525. {
  526. set { gradientEndBackgroundColor = value;}
  527. get { return gradientEndBackgroundColor; }
  528. }
  529. public Color GradientStartForegroundColor
  530. {
  531. set { gradientStartForegroundColor = value;}
  532. get { return gradientStartForegroundColor; }
  533. }
  534. public Color GradientEndForegroundColor
  535. {
  536. set { gradientEndForegroundColor = value;}
  537. get { return gradientEndForegroundColor; }
  538. }
  539. public ImageList ThumbImageList
  540. {
  541. set { thumbImageList = value; }
  542. get { return thumbImageList; }
  543. }
  544. public Image ScrollShaftImage
  545. {
  546. set { scrollShaftImage = value; }
  547. get { return scrollShaftImage; }
  548. }
  549. #endregion
  550. #region Implementation
  551. void CheckForUsingBothScrollBarsFlag(ScrollBarEx scrollBar)
  552. {
  553. for ( int i = 0; i < scrollBarList.Count; i++ )
  554. {
  555. ScrollBarEx currentScrollBar = (ScrollBarEx)scrollBarList[i];
  556. Debug.Assert(currentScrollBar != null);
  557. if ( currentScrollBar.parentWindow == scrollBar.parentWindow )
  558. {
  559. if ( currentScrollBar.GetType() != scrollBar.GetType() )
  560. {
  561. currentScrollBar.usingBothScrollBars = true;
  562. scrollBar.usingBothScrollBars = true;
  563. }
  564. }
  565. }
  566. }
  567. void ParentSizeChanged(object sender, EventArgs e)
  568. {
  569. SizeScrollBar();
  570. }
  571. protected void FireStartingAutomaticScrolling()
  572. {
  573. if ( StartingAutomaticScrolling != null )
  574. StartingAutomaticScrolling(this, EventArgs.Empty);
  575. }
  576. protected void FireStoppingAutomaticScrolling()
  577. {
  578. if ( StoppingAutomaticScrolling != null )
  579. StoppingAutomaticScrolling(this, EventArgs.Empty);
  580. }
  581. protected void FireThumbRelease()
  582. {
  583. if ( ThumbReleased != null )
  584. ThumbReleased(this, EventArgs.Empty);
  585. }
  586. #endregion
  587. }
  588. }