FrameControl.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows.Forms;
  9. namespace DllXqManager
  10. {
  11. public class FrameControl : UserControl
  12. {
  13. #region Constructors
  14. /// <summary>
  15. /// 构造函数
  16. /// </summary>
  17. public FrameControl(Control ctrl)
  18. {
  19. baseControl = ctrl;
  20. AddEvents();
  21. CreateBounds();
  22. }
  23. #endregion
  24. #region Fields
  25. const int Band = 6; //调整大小的响应边框
  26. private int MinWidth = 20; //最小宽度
  27. private int MinHeight = 20;//最小高度
  28. Size square = new Size(Band, Band);//小矩形大小
  29. public Control baseControl; //基础控件,即被包围的控件
  30. Rectangle[] smallRects = new Rectangle[8];//边框中的八个小圆圈
  31. Rectangle[] sideRects = new Rectangle[4];//四条边框,用来做响应区域
  32. Point[] linePoints = new Point[5];//四条边,用于画虚线
  33. Graphics g; //画图板
  34. Rectangle ControlRect; //控件包含边框的区域
  35. private Point pPoint; //上个鼠标坐标
  36. private Point cPoint; //当前鼠标坐标
  37. private MousePosOnCtrl mpoc;
  38. #endregion
  39. #region Properties
  40. /// <summary>
  41. /// 鼠标在控件中位置
  42. /// </summary>
  43. enum MousePosOnCtrl
  44. {
  45. NONE = 0,
  46. TOP = 1,
  47. RIGHT = 2,
  48. BOTTOM = 3,
  49. LEFT = 4,
  50. TOPLEFT = 5,
  51. TOPRIGHT = 6,
  52. BOTTOMLEFT = 7,
  53. BOTTOMRIGHT = 8,
  54. }
  55. #endregion
  56. #region Methods
  57. /// <summary>
  58. /// 加载事件
  59. /// </summary>
  60. private void AddEvents()
  61. {
  62. this.Name = "FrameControl" + baseControl.Name;
  63. this.MouseDown += new MouseEventHandler(FrameControl_MouseDown);
  64. this.MouseMove += new MouseEventHandler(FrameControl_MouseMove);
  65. this.MouseUp += new MouseEventHandler(FrameControl_MouseUp);
  66. }
  67. #region 创建边框
  68. /// <summary>
  69. /// 建立控件可视区域
  70. /// </summary>
  71. private void CreateBounds()
  72. {
  73. //创建边界
  74. int X = baseControl.Bounds.X - square.Width - 1;
  75. int Y = baseControl.Bounds.Y - square.Height - 1;
  76. int Height = baseControl.Bounds.Height + (square.Height * 2) + 2;
  77. int Width = baseControl.Bounds.Width + (square.Width * 2) + 2;
  78. this.Bounds = new Rectangle(X, Y, Width, Height);
  79. this.BringToFront();
  80. SetRectangles();
  81. //设置可视区域
  82. this.Region = new Region(BuildFrame());
  83. g = this.CreateGraphics();
  84. }
  85. /// <summary>
  86. /// 设置定义8个小矩形的范围
  87. /// </summary>
  88. void SetRectangles()
  89. {
  90. //左上
  91. smallRects[0] = new Rectangle(new Point(0, 0), square);
  92. //右上
  93. smallRects[1] = new Rectangle(new Point(this.Width - square.Width - 1, 0), square);
  94. //左下
  95. smallRects[2] = new Rectangle(new Point(0, this.Height - square.Height - 1), square);
  96. //右下
  97. smallRects[3] = new Rectangle(new Point(this.Width - square.Width - 1, this.Height - square.Height - 1), square);
  98. //上中
  99. smallRects[4] = new Rectangle(new Point(this.Width / 2 - 1, 0), square);
  100. //下中
  101. smallRects[5] = new Rectangle(new Point(this.Width / 2 - 1, this.Height - square.Height - 1), square);
  102. //左中
  103. smallRects[6] = new Rectangle(new Point(0, this.Height / 2 - 1), square);
  104. //右中
  105. smallRects[7] = new Rectangle(new Point(square.Width + baseControl.Width + 1, this.Height / 2 - 1), square);
  106. //四条边线
  107. //左上
  108. linePoints[0] = new Point(square.Width / 2, square.Height / 2);
  109. //右上
  110. linePoints[1] = new Point(this.Width - square.Width / 2 - 1, square.Height / 2);
  111. //右下
  112. linePoints[2] = new Point(this.Width - square.Width / 2 - 1, this.Height - square.Height / 2);
  113. //左下
  114. linePoints[3] = new Point(square.Width / 2, this.Height - square.Height / 2 - 1);
  115. //左上
  116. linePoints[4] = new Point(square.Width / 2, square.Height / 2);
  117. //整个包括周围边框的范围
  118. ControlRect = new Rectangle(new Point(0, 0), this.Bounds.Size);
  119. }
  120. /// <summary>
  121. /// 设置边框控件可视区域
  122. /// </summary>
  123. /// <returns></returns>
  124. private GraphicsPath BuildFrame()
  125. {
  126. GraphicsPath path = new GraphicsPath();
  127. //上边框
  128. sideRects[0] = new Rectangle(0, 0, this.Width - square.Width - 1, square.Height + 1);
  129. //左边框
  130. sideRects[1] = new Rectangle(0, square.Height + 1, square.Width + 1, this.Height - square.Height - 1);
  131. //下边框
  132. sideRects[2] = new Rectangle(square.Width + 1, this.Height - square.Height - 1, this.Width - square.Width - 1, square.Height + 1);
  133. //右边框
  134. sideRects[3] = new Rectangle(this.Width - square.Width - 1, 0, square.Width + 1, this.Height - square.Height - 1);
  135. path.AddRectangle(sideRects[0]);
  136. path.AddRectangle(sideRects[1]);
  137. path.AddRectangle(sideRects[2]);
  138. path.AddRectangle(sideRects[3]);
  139. return path;
  140. }
  141. #endregion
  142. /// <summary>
  143. /// 绘图
  144. /// </summary>
  145. public void Draw()
  146. {
  147. this.BringToFront();
  148. //g.FillRectangles(Brushes.LightGray, sideRects); //填充四条边框的内部
  149. Pen pen = new Pen(Color.Black);
  150. pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果
  151. g.DrawLines(pen, linePoints);//绘制四条边线
  152. g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部
  153. foreach (Rectangle smallRect in smallRects)
  154. {
  155. g.DrawEllipse(Pens.Black, smallRect); //绘制8个小椭圆
  156. }
  157. //g.DrawRectangles(Pens.Black, smallRects); //绘制8个小矩形的黑色边线
  158. }
  159. /// <summary>
  160. /// 设置光标状态
  161. /// </summary>
  162. public bool SetCursorShape(int x, int y)
  163. {
  164. Point point = new Point(x, y);
  165. if (!ControlRect.Contains(point))
  166. {
  167. Cursor.Current = Cursors.Arrow;
  168. return false;
  169. }
  170. else if (smallRects[0].Contains(point))
  171. {
  172. Cursor.Current = Cursors.SizeNWSE;
  173. mpoc = MousePosOnCtrl.TOPLEFT;
  174. }
  175. else if (smallRects[1].Contains(point))
  176. {
  177. Cursor.Current = Cursors.SizeNESW;
  178. mpoc = MousePosOnCtrl.TOPRIGHT;
  179. }
  180. else if (smallRects[2].Contains(point))
  181. {
  182. Cursor.Current = Cursors.SizeNESW;
  183. mpoc = MousePosOnCtrl.BOTTOMLEFT;
  184. }
  185. else if (smallRects[3].Contains(point))
  186. {
  187. Cursor.Current = Cursors.SizeNWSE;
  188. mpoc = MousePosOnCtrl.BOTTOMRIGHT;
  189. }
  190. else if (sideRects[0].Contains(point))
  191. {
  192. Cursor.Current = Cursors.SizeNS;
  193. mpoc = MousePosOnCtrl.TOP;
  194. }
  195. else if (sideRects[1].Contains(point))
  196. {
  197. Cursor.Current = Cursors.SizeWE;
  198. mpoc = MousePosOnCtrl.LEFT;
  199. }
  200. else if (sideRects[2].Contains(point))
  201. {
  202. Cursor.Current = Cursors.SizeNS;
  203. mpoc = MousePosOnCtrl.BOTTOM;
  204. }
  205. else if (sideRects[3].Contains(point))
  206. {
  207. Cursor.Current = Cursors.SizeWE;
  208. mpoc = MousePosOnCtrl.RIGHT;
  209. }
  210. else
  211. {
  212. Cursor.Current = Cursors.Arrow;
  213. }
  214. return true;
  215. }
  216. /// <summary>
  217. /// 控件移动
  218. /// </summary>
  219. private void ControlMove()
  220. {
  221. cPoint = Cursor.Position;
  222. int x = cPoint.X - pPoint.X;
  223. int y = cPoint.Y - pPoint.Y;
  224. switch (this.mpoc)
  225. {
  226. case MousePosOnCtrl.TOP:
  227. if (baseControl.Height - y > MinHeight)
  228. {
  229. baseControl.Top += y;
  230. baseControl.Height -= y;
  231. }
  232. else
  233. {
  234. baseControl.Top -= MinHeight - baseControl.Height;
  235. baseControl.Height = MinHeight;
  236. }
  237. break;
  238. case MousePosOnCtrl.BOTTOM:
  239. if (baseControl.Height + y > MinHeight)
  240. {
  241. baseControl.Height += y;
  242. }
  243. else
  244. {
  245. baseControl.Height = MinHeight;
  246. }
  247. break;
  248. case MousePosOnCtrl.LEFT:
  249. if (baseControl.Width - x > MinWidth)
  250. {
  251. baseControl.Left += x;
  252. baseControl.Width -= x;
  253. }
  254. else
  255. {
  256. baseControl.Left -= MinWidth - baseControl.Width;
  257. baseControl.Width = MinWidth;
  258. }
  259. break;
  260. case MousePosOnCtrl.RIGHT:
  261. if (baseControl.Width + x > MinWidth)
  262. {
  263. baseControl.Width += x;
  264. }
  265. else
  266. {
  267. baseControl.Width = MinWidth;
  268. }
  269. break;
  270. case MousePosOnCtrl.TOPLEFT:
  271. if (baseControl.Height - y > MinHeight)
  272. {
  273. baseControl.Top += y;
  274. baseControl.Height -= y;
  275. }
  276. else
  277. {
  278. baseControl.Top -= MinHeight - baseControl.Height;
  279. baseControl.Height = MinHeight;
  280. }
  281. if (baseControl.Width - x > MinWidth)
  282. {
  283. baseControl.Left += x;
  284. baseControl.Width -= x;
  285. }
  286. else
  287. {
  288. baseControl.Left -= MinWidth - baseControl.Width;
  289. baseControl.Width = MinWidth;
  290. }
  291. break;
  292. case MousePosOnCtrl.TOPRIGHT:
  293. if (baseControl.Height - y > MinHeight)
  294. {
  295. baseControl.Top += y;
  296. baseControl.Height -= y;
  297. }
  298. else
  299. {
  300. baseControl.Top -= MinHeight - baseControl.Height;
  301. baseControl.Height = MinHeight;
  302. }
  303. if (baseControl.Width + x > MinWidth)
  304. {
  305. baseControl.Width += x;
  306. }
  307. else
  308. {
  309. baseControl.Width = MinWidth;
  310. }
  311. break;
  312. case MousePosOnCtrl.BOTTOMLEFT:
  313. if (baseControl.Height + y > MinHeight)
  314. {
  315. baseControl.Height += y;
  316. }
  317. else
  318. {
  319. baseControl.Height = MinHeight;
  320. }
  321. if (baseControl.Width - x > MinWidth)
  322. {
  323. baseControl.Left += x;
  324. baseControl.Width -= x;
  325. }
  326. else
  327. {
  328. baseControl.Left -= MinWidth - baseControl.Width;
  329. baseControl.Width = MinWidth;
  330. }
  331. break;
  332. case MousePosOnCtrl.BOTTOMRIGHT:
  333. if (baseControl.Height + y > MinHeight)
  334. {
  335. baseControl.Height += y;
  336. }
  337. else
  338. {
  339. baseControl.Height = MinHeight;
  340. }
  341. if (baseControl.Width + x > MinWidth)
  342. {
  343. baseControl.Width += x;
  344. }
  345. else
  346. {
  347. baseControl.Width = MinWidth;
  348. }
  349. break;
  350. }
  351. pPoint = Cursor.Position;
  352. }
  353. #endregion
  354. #region Events
  355. /// <summary>
  356. /// 鼠标按下事件:记录当前鼠标相对窗体的坐标
  357. /// </summary>
  358. void FrameControl_MouseDown(object sender, MouseEventArgs e)
  359. {
  360. pPoint = Cursor.Position;
  361. SetCursorShape(e.X, e.Y); //更新鼠标指针样式
  362. }
  363. /// <summary>
  364. /// 鼠标移动事件:让控件跟着鼠标移动
  365. /// </summary>
  366. void FrameControl_MouseMove(object sender, MouseEventArgs e)
  367. {
  368. if (e.Button == MouseButtons.Left)
  369. {
  370. this.Visible = false;
  371. MoveControl.DrawDragBound(baseControl);
  372. ControlMove();
  373. }
  374. else
  375. {
  376. this.Visible = true;
  377. SetCursorShape(e.X, e.Y); //更新鼠标指针样式
  378. }
  379. }
  380. /// <summary>
  381. /// 鼠标弹起事件:让自定义的边框出现
  382. /// </summary>
  383. void FrameControl_MouseUp(object sender, MouseEventArgs e)
  384. {
  385. this.baseControl.Refresh(); //刷掉黑色边框
  386. this.Visible = true;
  387. CreateBounds();
  388. Draw();
  389. MoveControl.ClearFrameControl();
  390. MoveControl.AddFrameControl();
  391. }
  392. #endregion
  393. private void InitializeComponent()
  394. {
  395. this.SuspendLayout();
  396. //
  397. // FrameControl
  398. //
  399. this.Name = "FrameControl";
  400. this.Size = new System.Drawing.Size(165, 145);
  401. this.ResumeLayout(false);
  402. }
  403. }
  404. }