InertButton.cs
上传用户:szlfmled
上传日期:2020-11-22
资源大小:978k
文件大小:14k
源码类别:

C#编程

开发平台:

C#

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Windows.Forms;
  5. using System.ComponentModel;
  6. namespace DockSample.Customization
  7. {
  8. internal class InertButton : Button
  9. {
  10. private enum RepeatClickStatus
  11. {
  12. Disabled,
  13. Started,
  14. Repeating,
  15. Stopped
  16. }
  17. private class RepeatClickEventArgs : EventArgs
  18. {
  19. private static RepeatClickEventArgs _empty;
  20. static RepeatClickEventArgs()
  21. {
  22. _empty = new RepeatClickEventArgs();
  23. }
  24. public new static RepeatClickEventArgs Empty
  25. {
  26. get { return _empty; }
  27. }
  28. }
  29. private IContainer components = new Container();
  30. private int m_borderWidth = 1;
  31. private bool m_mouseOver = false;
  32. private bool m_mouseCapture = false;
  33. private bool m_isPopup = false;
  34. private Image m_imageEnabled = null;
  35. private Image m_imageDisabled = null;
  36. private int m_imageIndexEnabled = -1;
  37. private int m_imageIndexDisabled = -1;
  38. private bool m_monochrom = true;
  39. private ToolTip m_toolTip = null;
  40. private string m_toolTipText = "";
  41. private Color m_borderColor = Color.Empty;
  42. public InertButton()
  43. {
  44. InternalConstruct(null, null);
  45. }
  46. public InertButton(Image imageEnabled)
  47. {
  48. InternalConstruct(imageEnabled, null);
  49. }
  50. public InertButton(Image imageEnabled, Image imageDisabled)
  51. {
  52. InternalConstruct(imageEnabled, imageDisabled);
  53. }
  54. private void InternalConstruct(Image imageEnabled, Image imageDisabled)
  55. {
  56. // Remember parameters
  57. ImageEnabled = imageEnabled;
  58. ImageDisabled = imageDisabled;
  59. // Prevent drawing flicker by blitting from memory in WM_PAINT
  60. SetStyle(ControlStyles.ResizeRedraw, true);
  61. SetStyle(ControlStyles.UserPaint, true);
  62. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  63. // Prevent base class from trying to generate double click events and
  64. // so testing clicks against the double click time and rectangle. Getting
  65. // rid of this allows the user to press then release button very quickly.
  66. //SetStyle(ControlStyles.StandardDoubleClick, false);
  67. // Should not be allowed to select this control
  68. SetStyle(ControlStyles.Selectable, false);
  69. m_timer = new Timer();
  70. m_timer.Enabled = false;
  71. m_timer.Tick += new EventHandler(Timer_Tick);
  72. }
  73. protected override void Dispose(bool disposing)
  74. {
  75. if (disposing)
  76. {
  77. if (components != null)
  78. components.Dispose();
  79. }
  80. base.Dispose(disposing);
  81. }
  82. public Color BorderColor
  83. {
  84. get { return m_borderColor; }
  85. set
  86. {
  87. if (m_borderColor != value)
  88. {
  89. m_borderColor = value;
  90. Invalidate();
  91. }
  92. }
  93. }
  94. private bool ShouldSerializeBorderColor()
  95. {
  96. return (m_borderColor != Color.Empty);
  97. }
  98. public int BorderWidth
  99. {
  100. get { return m_borderWidth; }
  101. set
  102. {
  103. if (value < 1)
  104. value = 1;
  105. if (m_borderWidth != value)
  106. {
  107. m_borderWidth = value;
  108. Invalidate();
  109. }
  110. }
  111. }
  112. public Image ImageEnabled
  113. {
  114. get
  115. if (m_imageEnabled != null)
  116. return m_imageEnabled;
  117. try
  118. {
  119. if (ImageList == null || ImageIndexEnabled == -1)
  120. return null;
  121. else
  122. return ImageList.Images[m_imageIndexEnabled];
  123. }
  124. catch
  125. {
  126. return null;
  127. }
  128. }
  129. set
  130. {
  131. if (m_imageEnabled != value)
  132. {
  133. m_imageEnabled = value;
  134. Invalidate();
  135. }
  136. }
  137. }
  138. private bool ShouldSerializeImageEnabled()
  139. {
  140. return (m_imageEnabled != null);
  141. }
  142. public Image ImageDisabled
  143. {
  144. get
  145. {
  146. if (m_imageDisabled != null)
  147. return m_imageDisabled;
  148. try
  149. {
  150. if (ImageList == null || ImageIndexDisabled == -1)
  151. return null;
  152. else
  153. return ImageList.Images[m_imageIndexDisabled];
  154. }
  155. catch
  156. {
  157. return null;
  158. }
  159. }
  160. set
  161. {
  162. if (m_imageDisabled != value)
  163. {
  164. m_imageDisabled = value;
  165. Invalidate();
  166. }
  167. }
  168. }
  169. public int ImageIndexEnabled
  170. {
  171. get { return m_imageIndexEnabled; }
  172. set
  173. {
  174. if (m_imageIndexEnabled != value)
  175. {
  176. m_imageIndexEnabled = value;
  177. Invalidate();
  178. }
  179. }
  180. }
  181. public int ImageIndexDisabled
  182. {
  183. get { return m_imageIndexDisabled; }
  184. set
  185. {
  186. if (m_imageIndexDisabled != value)
  187. {
  188. m_imageIndexDisabled = value;
  189. Invalidate();
  190. }
  191. }
  192. }
  193. public bool IsPopup
  194. {
  195. get { return m_isPopup; }
  196. set
  197. {
  198. if (m_isPopup != value)
  199. {
  200. m_isPopup = value;
  201. Invalidate();
  202. }
  203. }
  204. }
  205. public bool Monochrome
  206. {
  207. get { return m_monochrom; }
  208. set
  209. {
  210. if (value != m_monochrom)
  211. {
  212. m_monochrom = value;
  213. Invalidate();
  214. }
  215. }
  216. }
  217. public bool RepeatClick
  218. {
  219. get { return (ClickStatus != RepeatClickStatus.Disabled); }
  220. set { ClickStatus = RepeatClickStatus.Stopped; }
  221. }
  222. private RepeatClickStatus m_clickStatus = RepeatClickStatus.Disabled;
  223. private RepeatClickStatus ClickStatus
  224. {
  225. get { return m_clickStatus; }
  226. set
  227. {
  228. if (m_clickStatus == value)
  229. return;
  230. m_clickStatus = value;
  231. if (ClickStatus == RepeatClickStatus.Started)
  232. {
  233. Timer.Interval = RepeatClickDelay;
  234. Timer.Enabled = true;
  235. }
  236. else if (ClickStatus == RepeatClickStatus.Repeating)
  237. Timer.Interval = RepeatClickInterval;
  238. else
  239. Timer.Enabled = false;
  240. }
  241. }
  242. private int m_repeatClickDelay = 500;
  243. public int RepeatClickDelay
  244. {
  245. get { return m_repeatClickDelay; } 
  246. set { m_repeatClickDelay = value; }
  247. }
  248. private int m_repeatClickInterval = 100;
  249. public int RepeatClickInterval
  250. {
  251. get { return m_repeatClickInterval; }
  252. set { m_repeatClickInterval = value; }
  253. }
  254. private Timer m_timer;
  255. private Timer Timer
  256. {
  257. get { return m_timer; }
  258. }
  259. public string ToolTipText
  260. {
  261. get { return m_toolTipText; }
  262. set
  263. {
  264. if (m_toolTipText != value)
  265. {
  266. if (m_toolTip == null)
  267. m_toolTip = new ToolTip(this.components);
  268. m_toolTipText = value;
  269. m_toolTip.SetToolTip(this, value);
  270. }
  271. }
  272. }
  273. private void Timer_Tick(object sender, EventArgs e)
  274. {
  275. if (m_mouseCapture && m_mouseOver)
  276. OnClick(RepeatClickEventArgs.Empty);
  277. if (ClickStatus == RepeatClickStatus.Started)
  278. ClickStatus = RepeatClickStatus.Repeating;
  279. }
  280. /// <exclude/>
  281. protected override void OnMouseDown(MouseEventArgs e)
  282. {
  283. base.OnMouseDown(e);
  284. if (e.Button != MouseButtons.Left)
  285. return;
  286. if (m_mouseCapture == false || m_mouseOver == false)
  287. {
  288. m_mouseCapture = true;
  289. m_mouseOver = true;
  290. //Redraw to show button state
  291. Invalidate();
  292. }
  293. if (RepeatClick)
  294. {
  295. OnClick(RepeatClickEventArgs.Empty);
  296. ClickStatus = RepeatClickStatus.Started;
  297. }
  298. }
  299. /// <exclude/>
  300. protected override void OnClick(EventArgs e)
  301. {
  302. if (RepeatClick && !(e is RepeatClickEventArgs))
  303. return;
  304. base.OnClick (e);
  305. }
  306. /// <exclude/>
  307. protected override void OnMouseUp(MouseEventArgs e)
  308. {
  309. base.OnMouseUp(e);
  310. if (e.Button != MouseButtons.Left)
  311. return;
  312. if (m_mouseOver == true || m_mouseCapture == true)
  313. {
  314. m_mouseOver = false;
  315. m_mouseCapture = false;
  316. // Redraw to show button state
  317. Invalidate();
  318. }
  319. if (RepeatClick)
  320. ClickStatus = RepeatClickStatus.Stopped;
  321. }
  322. /// <exclude/>
  323. protected override void OnMouseMove(MouseEventArgs e)
  324. {
  325. base.OnMouseMove(e);
  326. // Is mouse point inside our client rectangle
  327. bool over = this.ClientRectangle.Contains(new Point(e.X, e.Y));
  328. // If entering the button area or leaving the button area...
  329. if (over != m_mouseOver)
  330. {
  331. // Update state
  332. m_mouseOver = over;
  333. // Redraw to show button state
  334. Invalidate();
  335. }
  336. }
  337. /// <exclude/>
  338. protected override void OnMouseEnter(EventArgs e)
  339. {
  340. // Update state to reflect mouse over the button area
  341. if (!m_mouseOver)
  342. {
  343. m_mouseOver = true;
  344. // Redraw to show button state
  345. Invalidate();
  346. }
  347. base.OnMouseEnter(e);
  348. }
  349. /// <exclude/>
  350. protected override void OnMouseLeave(EventArgs e)
  351. {
  352. // Update state to reflect mouse not over the button area
  353. if (m_mouseOver)
  354. {
  355. m_mouseOver = false;
  356. // Redraw to show button state
  357. Invalidate();
  358. }
  359. base.OnMouseLeave(e);
  360. }
  361. /// <exclude/>
  362. protected override void OnPaint(PaintEventArgs e)
  363. {
  364. base.OnPaint(e);
  365. DrawBackground(e.Graphics);
  366. DrawImage(e.Graphics);
  367. DrawText(e.Graphics);
  368. DrawBorder(e.Graphics);
  369. }
  370. private void DrawBackground(Graphics g)
  371. {
  372. using (SolidBrush brush = new SolidBrush(BackColor))
  373. {
  374. g.FillRectangle(brush, ClientRectangle);
  375. }
  376. }
  377. private void DrawImage(Graphics g)
  378. {
  379. Image image = this.Enabled ? ImageEnabled : ((ImageDisabled != null) ? ImageDisabled : ImageEnabled);
  380. ImageAttributes imageAttr = null;
  381. if (null == image)
  382. return;
  383. if (m_monochrom)
  384. {
  385. imageAttr = new ImageAttributes();
  386. // transform the monochrom image
  387. // white -> BackColor
  388. // black -> ForeColor
  389. ColorMap[] colorMap = new ColorMap[2];
  390. colorMap[0] = new ColorMap();
  391. colorMap[0].OldColor = Color.White;
  392. colorMap[0].NewColor = this.BackColor;
  393. colorMap[1] = new ColorMap();
  394. colorMap[1].OldColor = Color.Black;
  395. colorMap[1].NewColor = this.ForeColor;
  396. imageAttr.SetRemapTable(colorMap);
  397. }
  398. Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
  399. if ((!Enabled) && (null == ImageDisabled))
  400. {
  401. using (Bitmap bitmapMono = new Bitmap(image, ClientRectangle.Size))
  402. {
  403. if (imageAttr != null)
  404. {
  405. using (Graphics gMono = Graphics.FromImage(bitmapMono))
  406. {
  407. gMono.DrawImage(image, new Point[3] { new Point(0, 0), new Point(image.Width - 1, 0), new Point(0, image.Height - 1) }, rect, GraphicsUnit.Pixel, imageAttr);
  408. }
  409. }
  410. ControlPaint.DrawImageDisabled(g, bitmapMono, 0, 0, this.BackColor);
  411. }
  412. }
  413. else
  414. {
  415. // Three points provided are upper-left, upper-right and 
  416. // lower-left of the destination parallelogram. 
  417. Point[] pts = new Point[3];
  418. pts[0].X = (Enabled && m_mouseOver && m_mouseCapture) ? 1 : 0;
  419. pts[0].Y = (Enabled && m_mouseOver && m_mouseCapture) ? 1 : 0;
  420. pts[1].X = pts[0].X + ClientRectangle.Width;
  421. pts[1].Y = pts[0].Y;
  422. pts[2].X = pts[0].X;
  423. pts[2].Y = pts[1].Y + ClientRectangle.Height;
  424. if (imageAttr == null)
  425. g.DrawImage(image, pts, rect, GraphicsUnit.Pixel);
  426. else
  427. g.DrawImage(image, pts, rect, GraphicsUnit.Pixel, imageAttr);
  428. }
  429. }
  430. private void DrawText(Graphics g)
  431. {
  432. if (Text == string.Empty)
  433. return;
  434. Rectangle rect = ClientRectangle;
  435. rect.X += BorderWidth;
  436. rect.Y += BorderWidth;
  437. rect.Width -= 2 * BorderWidth;
  438. rect.Height -= 2 * BorderWidth;
  439. StringFormat stringFormat = new StringFormat();
  440. if (TextAlign == ContentAlignment.TopLeft)
  441. {
  442. stringFormat.Alignment = StringAlignment.Near;
  443. stringFormat.LineAlignment = StringAlignment.Near;
  444. }
  445. else if (TextAlign == ContentAlignment.TopCenter)
  446. {
  447. stringFormat.Alignment = StringAlignment.Center;
  448. stringFormat.LineAlignment = StringAlignment.Near;
  449. }
  450. else if (TextAlign == ContentAlignment.TopRight)
  451. {
  452. stringFormat.Alignment = StringAlignment.Far;
  453. stringFormat.LineAlignment = StringAlignment.Near;
  454. }
  455. else if (TextAlign == ContentAlignment.MiddleLeft)
  456. {
  457. stringFormat.Alignment = StringAlignment.Near;
  458. stringFormat.LineAlignment = StringAlignment.Center;
  459. }
  460. else if (TextAlign == ContentAlignment.MiddleCenter)
  461. {
  462. stringFormat.Alignment = StringAlignment.Center;
  463. stringFormat.LineAlignment = StringAlignment.Center;
  464. }
  465. else if (TextAlign == ContentAlignment.MiddleRight)
  466. {
  467. stringFormat.Alignment = StringAlignment.Far;
  468. stringFormat.LineAlignment = StringAlignment.Center;
  469. }
  470. else if (TextAlign == ContentAlignment.BottomLeft)
  471. {
  472. stringFormat.Alignment = StringAlignment.Near;
  473. stringFormat.LineAlignment = StringAlignment.Far;
  474. }
  475. else if (TextAlign == ContentAlignment.BottomCenter)
  476. {
  477. stringFormat.Alignment = StringAlignment.Center;
  478. stringFormat.LineAlignment = StringAlignment.Far;
  479. }
  480. else if (TextAlign == ContentAlignment.BottomRight)
  481. {
  482. stringFormat.Alignment = StringAlignment.Far;
  483. stringFormat.LineAlignment = StringAlignment.Far;
  484. }
  485. using (Brush brush = new SolidBrush(ForeColor))
  486. {
  487. g.DrawString(Text, Font, brush, rect, stringFormat);
  488. }
  489. }
  490. private void DrawBorder(Graphics g)
  491. {
  492. ButtonBorderStyle bs;
  493. // Decide on the type of border to draw around image
  494. if (!this.Enabled)
  495. bs = IsPopup ? ButtonBorderStyle.Outset : ButtonBorderStyle.Solid;
  496. else if (m_mouseOver && m_mouseCapture)
  497. bs = ButtonBorderStyle.Inset;
  498. else if (IsPopup || m_mouseOver)
  499. bs = ButtonBorderStyle.Outset;
  500. else
  501. bs = ButtonBorderStyle.Solid;
  502. Color colorLeftTop;
  503. Color colorRightBottom;
  504. if (bs == ButtonBorderStyle.Solid)
  505. {
  506. colorLeftTop = this.BackColor;
  507. colorRightBottom = this.BackColor;
  508. }
  509. else if (bs == ButtonBorderStyle.Outset)
  510. {
  511. colorLeftTop = m_borderColor.IsEmpty ? this.BackColor : m_borderColor;
  512. colorRightBottom = this.BackColor;
  513. }
  514. else
  515. {
  516. colorLeftTop = this.BackColor;
  517. colorRightBottom = m_borderColor.IsEmpty ? this.BackColor : m_borderColor;
  518. }
  519. ControlPaint.DrawBorder(g, this.ClientRectangle,
  520. colorLeftTop, m_borderWidth, bs,
  521. colorLeftTop, m_borderWidth, bs,
  522. colorRightBottom, m_borderWidth, bs,
  523. colorRightBottom, m_borderWidth, bs);
  524. }
  525. /// <exclude/>
  526. protected override void OnEnabledChanged(EventArgs e)
  527. {
  528. base.OnEnabledChanged(e);
  529. if (Enabled == false)
  530. {
  531. m_mouseOver = false;
  532. m_mouseCapture = false;
  533. if (RepeatClick && ClickStatus != RepeatClickStatus.Stopped)
  534. ClickStatus = RepeatClickStatus.Stopped;
  535. }
  536. Invalidate();
  537. }
  538. }
  539. }