LedControl.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. using HNWD.LatticeScreen;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Concurrent;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Runtime.InteropServices;
  11. using System.Text;
  12. using System.Threading;
  13. using System.Windows.Forms;
  14. using LatticeScreenServer;
  15. namespace HNWD.LatticeScreen
  16. {
  17. public class LedControl
  18. {
  19. public const int JR_OK = 0;
  20. private static readonly ConcurrentDictionary<IntPtr, IntPtr> handle = new ConcurrentDictionary<IntPtr, IntPtr>();
  21. private static readonly ConcurrentDictionary<IntPtr, DomainInfo> domainInfo = new ConcurrentDictionary<IntPtr, DomainInfo>();
  22. private static string configFile = "Config.ini";
  23. private static FileSystemWatcher fileWatcher = null;
  24. public static string ConfigFile
  25. {
  26. get => configFile;
  27. set
  28. {
  29. configFile = Path.GetFullPath(value);
  30. fileWatcher?.Dispose();
  31. fileWatcher = new FileSystemWatcher(Path.GetDirectoryName(configFile) ?? string.Empty, $"*{Path.GetExtension(configFile)}")
  32. {
  33. EnableRaisingEvents = true
  34. };
  35. fileWatcher.Changed += (sender, e) =>
  36. {
  37. if (e.FullPath == configFile && WatcherChangeTypes.All.HasFlag(e.ChangeType))
  38. {
  39. isPlaySound = null;
  40. soundPerson = null;
  41. soundVolume = null;
  42. soundSpeed = null;
  43. font = null;
  44. fontSize = null;
  45. }
  46. };
  47. }
  48. }
  49. static LedControl()
  50. {
  51. ConfigFile = "Config.ini";
  52. // 将 dll 文件保存到运行根目录
  53. SaveNonFile("bx_sdk_dual.dll", OnbonResources.bx_sdk_dual);
  54. SaveNonFile("cairo-1.14.6.dll", OnbonResources.cairo_1_14_6);
  55. SaveNonFile("freetype.dll", OnbonResources.freetype);
  56. SaveNonFile("freetype265.dll", OnbonResources.freetype265);
  57. SaveNonFile("libpng16.dll", OnbonResources.libpng16);
  58. SaveNonFile("msvcr110.dll", OnbonResources.msvcr110);
  59. SaveNonFile("zlibwapi.dll", OnbonResources.zlibwapi);
  60. }
  61. private static void SaveNonFile(string filePath, byte[] fileData)
  62. {
  63. if (!Path.IsPathRooted(filePath))
  64. {
  65. filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filePath);
  66. }
  67. if (!File.Exists(filePath))
  68. {
  69. using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, fileData.Length))
  70. {
  71. fileStream.Write(fileData, 0, fileData.Length);
  72. }
  73. }
  74. }
  75. private static bool? isPlaySound = null;
  76. public static bool IsPlaySound
  77. {
  78. get
  79. {
  80. if (isPlaySound.HasValue)
  81. {
  82. return isPlaySound.Value;
  83. }
  84. var result = ReadValue(nameof(IsPlaySound));
  85. if (bool.TryParse(result, out var value))
  86. {
  87. isPlaySound = value;
  88. return value;
  89. }
  90. isPlaySound = false;
  91. return false;
  92. }
  93. }
  94. private static byte? soundPerson = null;
  95. public static byte SoundPerson
  96. {
  97. get
  98. {
  99. if (soundPerson.HasValue)
  100. {
  101. return soundPerson.Value;
  102. }
  103. var result = ReadValue(nameof(SoundPerson));
  104. if (byte.TryParse(result, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
  105. {
  106. soundPerson = value;
  107. return value;
  108. }
  109. soundPerson = 0;
  110. return 0;
  111. }
  112. }
  113. private static byte? soundVolume = null;
  114. public static byte SoundVolume
  115. {
  116. get
  117. {
  118. if (soundVolume.HasValue)
  119. {
  120. return soundVolume.Value;
  121. }
  122. var result = ReadValue(nameof(SoundVolume));
  123. if (byte.TryParse(result, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
  124. {
  125. soundVolume = value;
  126. return value;
  127. }
  128. soundVolume = 0;
  129. return 0;
  130. }
  131. }
  132. private static byte? soundSpeed = null;
  133. public static byte SoundSpeed
  134. {
  135. get
  136. {
  137. if (soundSpeed.HasValue)
  138. {
  139. return soundSpeed.Value;
  140. }
  141. var result = ReadValue(nameof(SoundSpeed));
  142. if (byte.TryParse(result, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
  143. {
  144. soundSpeed = value;
  145. return value;
  146. }
  147. soundSpeed = 0;
  148. return 0;
  149. }
  150. }
  151. private static string font = null;
  152. public static string Font
  153. {
  154. get
  155. {
  156. if (font != null)
  157. {
  158. return font;
  159. }
  160. var result = ReadValue(nameof(Font));
  161. if (string.IsNullOrEmpty(result))
  162. {
  163. font = "宋体";
  164. }
  165. else
  166. {
  167. font = result;
  168. }
  169. return font;
  170. }
  171. }
  172. private static int? fontSize = null;
  173. public static int FontSize
  174. {
  175. get
  176. {
  177. if (fontSize.HasValue)
  178. {
  179. return fontSize.Value;
  180. }
  181. var result = ReadValue(nameof(FontSize));
  182. if (int.TryParse(result, out var value))
  183. {
  184. fontSize = value;
  185. }
  186. else
  187. {
  188. fontSize = 12;
  189. }
  190. return fontSize.Value;
  191. }
  192. }
  193. public static int JHCreateInst(ref IntPtr hdl, ushort serverid)
  194. {
  195. var tmp = new IntPtr(new Random().Next(100, 1000000));
  196. hdl = tmp;
  197. handle.AddOrUpdate(hdl, hdl, (key, value) => tmp);
  198. return bx_sdk_dual.InitSdk();
  199. }
  200. public static int JHCommInit()
  201. {
  202. return 0;
  203. }
  204. public static int JHDeleteInst(IntPtr hdl)
  205. {
  206. if (handle.TryGetValue(hdl, out var value))
  207. {
  208. domainInfo.TryRemove(value, out _);
  209. }
  210. return 0;
  211. }
  212. public static int JHCommGetTransportlayer(ref IntPtr ptransportlayer, int dev)
  213. {
  214. return 0;
  215. }
  216. public static int JHCommGetNetArgStruct(ref IntPtr pargs, string ipordomain, ushort port, uint timeout)
  217. {
  218. var tmp = new IntPtr(new Random().Next(100, 1000000));
  219. pargs = tmp;
  220. ushort controllerType = 0;
  221. var data = new bx_sdk_dual.Ping_data();
  222. var err = bx_sdk_dual.cmd_tcpPing(Encoding.Default.GetBytes(ipordomain), port, ref data);
  223. if (err == 0)
  224. {
  225. controllerType = data.ControllerType;
  226. }
  227. else
  228. {
  229. var buffer = new byte[Marshal.SizeOf(typeof(bx_sdk_dual.Ping_data))];
  230. err = bx_sdk_dual.cmd_udpPing(buffer);
  231. if (err != 0)
  232. {
  233. return err;
  234. }
  235. if (ipordomain == Encoding.Default.GetString(data.ipAdder).Replace("\0", ""))
  236. {
  237. controllerType = data.ControllerType;
  238. }
  239. else
  240. {
  241. return -1;
  242. }
  243. }
  244. var result = bx_sdk_dual.cmd_check_time(Encoding.Default.GetBytes(ipordomain), port);
  245. var doman = new DomainInfo
  246. {
  247. Address = ipordomain,
  248. Port = port,
  249. Timeout = timeout,
  250. ControllerType = controllerType,
  251. Size = new Size(data.ScreenWidth, data.ScreenHeight),
  252. Sync = new object()
  253. };
  254. domainInfo.AddOrUpdate(tmp, doman, (key, value) => doman);
  255. return 0;
  256. }
  257. public static int JHMountTransportLayer(IntPtr hdl, IntPtr ptl, IntPtr argstruct)
  258. {
  259. handle.AddOrUpdate(hdl, argstruct, (key, value) => argstruct);
  260. return 0;
  261. }
  262. private static string lastText = string.Empty;
  263. private static ConcurrentDictionary<IntPtr, List<DrawText>> drawList = new ConcurrentDictionary<IntPtr, List<DrawText>>();
  264. private static DrawText[] lastDraw = new DrawText[0];
  265. public static int JHDrawText(IntPtr hdl, short x, short y, ushort width, ushort height, uint format, string ptext)
  266. {
  267. if (!handle.TryGetValue(hdl, out var argsPtr))
  268. {
  269. return -1;
  270. }
  271. if (!domainInfo.TryGetValue(argsPtr, out var domain))
  272. {
  273. return -1;
  274. }
  275. lock (domain.Sync)
  276. {
  277. var list = drawList.AddOrUpdate(hdl,
  278. new List<DrawText>()
  279. {
  280. new DrawText()
  281. {Format = format, Location = new Point(x, y), Size = new Size(width, height), Text = ptext}
  282. }, (key, value) =>
  283. {
  284. if (value == null)
  285. {
  286. value = new List<DrawText>();
  287. }
  288. var tmp = new DrawText()
  289. {
  290. Format = format,
  291. Location = new Point(x, y),
  292. Size = new Size(width, height),
  293. Text = ptext
  294. };
  295. if (!value.Contains(tmp))
  296. {
  297. value.Add(tmp);
  298. }
  299. return value;
  300. });
  301. var allWidth = list.Sum(item => item.Size.Width);
  302. if (allWidth > 0 && allWidth < domain.Size.Width)
  303. {
  304. return 0;
  305. }
  306. var allHeight = list.Sum(item => item.Size.Height);
  307. if (allHeight > 0 && allHeight < domain.Size.Height)
  308. {
  309. return 0;
  310. }
  311. if (StructuralComparisons.StructuralEqualityComparer.Equals(list.ToArray(), lastDraw))
  312. {
  313. return 0;
  314. }
  315. bx_sdk_dual.EQprogramHeader_G6 header;
  316. header.FileType = 0x00;
  317. header.ProgramID = 0;
  318. header.ProgramStyle = 0x00;
  319. header.ProgramPriority = 0x00;
  320. header.ProgramPlayTimes = 1;
  321. header.ProgramTimeSpan = 0;
  322. header.SpecialFlag = 0;
  323. header.CommExtendParaLen = 0x00;
  324. header.ScheduNum = 0;
  325. header.LoopValue = 0;
  326. header.Intergrate = 0x00;
  327. header.TimeAttributeNum = 0x00;
  328. header.TimeAttribute0Offset = 0x0000;
  329. header.ProgramWeek = 0xff;
  330. header.ProgramLifeSpan_sy = 0xffff;
  331. header.ProgramLifeSpan_sm = 0x03;
  332. header.ProgramLifeSpan_sd = 0x14;
  333. header.ProgramLifeSpan_ey = 0xffff;
  334. header.ProgramLifeSpan_em = 0x03;
  335. header.ProgramLifeSpan_ed = 0x14;
  336. header.PlayPeriodGrpNum = 1;
  337. IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(bx_sdk_dual.EQprogramHeader_G6)));
  338. Marshal.StructureToPtr(header, ptr, false);
  339. int err = bx_sdk_dual.program_addProgram_G6(ptr);
  340. if (err != 0)
  341. {
  342. return err;
  343. }
  344. ushort areaId = 0;
  345. var empty = list.FirstOrDefault(item => string.IsNullOrEmpty(item.Text) && item.Size.Width >= domain.Size.Width && item.Size.Height >= domain.Size.Height);
  346. var isEmpty = empty.Equals(default(DrawText));
  347. if (isEmpty)
  348. {
  349. StopEraseThreead();
  350. foreach (var item in list)
  351. {
  352. var aheader = new bx_sdk_dual.EQareaHeader_G6();
  353. aheader.AreaX = (ushort)item.Location.X;
  354. aheader.AreaY = (ushort)item.Location.Y;
  355. aheader.AreaWidth = (ushort)item.Size.Width;
  356. aheader.AreaHeight = (ushort)item.Size.Height;
  357. aheader.BackGroundFlag = 0x00;
  358. aheader.Transparency = 101;
  359. var isDateTime = IsDateTimeText(item.Text, out var dateStyle, out var timeStyle);
  360. if (isDateTime)
  361. {
  362. aheader.AreaType = (byte)bx_sdk_dual.AreaType.DateTime;
  363. }
  364. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(bx_sdk_dual.EQareaHeader_G6)));
  365. Marshal.StructureToPtr(aheader, ptr, false);
  366. err = bx_sdk_dual.program_addArea_G6(areaId, ptr);
  367. if (err != 0)
  368. {
  369. return err;
  370. }
  371. if (isDateTime)
  372. {
  373. var timeData = new bx_sdk_dual.EQtimeAreaData_G56();
  374. timeData.linestyle = bx_sdk_dual.E_arrMode.eSINGLELINE;
  375. timeData.color = (uint)bx_sdk_dual.E_Color_G56.eRED;
  376. timeData.fontName = Font;
  377. timeData.fontSize = (ushort)FontSize;
  378. timeData.fontBold = 0;
  379. timeData.fontItalic = 0;
  380. timeData.fontUnderline = 0;
  381. timeData.fontAlign = GetHalign(format);
  382. if (timeData.fontAlign > 0)
  383. {
  384. timeData.fontAlign--;
  385. }
  386. if (dateStyle.HasValue)
  387. {
  388. timeData.date_enable = 1;
  389. timeData.datestyle = dateStyle.Value;
  390. }
  391. if (timeStyle.HasValue)
  392. {
  393. timeData.time_enable = 1;
  394. timeData.timestyle = timeStyle.Value;
  395. }
  396. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(bx_sdk_dual.EQtimeAreaData_G56)));
  397. Marshal.StructureToPtr(timeData, ptr, false);
  398. err = bx_sdk_dual.program_timeAreaAddContent_G6(areaId, ptr);
  399. if (err != 0)
  400. {
  401. return err;
  402. }
  403. }
  404. else
  405. {
  406. var str = Encoding.GetEncoding("GBK").GetBytes(item.Text);
  407. if (ControlType.HasVoiceModule(domain.ControllerType) && IsPlaySound)
  408. {
  409. var sound = new bx_sdk_dual.EQPicAreaSoundHeader_G6();
  410. sound.SoundPerson = SoundPerson;
  411. sound.SoundVolum = SoundVolume;
  412. sound.SoundSpeed = SoundSpeed;
  413. sound.SoundDataMode = 0;
  414. sound.SoundReplayTimes = 0;
  415. sound.SoundReplayDelay = 1000;
  416. sound.SoundReservedParaLen = 3;
  417. sound.Soundnumdeal = 0;
  418. sound.Soundlanguages = 0;
  419. sound.Soundwordstyle = 0;
  420. bx_sdk_dual.program_pictureAreaEnableSound_G6(0, sound, str);
  421. }
  422. var font = Encoding.Default.GetBytes(Font);
  423. bx_sdk_dual.EQpageHeader_G6 pheader = new bx_sdk_dual.EQpageHeader_G6();
  424. pheader.PageStyle = 0x00;
  425. pheader.DisplayMode = 0x01; //移动模式
  426. pheader.ClearMode = 0x01;
  427. pheader.Speed = 15; //速度
  428. pheader.StayTime = 0; //停留时间
  429. pheader.RepeatTime = 1;
  430. pheader.ValidLen = 0;
  431. pheader.CartoonFrameRate = 0x00;
  432. pheader.BackNotValidFlag = 0x00;
  433. pheader.arrMode = bx_sdk_dual.E_arrMode.eSINGLELINE;
  434. pheader.fontSize = (ushort)FontSize;
  435. pheader.color = (uint)0x01;
  436. pheader.fontBold = 0;
  437. pheader.fontItalic = 0;
  438. pheader.tdirection = bx_sdk_dual.E_txtDirection.pNORMAL;
  439. pheader.txtSpace = 0;
  440. pheader.Valign = GetValign(item.Format);
  441. pheader.Halign = GetHalign(item.Format);
  442. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(bx_sdk_dual.EQpageHeader_G6)));
  443. Marshal.StructureToPtr(pheader, ptr, false);
  444. err = bx_sdk_dual.program_picturesAreaAddTxt_G6(areaId, str, font, ptr);
  445. if (err != 0)
  446. {
  447. return err;
  448. }
  449. }
  450. areaId++;
  451. }
  452. }
  453. else
  454. {
  455. var aheader = new bx_sdk_dual.EQareaHeader_G6();
  456. aheader.AreaX = (ushort)empty.Location.X;
  457. aheader.AreaY = (ushort)empty.Location.Y;
  458. aheader.AreaWidth = (ushort)empty.Size.Width;
  459. aheader.AreaHeight = (ushort)empty.Size.Height;
  460. aheader.BackGroundFlag = 0x00;
  461. aheader.Transparency = 101;
  462. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(bx_sdk_dual.EQareaHeader_G6)));
  463. Marshal.StructureToPtr(aheader, ptr, false);
  464. err = bx_sdk_dual.program_addArea_G6(areaId, ptr);
  465. if (err != 0)
  466. {
  467. return err;
  468. }
  469. var font = Encoding.Default.GetBytes(Font);
  470. bx_sdk_dual.EQpageHeader_G6 pheader;
  471. pheader.PageStyle = 0x00;
  472. pheader.DisplayMode = 0x01; //移动模式
  473. pheader.ClearMode = 0x01;
  474. pheader.Speed = 15; //速度
  475. pheader.StayTime = 0; //停留时间
  476. pheader.RepeatTime = 1;
  477. pheader.ValidLen = 0;
  478. pheader.CartoonFrameRate = 0x00;
  479. pheader.BackNotValidFlag = 0x00;
  480. pheader.arrMode = bx_sdk_dual.E_arrMode.eSINGLELINE;
  481. pheader.fontSize = (ushort)FontSize;
  482. pheader.color = (uint)0x01;
  483. pheader.fontBold = 0;
  484. pheader.fontItalic = 0;
  485. pheader.tdirection = bx_sdk_dual.E_txtDirection.pNORMAL;
  486. pheader.txtSpace = 0;
  487. pheader.Valign = GetValign(empty.Format);
  488. pheader.Halign = GetHalign(empty.Format);
  489. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(bx_sdk_dual.EQpageHeader_G6)));
  490. Marshal.StructureToPtr(pheader, ptr, false);
  491. err = bx_sdk_dual.program_picturesAreaAddTxt_G6(areaId, Encoding.GetEncoding("GBK").GetBytes(empty.Text), font, ptr);
  492. if (err != 0)
  493. {
  494. return err;
  495. }
  496. }
  497. bx_sdk_dual.EQprogram_G6 program = new bx_sdk_dual.EQprogram_G6();
  498. program.fileName = Encoding.GetEncoding("GBK").GetBytes("P000");
  499. program.fileType = 0;
  500. program.fileLen = 0;
  501. program.fileAddre = IntPtr.Zero;
  502. program.dfileName = Encoding.GetEncoding("GBK").GetBytes("D000");
  503. program.dfileType = 0;
  504. program.dfileLen = 0;
  505. program.dfileAddre = IntPtr.Zero;
  506. err = bx_sdk_dual.program_IntegrateProgramFile_G6(ref program);
  507. if (err != 0)
  508. {
  509. return err;
  510. }
  511. err = bx_sdk_dual.cmd_ofsStartFileTransf(Encoding.GetEncoding("GBK").GetBytes(domain.Address),
  512. (ushort)domain.Port);
  513. if (err != 0)
  514. {
  515. return err;
  516. }
  517. err = bx_sdk_dual.cmd_ofsWriteFile(Encoding.GetEncoding("GBK").GetBytes(domain.Address),
  518. (ushort)domain.Port, program.dfileName, program.dfileType, program.dfileLen, 1,
  519. program.dfileAddre);
  520. if (err != 0)
  521. {
  522. return err;
  523. }
  524. err = bx_sdk_dual.cmd_ofsWriteFile(Encoding.GetEncoding("GBK").GetBytes(domain.Address),
  525. (ushort)domain.Port, program.fileName, program.fileType, program.fileLen, 1, program.fileAddre);
  526. if (err != 0)
  527. {
  528. return err;
  529. }
  530. err = bx_sdk_dual.cmd_ofsEndFileTransf(Encoding.GetEncoding("GBK").GetBytes(domain.Address),
  531. (ushort)domain.Port);
  532. if (err != 0)
  533. {
  534. return err;
  535. }
  536. bx_sdk_dual.program_deleteProgram_G6();
  537. //lastText = ptext;
  538. drawList.AddOrUpdate(hdl, new List<DrawText>(), (key, value) => new List<DrawText>());
  539. lastDraw = list.ToArray();
  540. return 0;
  541. }
  542. }
  543. public static int JHDrawMultPixel(IntPtr hdl, ushort[] pdat, ushort poscnt)
  544. {
  545. return 0;
  546. }
  547. private static Thread eraseThread;
  548. public static int JHErase(IntPtr hdl)
  549. {
  550. //return JHDrawText(hdl, 0, 0, ushort.MaxValue, ushort.MaxValue, 0, "");
  551. StopEraseThreead();
  552. eraseThread = new Thread(state =>
  553. {
  554. Thread.Sleep(TimeSpan.FromSeconds(10));
  555. JHDrawText(hdl, 0, 0, ushort.MaxValue, ushort.MaxValue, 0, "");
  556. });
  557. return 0;
  558. }
  559. private static void StopEraseThreead()
  560. {
  561. try
  562. {
  563. eraseThread?.Abort();
  564. eraseThread?.DisableComObjectEagerCleanup();
  565. }
  566. catch
  567. {
  568. }
  569. }
  570. public static int JHDrawBitmap(IntPtr hdl, short x, short y, ushort width, ushort height, uint format, tagBitmapSource pbmpsrc)
  571. {
  572. return 0;
  573. }
  574. public static int JHCommDeinit()
  575. {
  576. return 0;
  577. }
  578. public static int JHCommReleaseArgStruct(IntPtr pargs)
  579. {
  580. domainInfo.TryRemove(pargs, out _);
  581. return 0;
  582. }
  583. private static byte GetHalign(uint format)
  584. {
  585. var value = (int)((format >> 4) & 0x3);
  586. switch (value)
  587. {
  588. case 0b00:
  589. return 1;
  590. case 0b01:
  591. return 2;
  592. case 0b10:
  593. return 3;
  594. default:
  595. return 0;
  596. }
  597. }
  598. private static byte GetValign(uint format)
  599. {
  600. var value = (int)((format >> 6) & 0x3);
  601. switch (value)
  602. {
  603. case 0b00: return 1;
  604. case 0b01: return 2;
  605. case 0b10: return 3;
  606. default: return 0;
  607. }
  608. }
  609. private struct DomainInfo
  610. {
  611. public string Address { get; set; }
  612. public int Port { get; set; }
  613. public uint Timeout { get; set; }
  614. public ushort ControllerType { get; set; }
  615. public Size Size { get; set; }
  616. public object Sync { get; set; }
  617. }
  618. private struct DrawText
  619. {
  620. public Point Location { get; set; }
  621. public Size Size { get; set; }
  622. public string Text { get; set; }
  623. public uint Format { get; set; }
  624. public override bool Equals(object obj)
  625. {
  626. if (obj is DrawText other)
  627. {
  628. if (Location.Equals(other.Location) && Size.Equals(other.Size) && Format == other.Format)
  629. {
  630. if (IsDateTimeText(Text, out var thisDateStyle, out var thisTimeStyle))
  631. {
  632. if (IsDateTimeText(other.Text, out var otherDateStyle, out var otherTimeStyle))
  633. {
  634. return thisDateStyle == otherDateStyle && thisTimeStyle == otherTimeStyle;
  635. }
  636. }
  637. if (!IsDateTimeText(other.Text, out _, out _))
  638. {
  639. return this.Text == other.Text;
  640. }
  641. }
  642. }
  643. return false;
  644. }
  645. public override int GetHashCode()
  646. {
  647. unchecked
  648. {
  649. var hashCode = Location.GetHashCode();
  650. hashCode = (hashCode * 397) ^ Size.GetHashCode();
  651. hashCode = (hashCode * 397) ^ Format.GetHashCode();
  652. if (!IsDateTimeText(Text, out _, out _))
  653. {
  654. hashCode = (hashCode * 397) ^ (Text != null ? Text.GetHashCode() : 0);
  655. }
  656. return hashCode;
  657. }
  658. }
  659. }
  660. private static bool IsDateTimeText(string text, out bx_sdk_dual.E_DateStyle? dateStyle, out bx_sdk_dual.E_TimeStyle? timeStyle)
  661. {
  662. dateStyle = null;
  663. timeStyle = null;
  664. if (DateTime.TryParseExact(text, "HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  665. {
  666. timeStyle = bx_sdk_dual.E_TimeStyle.eHH_MM_SS_COLON;
  667. return true;
  668. }
  669. if (DateTime.TryParseExact(text, "HH时MM分ss秒", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  670. {
  671. timeStyle = bx_sdk_dual.E_TimeStyle.eHH_MM_SS_CHS;
  672. return true;
  673. }
  674. if (DateTime.TryParseExact(text, "HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  675. {
  676. timeStyle = bx_sdk_dual.E_TimeStyle.eHH_MM_COLON;
  677. return true;
  678. }
  679. if (DateTime.TryParseExact(text, "HH时mm分", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  680. {
  681. timeStyle = bx_sdk_dual.E_TimeStyle.eHH_MM_CHS;
  682. return true;
  683. }
  684. if (DateTime.TryParseExact(text, "yy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  685. {
  686. dateStyle = bx_sdk_dual.E_DateStyle.eYYYY_MM_DD_MINUS;
  687. return true;
  688. }
  689. if (DateTime.TryParseExact(text, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  690. {
  691. dateStyle = bx_sdk_dual.E_DateStyle.eYYYY_MM_DD_MINUS;
  692. return true;
  693. }
  694. if (DateTime.TryParseExact(text, "yyyy年MM月dd日", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  695. {
  696. dateStyle = bx_sdk_dual.E_DateStyle.eYYYY_MM_DD_CHS;
  697. return true;
  698. }
  699. if (DateTime.TryParseExact(text, "yyyy年MM月dd日HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  700. {
  701. dateStyle = bx_sdk_dual.E_DateStyle.eYYYY_MM_DD_CHS;
  702. timeStyle = bx_sdk_dual.E_TimeStyle.eHH_MM_SS_COLON;
  703. return true;
  704. }
  705. if (DateTime.TryParseExact(text, "yyyy年MM月dd日 HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
  706. {
  707. dateStyle = bx_sdk_dual.E_DateStyle.eYYYY_MM_DD_CHS;
  708. timeStyle = bx_sdk_dual.E_TimeStyle.eHH_MM_SS_COLON;
  709. return true;
  710. }
  711. return false;
  712. }
  713. private static string ReadValue(string key)
  714. {
  715. var builder = new StringBuilder(500);
  716. GetPrivateProfileString("DotScreen", key, "", builder, 500, configFile);
  717. return builder.ToString();
  718. }
  719. [DllImport("kernel32")]
  720. private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
  721. [DllImport("kernel32")]
  722. private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
  723. }
  724. }