多线程结束阻塞第三方对话窗体的方法
最近用到了《Syncfusion Essential Studio》这个组件,这不是重点,重点是在用到 Grid 组件,想要将其导出为Excel文件时遇到了问题。
导出中组件会自己弹出一个阻塞的 MessageBox 对话窗口,窗口显示了遍历表格所用时间,标题为英文显得煞是突兀,由于直接引用的 .DLL 文件,无法将对话窗口的语句注释掉。
因为自己所用到的组件版本比较老,加之此东西比较生僻网上也很少有详实的参考资料,官网的开发文档也没找到设置取消的方法。
只能通过别的方法变通地解决这个不和谐的问题。网上找了下思路,觉得通过标题获取窗口句柄的方法来关闭窗口的方法比较合适。
以下是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")] static extern bool EndDialog(IntPtr hDlg, out IntPtr nResult); GridExcelConverterControl gridExcelContrl = new GridExcelConverterControl(); try { gridExcelContrl.GridToExcel(this.Grid_BatchModify, fileName ); ptr = FindWindow(null, "窗口标题"); EndDialog(ptr, out result); MessageBox.Show(@"导出成功"); } catch { MessageBox.Show(@"导出失败"); } finally { gridExcelContrl.Dispose(); }
|
好了🎉,小功告成,让我们来看看效果吧……欸?!😡怎么还是有呢?仔细一看,哈哈自己逗了,窗口出来的时候是阻塞状态,后面的销毁流程是无法执行的。
看来只能让销毁函数独立于对话窗口去销毁它了,于是换个思路,用独立的线程去关闭这个窗口,我们先做个销毁的线程,让它一直循环直到获取到窗口销毁然后退出执行。
程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")] static extern bool EndDialog(IntPtr hDlg, out IntPtr nResult); GridExcelConverterControl gridExcelContrl = new GridExcelConverterControl(); try { Thread closeDlg = new Thread(delegate() { IntPtr ptr = IntPtr.Zero; IntPtr result; while (ptr == IntPtr.Zero) ptr = FindWindow(null, "窗口标题"); EndDialog(ptr, out result); }); closeDlg.Start(); gridExcelContrl.GridToExcel(this.Grid_BatchModify, fileName ); MessageBox.Show(@"导出成功"); } catch { MessageBox.Show(@"导出失败"); } finally { gridExcelContrl.Dispose(); }
|
写完抓紧跑起来试试,哟嚯😁。可以了,这样一来导出的时候再也不会有烦人的英文窗口弹出来告诉你“导出用了0.00000000n秒”这件事了。
Ps:其实窗口还是存在过的,我们没法在内部跳过窗口创建的这一部,只是从外面结束掉而已,因为程序执行很快所以窗口几乎没有 show 出来就被终止掉了。
另外文中EndDialog
函数在有的时候也可以用DestroyWindow
这个函数,根据需要终结的窗口类型去选用,不然可能会关闭不成功哦~
这就是我的方法,希望能抛砖引玉,给需要的朋友一点思路。
谢谢😄