UXrayControl.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Data;
  5. using System.Windows.Forms;
  6. namespace SpectrumSTDEditor
  7. {
  8. public partial class UXrayControl : UserControl
  9. {
  10. // 画能谱图的矩形区域
  11. protected Rectangle m_XrayArea;
  12. protected PointF[] m_xraypointf = null;
  13. protected bool m_bShowElementLines = true;
  14. // 水平刻度分成20等分
  15. protected const int m_iHscale = 20;
  16. protected bool m_bMouseMove = false;
  17. protected Point m_curCurssorPos;
  18. private DataTable dt = null;
  19. private DataRow dr = null;
  20. public DataRow Dr { get => dr; set => dr = value; }
  21. public DataTable Dt { get => dt; set => dt = value; }
  22. public UXrayControl()
  23. {
  24. InitializeComponent();
  25. // 设置双缓冲
  26. SetDoubleBufferByIsDraw();
  27. }
  28. public void SetDoubleBufferByIsDraw()
  29. {
  30. SetStyle(ControlStyles.UserPaint, true);//没什么效果,开与关
  31. SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景,关了闪
  32. this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 双缓冲,关了闪
  33. //上面是必须有的
  34. SetStyle(ControlStyles.UserMouse, true);//执行自己的鼠标行为,这个打开后,在win7下鼠标操作明显改善
  35. }
  36. private void UXrayControl_Load(object sender, EventArgs e)
  37. {
  38. }
  39. private void UXrayControl_Resize(object sender, EventArgs e)
  40. {
  41. this.RefreshCtrl();
  42. //setControls(newx, newy, this.tabSTDStandrad.TabPages[0]);
  43. }
  44. private void UXrayControl_Paint(object sender, PaintEventArgs e)
  45. {
  46. Graphics graphic = e.Graphics;
  47. DrawSpecture(ref graphic);
  48. if (m_bMouseMove)
  49. {
  50. ShowMouseMoveInfo(m_curCurssorPos.X, m_curCurssorPos.Y, ref m_XrayArea, ref graphic);
  51. }
  52. }
  53. public void RefreshCtrl()
  54. {
  55. this.Invalidate();
  56. Graphics graph = Graphics.FromHwnd(this.Handle);
  57. DrawSpecture(ref graph);
  58. m_bMouseMove = false;
  59. }
  60. public void DrawSpecture(ref Graphics graph)
  61. {
  62. // 设置设置能谱的区域大小
  63. // 首先预留出刻度的大小
  64. String strLabel = "99999";
  65. SizeF size = graph.MeasureString(strLabel, this.Font);
  66. // 上下左右四顶点预留2个像素空白, 扣除标签的宽高
  67. // Rectangle XrayArea = new Rectangle();
  68. m_XrayArea.X = 2 + (int)size.Width;
  69. m_XrayArea.Y = 5;
  70. m_XrayArea.Width = this.Width - 2 - m_XrayArea.X;
  71. m_XrayArea.Height = this.Height - 2 - m_XrayArea.Y - (int)size.Height;
  72. Pen pen = new Pen(Color.FromArgb(150, Color.Black), 1);
  73. // 画矩形框
  74. graph.DrawRectangle(pen, m_XrayArea);
  75. // 画横坐标刻度
  76. Point point = new Point();
  77. Point next = new Point();
  78. Point adapt = new Point(); // 微调参数
  79. SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.Black));
  80. pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
  81. for (int i = 0; i < m_iHscale; i++)
  82. {
  83. point.X = m_XrayArea.X + i * m_XrayArea.Width / m_iHscale;
  84. point.Y = m_XrayArea.Y + m_XrayArea.Height;
  85. // 画横坐标数字刻度
  86. adapt.X = (i > 9) ? 6 : 4;
  87. adapt.Y = 2;
  88. graph.DrawString(Convert.ToString(i), this.Font, brush, new Point(point.X - adapt.X, point.Y + adapt.Y));
  89. // 画垂直方向刻度
  90. next.X = point.X;
  91. next.Y = m_XrayArea.Y;
  92. pen.Color = Color.FromArgb(70, Color.Black);
  93. graph.DrawLine(pen, point, next);
  94. }
  95. // 画纵坐标的刻度
  96. int iRows = 0;
  97. int iMaxValue = 0;
  98. int iScale = GetYScale(ref iMaxValue);
  99. iRows = iMaxValue / iScale;
  100. for (int i = 1; i < iRows; i++)
  101. {
  102. point.Y = m_XrayArea.Y + m_XrayArea.Height - i * m_XrayArea.Height / iRows;
  103. point.X = m_XrayArea.X;
  104. // 画纵坐标数字刻度
  105. adapt.X = (i * iScale >= 100) ? 22 : 16;
  106. adapt.X = (i * iScale >= 1000) ? 28 : adapt.X;
  107. adapt.Y = 6;
  108. string drawstring = Convert.ToString(iScale * i);
  109. int a1= strLabel.Length-drawstring.Length;
  110. graph.DrawString(drawstring, this.Font, brush, new Point(point.X-7 - adapt.X, point.Y +2 - adapt.Y));
  111. // 画水平方向刻度
  112. next.X = point.X + m_XrayArea.Width;
  113. next.Y = point.Y;
  114. graph.DrawLine(pen, point, next);
  115. }
  116. // 画能谱数据
  117. // ShowXray(ref m_XrayArea, iMaxValue, ref graph, m_bShowElementLines);
  118. ShowXrayClr(ref m_XrayArea, iMaxValue, ref graph, m_bShowElementLines);
  119. }
  120. protected void ShowXrayClr(ref Rectangle XrayArea, int iMaxValue, ref Graphics graph, bool bShowElementLines)
  121. {
  122. ShowXray( Dr, ref XrayArea, iMaxValue, ref graph);
  123. if (bShowElementLines)
  124. {
  125. // 元素线的高度为能谱图矩形高度一半
  126. ShowElementLines(Dr, XrayArea.Height / 2, ref XrayArea, ref graph);
  127. }
  128. if (null != Dr)
  129. {
  130. int iDelt = 0;
  131. SizeF size = graph.MeasureString("Test", this.Font);
  132. for (int i = 0; i < 1; i++)
  133. {
  134. //DataRow dr = Dt.Rows[i];
  135. ShowXray(Dr, ref XrayArea, iMaxValue, ref graph, true);
  136. if (bShowElementLines)
  137. {
  138. iDelt = (0 == i % 2) ? (-i - 1) * (int)size.Height : i * (int)size.Height;
  139. ShowElementLines(dr, iDelt + XrayArea.Height / 2, ref XrayArea, ref graph);
  140. }
  141. }
  142. }
  143. }
  144. protected int[] bytesToInt(byte[] src, int offset)
  145. {
  146. int[] values = new int[src.Length / 4];
  147. for (int i = 0; i < values.Length; i++)
  148. {
  149. values[i] = BitConverter.ToInt32(src, offset);
  150. offset += 4;
  151. }
  152. return values;
  153. }
  154. public void ShowXray(DataRow dr, ref Rectangle XrayArea, int iMaxValue, ref Graphics graph, bool bComp = false)
  155. {
  156. if (null != dr)
  157. {
  158. int[] SPEC= bytesToInt((byte[])dr["SPEC"], 0);
  159. int iXrayDataLen = SPEC.Length;
  160. if (null == m_xraypointf)
  161. {
  162. m_xraypointf = new PointF[iXrayDataLen];
  163. }
  164. for (int i = 0; i < iXrayDataLen; i++)
  165. {
  166. m_xraypointf[i].X = XrayArea.X + i * XrayArea.Width / iXrayDataLen;
  167. m_xraypointf[i].Y = XrayArea.Y + XrayArea.Height - SPEC[i] * XrayArea.Height / iMaxValue;
  168. }
  169. int ColorValue = 0;
  170. if (!dr["Color"].ToString().Equals(""))
  171. {
  172. ColorValue = Convert.ToInt32(dr["Color"]);
  173. }
  174. if (bComp)
  175. {
  176. Pen pen = new Pen(Color.FromArgb(150, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256)), 1);
  177. graph.DrawPolygon(pen, m_xraypointf);
  178. }
  179. else
  180. {
  181. SolidBrush brush = new SolidBrush(Color.FromArgb(150, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256)));
  182. graph.FillPolygon(brush, m_xraypointf);
  183. }
  184. }
  185. }
  186. protected void ShowElementLines(DataRow dr, int iLineHeight, ref Rectangle XrayArea, ref Graphics graph)
  187. {
  188. if (null == dr)
  189. {
  190. return;
  191. }
  192. //double dEnergy = 0;
  193. String str = "Test";
  194. SizeF size = graph.MeasureString(str, this.Font);
  195. // 判断元素线高度的合法性
  196. iLineHeight = (iLineHeight > size.Height) ? iLineHeight : (int)size.Height;
  197. iLineHeight = ((iLineHeight + (int)size.Height) > XrayArea.Height) ? (XrayArea.Height - (int)size.Height) : iLineHeight;
  198. //PointF point = new PointF();
  199. //PointF next = new PointF();
  200. //RectangleF rect = new RectangleF();
  201. Pen pen = new Pen(Color.FromArgb(255, 150, 100, 50), 1);
  202. int ColorValue = 0;
  203. if (!dr["Color"].ToString().Equals(""))
  204. {
  205. ColorValue = Convert.ToInt32(dr["Color"]);
  206. }
  207. SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256)));
  208. //for (int i = 0; i < 1; i++)
  209. //{
  210. // //CElementClr elementclr = stdmineralclr.GetElement(i);
  211. // str = "0";//elementclr.GetName();
  212. // size = graph.MeasureString(str, this.Font);
  213. // dEnergy = 2.3;//elementclr.GetEnergyValueK();
  214. // point.X = XrayArea.X + (float)dEnergy * XrayArea.Width / m_iHscale;
  215. // point.Y = XrayArea.Y + XrayArea.Height;
  216. // next.X = point.X;
  217. // next.Y = (0 == i % 2) ? (point.Y - iLineHeight) : (point.Y - iLineHeight + 2 + (int)size.Height);
  218. // // 画线
  219. // graph.DrawLine(pen, point, next);
  220. // // 画矩形框
  221. // rect.X = next.X - size.Width / 2;
  222. // rect.Y = next.Y - size.Height;
  223. // rect.Width = size.Width;
  224. // rect.Height = size.Height;
  225. // brush.Color = Color.FromArgb(255, Color.FromArgb(ColorValue % 256, (ColorValue >> 8) % 256, (ColorValue >> 16) % 256));
  226. // graph.FillRectangle(brush, rect);
  227. // // 画字符串
  228. // brush.Color = Color.FromArgb(255, Color.Black);
  229. // graph.DrawString(str, this.Font, brush, rect.X, rect.Y);
  230. //}
  231. }
  232. protected void ShowMouseMoveInfo(int ix, int iy, ref Rectangle XrayArea, ref Graphics graph)
  233. {
  234. // 判断坐标是否在矩形框区域内, 如果不在, 则退出
  235. if (ix < XrayArea.X ||
  236. ix > XrayArea.X + XrayArea.Width ||
  237. iy < XrayArea.Y ||
  238. iy > XrayArea.Y + XrayArea.Height)
  239. {
  240. return;
  241. }
  242. float fpos = 0;
  243. PointF point = new PointF();
  244. PointF next = new PointF();
  245. Pen pen = new Pen(Color.FromArgb(150, Color.Black), 1);
  246. SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.FromArgb(255, 0, 0)));
  247. fpos = (ix - XrayArea.X) * m_iHscale / (float)XrayArea.Width;
  248. SizeF size = graph.MeasureString(fpos.ToString(), this.Font);
  249. // 画竖线
  250. point.X = ix;
  251. point.Y = XrayArea.Y + XrayArea.Height;
  252. next.X = point.X;
  253. next.Y = XrayArea.Y + (int)size.Height;
  254. graph.DrawLine(pen, point, next);
  255. // 显示坐标位置
  256. graph.DrawString(fpos.ToString(), this.Font, brush, ix - (int)(size.Width / 2), XrayArea.Y+20);
  257. // 获取当前位置的元素
  258. // List<String> liststr = CElement.GetAllElementsEnergy(fpos, 0.1f);
  259. List<String> liststr = new List<string>();
  260. //CElementClr.GetAllElementsEnergyK(fpos, 0.1f, ref liststr);
  261. brush.Color = Color.FromArgb(255, Color.Blue);
  262. for (int i = 0; i < liststr.Count; i++)
  263. {
  264. size = graph.MeasureString(liststr[i], this.Font);
  265. point.X = ('-' == liststr[i][0]) ? (ix - (size.Width + 2)) : ix;
  266. point.Y = (XrayArea.Y + size.Height) + i * (size.Height + 2);
  267. graph.DrawString(liststr[i], this.Font, brush, point.X, point.Y);
  268. }
  269. }
  270. public void SetElementLines(bool bShowElementLines)
  271. {
  272. m_bShowElementLines = bShowElementLines;
  273. }
  274. protected override void OnMouseMove(MouseEventArgs e)
  275. {
  276. //// if (null == m_CurSelMineral &&
  277. //// (null == m_ListCompMineral ||
  278. //// 0 == m_ListCompMineral.Count()))
  279. //if (null == m_CurSelSTDMineralClr &&
  280. // (null == m_ListCompMineralClr ||
  281. // 0 == m_ListCompMineralClr.Count()))
  282. //{
  283. // return;
  284. //}
  285. m_bMouseMove = true;
  286. m_curCurssorPos.X = e.X;
  287. m_curCurssorPos.Y = e.Y;
  288. this.Invalidate();
  289. // this.OnPaint(new PaintEventArgs(this.CreateGraphics(), new Rectangle(new Point(0, 0), this.Size)));
  290. }
  291. // 返回值是刻度的精度, iRows表示行数
  292. protected int GetYScale(ref int iMaxValue)
  293. {
  294. int iMaxXray = 0;
  295. int iMaxXray1 = 0;
  296. int iMaxXray2 = 0;
  297. int iBaseScale = 20; // 最小基础刻度20
  298. int iScale = 20; // 待返回的刻度值
  299. int iBaseMaxValue = 100; // 基础最大值100
  300. int iTimes = 0;
  301. int iLeft = 0;
  302. iMaxXray1 = GetMaxXray(Dr);
  303. iMaxXray2 = 0;//GetMaxXrayClr();
  304. iMaxXray = (iMaxXray1 > iMaxXray2) ? iMaxXray1 : iMaxXray2;
  305. // 设计需求: 0 <= iMaxXray < 500(iScale: 50, iMaxValue: 250或者500)
  306. // 设计需求: 500 <= iMaxXray < 1000(iScale: 100, iMaxValue: 750或者1000)
  307. // 设计需求: 1000 <= iMaxXray < 1500(iScale: 150, iMaxValue: 1250或者1500)
  308. // 设计需求: 1500 <= iMaxXray < 2000(iScale: 200, iMaxValue: 1750或者2000)
  309. // 以此类推
  310. // iMaxXray = 9000;// 测试代码, 可以删除
  311. iTimes = iMaxXray / iBaseMaxValue;
  312. iLeft = iMaxXray % iBaseMaxValue;
  313. iScale = iBaseScale + iBaseScale * (iTimes / 2);
  314. iMaxValue = iBaseMaxValue + iBaseMaxValue * iTimes;
  315. // 因为iScale * (iMaxValue / iScale) <= iMaxValue, 所以如果 iMaxXray > iScale * (iMaxValue / iScale) 刻度就会不够,导致bug
  316. if (iScale * (iMaxValue / iScale) < iMaxXray)
  317. {
  318. iMaxValue = iMaxValue + iBaseMaxValue;
  319. }
  320. return iScale;
  321. }
  322. protected int GetMaxXray(DataRow dr)
  323. {
  324. if (null == dr)
  325. {
  326. return 0;
  327. }
  328. int iMaxXray = 0;
  329. int iXrayLen = 0;
  330. int[] SPEC = bytesToInt((byte[])dr["SPEC"], 0);
  331. iXrayLen = SPEC.Length;
  332. for (int i = 0; i < iXrayLen; i++)
  333. {
  334. if (SPEC[i] > iMaxXray)
  335. {
  336. iMaxXray = SPEC[i];
  337. }
  338. }
  339. return iMaxXray;
  340. }
  341. protected int GetMaxXrayClr()
  342. {
  343. if (null == Dr)
  344. {
  345. return 0;
  346. }
  347. int iMaxXray = 0;
  348. int iXray = 0;
  349. for (int i = 0; i < Dt.Rows.Count; i++)
  350. {
  351. DataRow dr = Dt.Rows[i];
  352. iXray = GetMaxXray(dr);
  353. if (iXray > iMaxXray)
  354. {
  355. iMaxXray = iXray;
  356. }
  357. }
  358. return iMaxXray;
  359. }
  360. private void setTag(Control cons)
  361. {
  362. foreach (Control con in cons.Controls)
  363. {
  364. con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
  365. if (con.Controls.Count > 0)
  366. setTag(con);
  367. }
  368. }
  369. private void setControls(float newx, float newy, Control cons)
  370. {
  371. foreach (Control con in cons.Controls)
  372. {
  373. if (con.Name == "Form_ZeroElementRules")
  374. {
  375. continue;
  376. }
  377. if (false)
  378. {
  379. }
  380. else
  381. {
  382. string[] mytag = con.Tag.ToString().Split(':');
  383. float a = Convert.ToSingle(mytag[0]) * newx;
  384. con.Width = (int)a;
  385. a = Convert.ToSingle(mytag[1]) * newy;
  386. con.Height = (int)(a);
  387. a = Convert.ToSingle(mytag[2]) * newx;
  388. con.Left = (int)(a);
  389. a = Convert.ToSingle(mytag[3]) * newy;
  390. con.Top = (int)(a);
  391. Single currentSize;
  392. if (con.GetType().ToString() == "System.Windows.Forms.Label")
  393. {
  394. currentSize = Convert.ToSingle(mytag[4]) * ((newx + newy) / 2);
  395. //currentSize = 6f;
  396. }
  397. else
  398. {
  399. if (Math.Max(newx, newy) < 1)
  400. {
  401. currentSize = Convert.ToSingle(mytag[4]) * 1;
  402. }
  403. else
  404. {
  405. currentSize = Convert.ToSingle(mytag[4]) * Math.Max(newx, newy);
  406. }
  407. }
  408. con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
  409. if (con.Controls.Count > 0)
  410. {
  411. setControls(newx, newy, con);
  412. }
  413. }
  414. }
  415. }
  416. }
  417. }