You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1242 lines
53 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mesnac.Basic;
using System.Xml;
using System.IO;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Reflection;
using System.Reflection.Emit;
using System.Configuration;
using ICSharpCode.Core;
using Host;
using Loader;
using Mesnac.Core;
using Mesnac.Core.Service;
using Mesnac.Controls.Default;
using Mesnac.Equips;
namespace Mesnac.Gui.Common
{
/// <summary>
/// 运行引擎类
/// </summary>
public class RunEngine
{
#region 字段定义
private string _projectPath = String.Empty; //组态工程路径
private AccidenceAnalyzer express; //表达式解析器
private TreeView _tree = null; //解析组态工程后的工程树
private Dictionary<string, Form> _runForms = new Dictionary<string, Form>(); //运行的组态画面列表
private bool _isLoad = false; //是否已载入工程
private bool _isControlPruview = false; //是否启用权限控制
#endregion
#region 属性定义
/// <summary>
/// 是否启用权限控制
/// </summary>
public bool IsControlPruview
{
get { return this._isControlPruview; }
}
#endregion
#region 单例实现
private static RunEngine _instance = null;
private RunEngine()
{
//注册表达式
this.express = new AccidenceAnalyzer();
this.express.OnAccidenceAnalysis += new AccidenceAnalyzer.AccidenceAnalysis(express_OnAccidenceAnalysis);
this.express.OnCallBack += new AccidenceAnalyzer.CallBack(express_OnCallBack);
}
public static RunEngine Instance
{
get
{
if (_instance == null)
{
_instance = new RunEngine();
}
return _instance;
}
}
#endregion
#region 组态工程树属性定义
public TreeView Tree
{
get
{
return this._tree;
}
}
#endregion
#region 1、运行引擎初始化相关方法
#region 运行引擎初始化
/// <summary>
/// 运行引擎初始化
/// </summary>
/// <param name="projectPath">工程路径</param>
/// <param name="isAutoRun">是否自动执行自启动Action</param>
public bool Init(string projectPath, bool isAutoRun, bool isControlPurview)
{
LoggingService.Debug("运行引擎初始化...");
this._projectPath = projectPath;
this._isControlPruview = isControlPurview;
return this.Reload(isAutoRun);
}
#endregion
#region 重新加载工程
/// <summary>
/// 重新加载工程
/// </summary>
/// <param name="isAutoRun">是否自动执行自启动Action</param>
public bool Reload(bool isAutoRun)
{
LoggingService.Info("工程文件路径:" + this._projectPath);
string projectFile = String.Empty;
string[] files = Directory.GetFiles(this._projectPath, "*.mprj", SearchOption.TopDirectoryOnly);
if (files != null && files.Length == 1)
{
projectFile = files[0];
}
if (!String.IsNullOrWhiteSpace(projectFile))
{
this._tree = new TreeView();
this._tree.LoadFromXml(projectFile); //载入工程文件
this.ResetProjectDataSourceFactory(); //重置数据源
}
else
{
LoggingService.Error("缺少工程文件(mprj)...让系统以超级用户方式运行...");
UserInfo.Instance.UserID = "-99";
UserInfo.Instance.UserName = "-99";
UserInfo.Instance.RoleID = "-99";
return false;
}
string wizardName = this._tree.Nodes[0].Tag as string; //获取工程类型
Mesnac.Basic.RunSchema.Instance.ProjectPath = this._projectPath; //设置组态工程文件路径
Mesnac.Basic.RunSchema.Instance.EventConfigPath = Path.Combine(Application.StartupPath, "Data", "EventConfig", wizardName); //设置事件处理配置文件路径
if (this._isLoad)
{
new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { Factory.Instance.AllReadStop(); })).Start(); //重新载入时先异步把设备变量的读取停止
this._isLoad = false;
}
string equipConfigFile = String.Empty; //保存设备配置文件
TreeNode nodeDevices = this._tree.GetFirstNodeByNodeName(FixNodeName.NodeDeviceName);
if (nodeDevices != null)
{
equipConfigFile = Path.Combine(this._projectPath, nodeDevices.GetPathNoRoot()) + ".xml";
}
if (File.Exists(equipConfigFile))
{
Mesnac.Equips.Factory.Instance.ProjectWizardName = wizardName;
Mesnac.Equips.Factory.Instance.ConfigFile = equipConfigFile;
Mesnac.Equips.Factory.Instance.SetAllReadDataEvent(OnReadData);
Mesnac.Equips.Factory.Instance.SetAllExceptEvent(OnExceptData);
new System.Threading.Thread(new System.Threading.ThreadStart(delegate()
{
Mesnac.Equips.Factory.Instance.AllReadStart();
})).Start(); //异步启动设备读取线程
this._isLoad = true;
}
Mesnac.ActionService.Service.Instance.IniRuntimeAction(wizardName, isAutoRun);
return true;
}
#endregion
#region 获取工程数据源文件
/// <summary>
/// 获取工程数据源文件
/// </summary>
/// <returns></returns>
private string GetProjectDataSourceFile()
{
string fileName = String.Empty;
if (this._tree != null)
{
TreeNode node = this._tree.GetFirstNodeByNodeName(FixNodeName.NodeDataSourceName);
fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
return fileName;
}
else
{
LoggingService.Debug("获取工程数据源文件失败,原因:工程面板未初始化!");
return String.Empty;
}
}
#endregion
#region 重置工程数据源工厂,从文件读取数据
/// <summary>
/// 重置工程数据源工厂,从文件读取数据
/// </summary>
private void ResetProjectDataSourceFactory(params CallBackDelegate[] callBack)
{
string fileName = this.GetProjectDataSourceFile();
if (!String.IsNullOrEmpty(fileName))
{
DataSourceFactory.Instance.RefreshDataFromFile(fileName, callBack);
}
}
#endregion
#endregion
#region 2、画面仿真主业务相关方法
#region 画面仿真方法
/// <summary>
/// 画面仿真方法
/// </summary>
/// <param name="node">要仿真的画面节点</param>
/// <param name="showType">画面显示方式Document、Form、Dialog</param>
public void Simulation(TreeNode node, FormShowType showType)
{
try
{
if (!this._isLoad)
{
LoggingService.Debug("运行引擎未初始化,或组态工程缺少设备文件...");
//LoggingService.Error("运行引擎未初始化... 请调用RunEngine.Init(string projectPath)进行初始化工作或缺少设备文件");
}
//防止跨线程访问控件报告异常
Control.CheckForIllegalCrossThreadCalls = false;
string fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
//LoggingService.Debug(fileName);
if (!String.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
FrmRunTemplate frm = null;
//LoggingService.Info(fileName);
#region 获取要呈现的画面
#region 清除已释放的窗体对象
if (this._runForms.ContainsKey(node.Name))
{
if (this._runForms[node.Name].IsDisposed)
{
this._runForms.Remove(node.Name);
}
}
#endregion
if (!this._runForms.ContainsKey(node.Name))
{
#region 清除已释放的窗体对象
string[] viewKeys = Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.Keys.ToArray();
foreach (string key in viewKeys)
{
if ((Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic[key] as FrmRunTemplate).IsDisposed)
{
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.Remove(key);
}
}
#endregion
if (!Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.ContainsKey(Path.GetFileNameWithoutExtension(fileName)))
{
#region 构建画面组件和组件属性、事件
Dictionary<string, ObjectDescriptor> dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List<IComponent> components = hsManager.basicHostLoader.mComponents;
frm = new FrmRunTemplate();
this._runForms.Add(node.Name, frm);
if (components.Count > 0)
{
frm = CopyComponent(dic, components[0], frm) as FrmRunTemplate; //复制窗体属性
}
for (int i = 1; i < components.Count; i++)
{
Type t = components[i].GetType();
Component c = Activator.CreateInstance(t) as Component;
c = CopyComponent(dic, components[i], c);
string componentName = GetComponentName(components[i]);
if (c is Control)
{
Control parentControl = FindParentControl(dic, frm as Control, c as Control);
if (parentControl == null)
{
frm.Controls.Add(c as Control);
}
else
{
parentControl.Controls.Add(c as Control);
}
}
else
{
string siteName = c.Site.Name;
frm.Container.Add(c);
c.Site.Name = siteName;
}
BindEvent(c); //绑定事件
}
//释放资源
hostControl.Dispose();
System.GC.Collect();
BindEvent(frm);
frm.Disposed += new EventHandler(frm_Disposed); //仿真画面关闭时
#endregion
}
else
{
frm = Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic[Path.GetFileNameWithoutExtension(fileName)] as FrmRunTemplate;
}
}
else
{
frm = this._runForms[node.Name] as FrmRunTemplate;
}
#endregion
#region 画面呈现
switch (showType)
{
case FormShowType.Document: //文档显示
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm);
break;
case FormShowType.Form: //窗体显示
frm.Show();
break;
case FormShowType.Dialog: //对话框显示
frm.ShowDialog(Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench as Form);
break;
case FormShowType.MultiScreen: //多屏显示
Screen[] screens = Screen.AllScreens;
if (screens.Length > 1) //如果有多个显示器,显示在第二个显示器
{
foreach (Screen screen in screens)
{
if (!screen.Primary)
{
frm.ShowInTaskbar = false; //不在任务栏中显示
frm.Show();
frm.Left = screen.WorkingArea.Location.X;
frm.Top = screen.WorkingArea.Location.Y;
frm.WindowState = FormWindowState.Maximized;
frm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
}
}
else
{
//如果只有一个显示器,以文档方式显示
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm);
}
break;
case FormShowType.FloatWindow: //浮动显示
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm, Mesnac.Docking.DockState.Float);
break;
}
#endregion
}
}
catch (Exception ex)
{
LoggingService.Error(ex.Message);
LoggingService.Error(ex.StackTrace);
}
}
#endregion
public void Run(string formFile, Panel panelControl)
{
TreeNode nodeForm = Tree.GetFirstNodeByNodeName(formFile);
Simulation(nodeForm, panelControl);
}
#region Panel画面仿真
/// <summary>
/// 画面仿真方法
/// </summary>
/// <param name="node">要仿真的画面节点</param>
/// <param name="showType">画面显示方式Document、Form、Dialog</param>
public void Simulation(TreeNode node, Panel panelControl)
{
try
{
lock (String.Empty)
{
if (!this._isLoad)
{
LoggingService.Debug("运行引擎未初始化,或组态工程缺少设备文件...");
}
//防止跨线程访问控件报告异常
Control.CheckForIllegalCrossThreadCalls = false;
string fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
if (!String.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
FrmRunTemplate frm = null;
if (this._runForms.ContainsKey(node.Name))
{
if (this._runForms[node.Name].IsDisposed)
{
this._runForms.Remove(node.Name);
}
}
if (!this._runForms.ContainsKey(node.Name))
{
Dictionary<string, ObjectDescriptor> dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List<IComponent> components = hsManager.basicHostLoader.mComponents;
frm = new FrmRunTemplate();
this._runForms.Add(node.Name, frm);
if (components.Count > 0)
{
frm = CopyComponent(dic, components[0], frm) as FrmRunTemplate; //复制窗体属性
}
for (int i = 1; i < components.Count; i++)
{
Type t = components[i].GetType();
Component c = Activator.CreateInstance(t) as Component;
c = CopyComponent(dic, components[i], c);
string componentName = GetComponentName(components[i]);
if (c is Control)
{
Control parentControl = FindParentControl(dic, frm as Control, c as Control);
if (parentControl == null)
{
frm.Controls.Add(c as Control);
}
else
{
parentControl.Controls.Add(c as Control);
}
}
else
{
string siteName = c.Site.Name;
frm.Container.Add(c);
c.Site.Name = siteName;
}
BindEvent(c); //绑定事件
}
//释放资源
hostControl.Dispose();
System.GC.Collect();
BindEvent(frm);
frm.FormClosing += new FormClosingEventHandler(frm_Disposed); //仿真画面关闭时
}
else
{
frm = this._runForms[node.Name] as FrmRunTemplate;
}
if (frm.MCPurview)
{
FrmSysLogin login = new FrmSysLogin(frm, null);
if (login.ShowDialog() != DialogResult.OK)
return;
login.Close();
}
//隐藏窗口
//foreach (KeyValuePair<string, Form> item in this._runForms)
//{
// if (item.Key.ToLower() == "mainbottom" || item.Key.ToLower() == "sulfmointer" || item.Key.ToLower() == "maintop")
// continue;
// FrmRunTemplate frmhid = item.Value as FrmRunTemplate;
// //frmhid.Hide();
//}
frm.TopLevel = false;
frm.Dock = System.Windows.Forms.DockStyle.Fill;
frm.FormBorderStyle = FormBorderStyle.None;
panelControl.Controls.Add(frm);
frm.Show();
frm.BringToFront();
}
}
}
catch (Exception ex)
{
LoggingService.Error(ex.Message);
LoggingService.Error(ex.StackTrace);
}
}
#endregion
#region 仿真方法注释
/*
/// <summary>
/// 仿真方法
/// </summary>
public void Simulation(TreeNode node, bool isDialog)
{
try
{
if (!this._isLoad)
{
//LoggingService.Error("运行引擎未初始化... 请调用RunEngine.Init(string projectPath)进行初始化工作或缺少设备文件");
}
//防止跨线程访问控件报告异常
Control.CheckForIllegalCrossThreadCalls = false;
string fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
//LoggingService.Debug(fileName);
if (!String.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
FrmRunTemplate frm = null;
//LoggingService.Info(fileName);
if (!this._runForms.ContainsKey(node.Name))
{
if (!Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.ContainsKey(Path.GetFileNameWithoutExtension(fileName)))
{
Dictionary<string, ObjectDescriptor> dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List<IComponent> components = hsManager.basicHostLoader.mComponents;
frm = new FrmRunTemplate();
this._runForms.Add(node.Name, frm);
if (components.Count > 0)
{
frm = CopyComponent(dic, components[0], frm) as FrmRunTemplate; //复制窗体属性
}
for (int i = 1; i < components.Count; i++)
{
Type t = components[i].GetType();
Component c = Activator.CreateInstance(t) as Component;
c = CopyComponent(dic, components[i], c);
string componentName = GetComponentName(components[i]);
if (c is Control)
{
Control parentControl = FindParentControl(dic, frm as Control, c as Control);
if (parentControl == null)
{
frm.Controls.Add(c as Control);
}
else
{
parentControl.Controls.Add(c as Control);
}
}
else
{
string siteName = c.Site.Name;
frm.Container.Add(c);
c.Site.Name = siteName;
}
BindEvent(c); //绑定事件
}
//释放资源
hostControl.Dispose();
System.GC.Collect();
BindEvent(frm);
frm.FormClosing += new FormClosingEventHandler(frm_FormClosing); //仿真画面关闭时
}
else
{
frm = Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic[Path.GetFileNameWithoutExtension(fileName)] as FrmRunTemplate;
}
}
else
{
frm = this._runForms[node.Name] as FrmRunTemplate;
}
if (isDialog)
{
//frm.TopLevel = true;
//frm.AutoScroll = true;
frm.Show();
}
else
{
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm);
}
}
}
catch (Exception ex)
{
LoggingService.Error(ex.Message);
LoggingService.Error(ex.StackTrace);
}
}
* */
#endregion
#region 递归获取窗体下的所有控件
/// <summary>
/// 获取窗体内的所有控件,包括子级
/// </summary>
/// <param name="frm"></param>
/// <returns></returns>
private static Control[] GetAllControlsByForm(Form frm)
{
List<Control> controlList = new List<Control>();
GetAllControlsByParentControl(controlList, frm);
return controlList.ToArray();
}
/// <summary>
/// 递归获取控件下的子级控件
/// </summary>
/// <param name="controlList"></param>
/// <param name="parentControl"></param>
private static void GetAllControlsByParentControl(List<Control> controlList, Control parentControl)
{
foreach (Control c in parentControl.Controls)
{
controlList.Add(c);
GetAllControlsByParentControl(controlList, c);
}
}
#endregion
#region 递归获取当前控件的父级控件
/// <summary>
/// 递归获取当前控件的父级控件
/// </summary>
/// <param name="dic">xml窗体文件中的ObjectDescriptor集合</param>
/// <param name="top">顶层控件一般是Form</param>
/// <param name="c">当前控件</param>
/// <returns>返回当前控件的父级控件</returns>
private static Control FindParentControl(Dictionary<string, ObjectDescriptor> dic, Control top, Control c)
{
string componentName = GetComponentName(c);
foreach (Control ct in top.Controls)
{
Control parent = FindParentControl(dic, ct, c);
if (parent != null)
{
return parent;
}
if (ct.Site != null && ct.Site.Name == dic[componentName].ParentName)
{
return ct;
}
}
return null;
}
#endregion
#region 复制组件属性
/// <summary>
/// 复制组件属性
/// </summary>
/// <param name="dic">xml窗体文件中的ObjectDescriptor集合</param>
/// <param name="source">源组件</param>
/// <param name="destination">目标组件</param>
/// <returns>返回复制完属性后的目标组件</returns>
private static Component CopyComponent(Dictionary<string, ObjectDescriptor> dic, IComponent source, IComponent destination)
{
Type t = source.GetType();
Component c = destination as Component;
//BindEvent(c); //绑定事件
if (source.Site != null)
{
if (c.Site == null)
{
c.Site = (new IDEContainer(source.Site.GetService(typeof(IDesignerHost)) as IDesignerHost)).CreateSite(c);
c.Site.Name = source.Site.Name;
}
else
{
c.Site.Name = source.Site.Name;
}
}
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(source); //获取原组件的设计时属性集合
System.Reflection.PropertyInfo[] properties = t.GetProperties();
System.Reflection.FieldInfo[] fields = t.GetFields();
foreach (System.Reflection.FieldInfo f in fields)
{
if (f.Name == "isRuntime")
{
f.SetValue(c, true);
}
else
{
f.SetValue(c, f.GetValue(source));
}
}
string componentName = GetComponentName(source);
List<string> lstProperties = dic[componentName].Properties;
foreach (System.Reflection.PropertyInfo p in properties)
{
if (p.CanRead & p.CanWrite && lstProperties.Contains(p.Name))
{
PropertyDescriptor pd = pdc[p.Name];
p.SetValue(c, pd.GetValue(source), null);
}
else if (p.CanRead && lstProperties.Contains(p.Name) && typeof(IList).IsAssignableFrom(p.PropertyType))
{
//处理工具栏,菜单栏中项集合的属性
PropertyDescriptor pd = pdc[p.Name];
IList listSourceValue = pd.GetValue(source) as IList;
IList listDestinationValue = p.GetValue(c, null) as IList;
object[] objs = new object[listSourceValue.Count];
listSourceValue.CopyTo(objs, 0);
foreach (object obj in objs)
{
if (obj.GetType().IsPublic)
{
object instance = Activator.CreateInstance(obj.GetType());
instance = CopyComponent(dic, obj as Component, instance as Component);
listDestinationValue.Add(instance);
BindEvent(instance as Component); //绑定事件
}
}
}
}
return c;
}
#endregion
#region 获取组件名称
/// <summary>
/// 获取组件名称
/// </summary>
/// <param name="source">要获取名称的组件</param>
/// <returns>返回组件名称</returns>
private static string GetComponentName(IComponent source)
{
if (source.Site != null && !String.IsNullOrEmpty(source.Site.Name))
{
return source.Site.Name;
}
string componentInfo = source.ToString();
string componentName = String.Empty;
if (componentInfo.IndexOf("[") > 0)
{
componentName = componentInfo.Substring(0, componentInfo.IndexOf("[") - 1).Trim();
}
else if (componentInfo.IndexOf("{") > 0)
{
componentName = componentInfo.Substring(componentInfo.IndexOf("{") + 1, componentInfo.IndexOf("}") - componentInfo.IndexOf("{") - 1).Trim();
}
else
{
componentName = componentInfo;
}
return componentName;
}
#endregion
#region 为组件绑定事件
/// <summary>
/// 绑定事件
/// </summary>
/// <param name="o">要绑定事件的组件对象</param>
private static void BindEvent(Component o)
{
string t = o.GetType().Name;
XmlNode tmpXEventNode = PublicConfig.Instance.EventXmlDoc.SelectSingleNode(String.Format("Components/Component[@Name=\"{0}\"]", t));
if (tmpXEventNode != null)
{
XmlNodeList tmpXActionLst = tmpXEventNode.SelectNodes("Propertys/Property");
foreach (XmlNode node in tmpXActionLst)
{
System.Reflection.PropertyInfo propertyInfo = o.GetType().GetProperty(node.Attributes["Name"].Value); //获取事件名称属性
if (propertyInfo == null)
{
continue;
}
object actionList = propertyInfo.GetValue(o, null);
if (actionList != null)
{
List<Mesnac.Controls.Base.DesignAction> tmpActionList = actionList as List<Mesnac.Controls.Base.DesignAction>;
if (tmpActionList == null || tmpActionList.Count == 0)
{
continue; //如果控件的事件列表中没有绑定事件则不执行事件绑定
}
if (node.Attributes["ControlPropertyName"] == null) continue;
string eventId = node.Attributes["ControlPropertyName"].Value;//获取事件名称属性控制的事件属性
if (!String.IsNullOrEmpty(eventId))
{
System.Reflection.EventInfo eInfo = o.GetType().GetEvent(eventId);
if (eInfo != null)
{
if (o.GetType() == typeof(FrmRunTemplate))
{
if (RunEngine.Instance.IsControlPruview == false)
{
(o as FrmRunTemplate).MCPurview = RunEngine.Instance.IsControlPruview; //修改窗体的权限控制属性值,主要用于区分设计(不控制权限)和运行环境。
}
}
MCEventHandler eventProcessor = new MCEventHandler(o, actionList);
//MCEventHandler eventProcessor = new MCEventHandler(o, actionList, eventId);
Type handlerType = eInfo.EventHandlerType;
MethodInfo invokeMethod = handlerType.GetMethod("Invoke");
if (invokeMethod != null)
{
ParameterInfo[] parms = invokeMethod.GetParameters();
Type[] parmTypes = new Type[parms.Length];
for (int i = 0; i < parms.Length; i++)
{
parmTypes[i] = parms[i].ParameterType;
}
AssemblyName aName = new AssemblyName();
aName.Name = "DynamicTypes" + Guid.NewGuid().ToString(); //防止动态程序集重复
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName,
AssemblyBuilderAccess.Run);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
string typeBuidlerName = "Handler" + Guid.NewGuid().ToString(); //防止动态类型定义重复
TypeBuilder tb = mb.DefineType(typeBuidlerName, TypeAttributes.Public);
string dynamicHandlerName = "DynamicHandler_" + Guid.NewGuid().ToString(); //防止同一控件的多个方法名称重复
MethodBuilder handler = tb.DefineMethod(dynamicHandlerName, MethodAttributes.Public, invokeMethod.ReturnType, parmTypes);
ILGenerator il = handler.GetILGenerator();
il.Emit(OpCodes.Ldstr, "触发调用");
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldstr, eventId);
il.EmitCall(OpCodes.Callvirt, eventProcessor.GetType().GetMethod("ExecuteAction"), null);
il.Emit(OpCodes.Ret);
Type finished = tb.CreateType();
object helper = Activator.CreateInstance(finished);
MethodInfo eventHandler = finished.GetMethod(dynamicHandlerName);
Delegate d = Delegate.CreateDelegate(handlerType, helper, eventHandler);
eInfo.AddEventHandler(o, d);
}
}
}
}
}
}
}
#endregion
#region 设备数据读取处理(把设备变量的值绑定到对应组件的属性上)
#region 设备数据的读取方法
/// <summary>
/// 设备数据读取委托定义,用于处理跨线程访问控件属性的处理
/// </summary>
/// <param name="sender">事件源</param>
/// <param name="e">设备变量读取事件对象</param>
private delegate void FormReadDataDelegate(object sender, ReadEventArgs e);
/// <summary>
/// 设备数据的读取方法
/// </summary>
/// <param name="sender">事件源</param>
/// <param name="e">设备变量读取事件对象</param>
private void OnReadData(object sender, ReadEventArgs e)
{
try
{
//ICSharpCode.Core.LoggingService.Debug("开始刷新界面" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
Form[] runForms = this._runForms.Values.ToArray<Form>();
foreach (Form frm in runForms)
{
#region 过滤掉隐藏的窗口和没有动画的窗口
if (frm.Visible == false)
{
continue;
}
if (frm is FrmRunTemplate)
{
if ((frm as FrmRunTemplate).BHaveAction == false)
{
continue;
}
}
#endregion
if (frm.InvokeRequired)
{
FormReadDataDelegate d = new FormReadDataDelegate(ProcessReadData);
frm.BeginInvoke(d, new object[] { frm, e });
continue;
}
//ProcessReadData(frm , e);
}
//ICSharpCode.Core.LoggingService.Debug("结束刷新界面" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
}
catch (Exception ex)
{
//记录错误日志
ICSharpCode.Core.LoggingService.Error(ex.Message);// + "\r\n" + ex.StackTrace);
//MessageBox.Show(ex.Message);
}
}
#endregion
#region 把设备变量的值绑定到对应组件的属性上
/// <summary>
/// 把设备变量的值绑定到对应组件的属性上
/// </summary>
/// <param name="sender">事件源</param>
/// <param name="e">设备变量读取事件对象</param>
private void ProcessReadData(object sender, ReadEventArgs e)
{
//ICSharpCode.Core.LoggingService.Debug("设备开始绑定" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
try
{
Form frm = sender as Form;
//int n = frm.Controls.Count;
Control[] controls = GetAllControlsByForm(frm);
int n = controls.Length;
for (int i = 0; i < n; i++)
{
//Control o = frm.Controls[i];
Control o = controls[i];
string t = o.GetType().Name;
XmlNode tmpXActionNode = PublicConfig.Instance.ActionXmlDoc.SelectSingleNode(String.Format("Components/Component[@Name=\"{0}\"]", t));
if (tmpXActionNode != null)
{
XmlNodeList tmpXActionLst = tmpXActionNode.SelectNodes("Propertys/Property");
foreach (XmlNode node in tmpXActionLst)
{
System.Reflection.PropertyInfo propertyInfo = o.GetType().GetProperty(node.Attributes["Name"].Value); //获取动画属性
if (propertyInfo == null)
{
continue;
}
object varName = propertyInfo.GetValue(o, null);
if (varName != null)
{
if (node.Attributes["ControlPropertyName"] == null) continue;
System.Reflection.PropertyInfo controlProperty = o.GetType().GetProperty(node.Attributes["ControlPropertyName"].Value); //获取动画控制的属性
if (controlProperty != null)
{
try
{
if (e.Data.ContainsKey(varName.ToString())) //变量
{
//e.Data.
lock (o)
{
controlProperty.SetValue(o, this.ChangeType(e.Data[varName.ToString()], controlProperty.PropertyType.UnderlyingSystemType), null);
}
}
else
{
try
{
object d = ExpressValue(varName.ToString());
if (d != null && !(d is bool))
{
lock (o)
{
controlProperty.SetValue(o, this.ChangeType(d, controlProperty.PropertyType.UnderlyingSystemType), null);
}
}
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService.Error(varName.ToString() + ex.Message + "\r\n" + ex.StackTrace);
}
}
}
catch (Exception ex)
{
//ICSharpCode.Core.LoggingService.Error(varName.ToString() + "=" + e.Data[varName.ToString()].ToString());
ICSharpCode.Core.LoggingService.Error(varName.ToString() + ex.Message + "\r\n" + ex.StackTrace);
}
}
}
}
}
}
//ICSharpCode.Core.LoggingService.Debug("设备绑定已结束" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
}
catch (Exception ex)
{
//ICSharpCode.Core.LoggingService.Error(varName.ToString() + ex.Message + "\r\n" + ex.StackTrace);
}
}
#endregion
#endregion
#region 设备数据读取异常处理
private delegate void FormExceptDataDelegate(object sender, Exception e);
private void OnExceptData(object sender, Exception ex)
{
//设备数据出错时的事件处理程序
}
#endregion
#region 把目标值转换为指定类型的对象
/// <summary>
/// 把目标值转换为指定类型的对象
/// </summary>
/// <param name="value">目标值</param>
/// <param name="type">要转换的目标类型</param>
/// <returns>返回转换指定类型后的对象</returns>
private object ChangeType(object value, Type type)
{
if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
if (value == null) return null;
if (type == value.GetType()) return value;
if (type.IsEnum)
{
if (value is string)
return Enum.Parse(type, value as string);
else
return Enum.ToObject(type, Convert.ToInt32(value));
}
if (!type.IsInterface && type.IsGenericType)
{
Type innerType = type.GetGenericArguments()[0];
object innerValue = ChangeType(value, innerType);
return Activator.CreateInstance(type, new object[] { innerValue });
}
if (value is string && type == typeof(Guid)) return new Guid(value as string);
if (value is string && type == typeof(Version)) return new Version(value as string);
if (!(value is IConvertible)) return value;
return Convert.ChangeType(value, type);
}
#endregion
#region 仿真画面关闭业务处理
/// <summary>
/// 仿真画面关闭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frm_Disposed(object sender, EventArgs e)
{
Form frm = sender as Form;
if (this._runForms.ContainsKey(frm.Name))
{
this._runForms.Remove(frm.Name);
}
}
/// <summary>
/// 关闭所有画面
/// </summary>
public void CloseAllForms()
{
string[] frmNames = new string[this._runForms.Keys.Count];
this._runForms.Keys.CopyTo(frmNames, 0);
foreach (string frmName in frmNames)
{
if (this._runForms.ContainsKey(frmName))
{
if (!this._runForms[frmName].IsDisposed)
{
this._runForms[frmName].Close();
this._runForms.Remove(frmName);
}
}
}
}
#endregion
#endregion
#region 3、表达式与函数处理
//函数传到这个回调函数里
static object express_OnCallBack(string funcName, object[] param, ref bool isOk)
{
isOk = true;
string fun = funcName.ToUpper();
if (fun.Equals("SIN"))
{
return Math.Sin(Convert.ToDouble(param[0]));
}
else if (fun.Equals("COS"))
{
return Math.Cos(Convert.ToDouble(param[0]));
}
else if (fun.Equals("LOG10"))
{
return Math.Log10(Convert.ToDouble(param[0]));
}
else if (fun.Equals("EXP"))
{
return Math.Exp(Convert.ToDouble(param[0]));
}
else if (fun.Equals("ASIN"))
{
return Math.Asin(Convert.ToDouble(param[0]));
}
else if (fun.Equals("ACOS"))
{
return Math.Acos(Convert.ToDouble(param[0]));
}
else if (fun.Equals("ABS"))
{
return Math.Abs(Convert.ToDecimal(param[0]));
}
else if (fun.Equals("ATAN"))
{
return Math.Atan(Convert.ToDouble(param[0]));
}
else if (fun.Equals("CEILING"))
{
return Math.Ceiling(Convert.ToDouble(param[0]));
}
else if (fun.Equals("COSH"))
{
return Math.Cosh(Convert.ToDouble(param[0]));
}
else if (fun.Equals("FLOOR"))
{
return Math.Floor(Convert.ToDouble(param[0]));
}
else if (fun.Equals("SINH"))
{
return Math.Sinh(Convert.ToDouble(param[0]));
}
else if (fun.Equals("SQRT"))
{
return Math.Sqrt(Convert.ToDouble(param[0]));
}
else if (fun.Equals("TAN"))
{
return Math.Tan(Convert.ToDouble(param[0]));
}
else if (fun.Equals("TANH"))
{
return Math.Tanh(Convert.ToDouble(param[0]));
}
else if (fun.Equals("TRUNCATE"))
{
return Math.Truncate(Convert.ToDouble(param[0]));
}
isOk = false;
return 0;
}
//变量传到这个回调函数里
bool express_OnAccidenceAnalysis(ref Mesnac.Basic.Operand opd)
{
if (opd.Type == Mesnac.Basic.OperandType.STRING)
{
Dictionary<string, Mesnac.Equips.BaseEquip> allEquips = Mesnac.Equips.Factory.Instance.AllEquips;
foreach (string key in allEquips.Keys)
{
Dictionary<string, Mesnac.Equips.BaseInfo.Group> allGroups = allEquips[key].Group;
foreach (string key2 in allGroups.Keys)
{
//Dictionary<string, Mesnac.Equips.BaseInfo.Data> datas = allGroups[key2].Data;
Mesnac.Equips.BaseInfo.Data[] datas = new Equips.BaseInfo.Data[allGroups[key2].Data.Count];
allGroups[key2].Data.Values.CopyTo(datas, 0);
foreach (Mesnac.Equips.BaseInfo.Data data in datas)
{
if (data.KeyName.Equals(opd.Value.ToString()))
{
opd.Type = Mesnac.Basic.OperandType.NUMBER;
opd.Value = data.Value;
return true;
}
}
}
}
opd.Type = Mesnac.Basic.OperandType.NUMBER;
opd.Value = 0;
return false;
}
else
{
return true;
}
}
/// <summary>
/// 表达式求值
/// </summary>
/// <param name="sExpress"></param>
/// <returns></returns>
private object ExpressValue(string sExpress)
{
bool bok = express.Parse(sExpress);
if (bok)
{
bool ok = false;
object d = express.Evaluate(ref ok);
if (ok)
{
return d;
}
}
return null;
}
#endregion
public FrmRunTemplate getActiveFrmByName(string NodeName)
{
FrmRunTemplate frm = null;
if (this._runForms.ContainsKey(NodeName))
{
frm = this._runForms[NodeName] as FrmRunTemplate;
}
return frm;
}
/// <summary>
/// 获取主界面
/// </summary>
/// <returns></returns>
public void returnMainPage(string frmName)
{
string[] Formkey = this._runForms.Keys.ToArray<string>();
foreach (string key in Formkey)
{
if (this._runForms[key].Name != "Main")//这是主页面
{
if (this._runForms[key].Name.ToUpper() == "AUTO")//这是曲线页面
{
this._runForms[key].Hide();
}
else
{
this._runForms[key].Close();
}
}
}
}
}
}