using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Text; using CIA_CSS; using IndianHealthService.BMXNet.EHR.Model; namespace IndianHealthService.BMXNet.EHR { /// /// The EhrFramework integrates the COM-based EHR/VueCentric framework with BMXNET. /// A component that uses BMXNET for communications, events, and context can be implemented to /// be hosted within the EHR/VueCentric framework by creating a subclass of UserControl and including /// the a EHR integration partial class similar to the following: /// /// ///partial class YourEHRComponent : CSS_Patient.ICSS_PatientEvents, CSS_Encounter.ICSS_EncounterEvents, CIA_CSS.ICSS_SessionEvents, IEhrEvents, IEhrComponent ///{ /// /// #region Copy Region into partial EHR file plus include interfaces noted above /// /// protected override void Dispose(bool disposing) /// { /// this.TeardownFramework(); /// /// if (disposing && (components != null)) /// { /// components.Dispose(); /// } /// base.Dispose(disposing); /// } /// /// public LocalSession LocalSession /// { /// get { return this.Framework.LocalSession; } /// } /// /// public Context Context /// { /// get { return this.LocalSession.Context; } /// } /// /// public RemoteSession RemoteSession /// { /// get { return this.Framework.RemoteSession; } /// } /// /// private String _helpString = ""; /// /// [ComVisible(true)] /// public String HelpString /// { /// get { return _helpString; } /// set { _helpString = value; } /// } /// /// private String _helpContext = ""; /// /// [ComVisible(true)] /// public String HelpContext /// { /// get { return _helpContext; } /// set { _helpContext = value; } /// } /// private String _helpFile = ""; /// [ComVisible(true)] /// public String HelpFile /// { /// get { return _helpFile; } /// set { _helpFile = value; } /// } /// /// public virtual void AttachToEhr(object aConsumer) /// { /// this.SetupFramework(); /// this.Framework.AttachTo(aConsumer); /// /// if (this.HelpFile.Length == 0) /// { /// this.HelpFileAssemblyName(aConsumer.GetType()); /// } /// } /// /// private EhrFramework _framework = null; /// /// public EhrFramework Framework /// { /// get { return _framework; } /// set { _framework = value; } /// } /// /// protected void SetupFramework() /// { /// this.Framework = EhrFramework.On(new CIA_CSS.CSS_ServerClass().Session, (IEhrEvents)this, (CIA_CSS.ICSS_SessionEvents)this); /// } /// ///protected void TeardownFramework() ///{ /// if (this.Framework != null) /// { /// this.Framework.Close(); /// } ///} /// ///public event EventHandler<ContextChangedArgs> ContextChanged; ///public event EventHandler<ContextChangingArgs> ContextChanging; /// /// void CSS_Encounter.ICSS_EncounterEvents.Canceled() /// { /// } /// /// void CSS_Encounter.ICSS_EncounterEvents.Committed() /// { /// try /// { /// if (this.ContextChanged != null) /// { /// ContextChangedArgs args = new ContextChangedArgs(); /// args.IsVisitChange = true; /// args.AfterContext = this.Context; /// this.ContextChanged.Invoke(this, args); /// } /// } /// catch /// { /// } /// } /// /// string CSS_Encounter.ICSS_EncounterEvents.Pending(bool Silent) /// { /// try /// { /// if (this.ContextChanging == null) /// { /// return ""; /// } /// else /// { /// ContextChangingArgs args = new ContextChangingArgs(); /// args.BeforeContext = this.Context; /// args.IsVisitChange = true; /// args.Cancel = false; /// this.ContextChanging.Invoke(this, args); /// /// return args.Cancel ? "Cancel" : ""; /// } /// } /// catch /// { /// return ""; /// } /// } /// ///void CSS_Patient.ICSS_PatientEvents.Canceled() ///{ ///} /// ///void CSS_Patient.ICSS_PatientEvents.Committed() ///{ ///try ///{ ///if (this.ContextChanged != null) ///{ ///ContextChangedArgs args = new ContextChangedArgs(); ///args.IsPatientChange = true; ///args.AfterContext = this.Context; ///this.ContextChanged.Invoke(this, args); ///} ///} ///catch ///{ ///} ///} /// /// string CSS_Patient.ICSS_PatientEvents.Pending(bool Silent) /// { /// try /// { /// if (this.ContextChanging == null) /// { /// return ""; /// } /// else /// { /// ContextChangingArgs args = new ContextChangingArgs(); /// args.BeforeContext = this.Context; /// args.IsPatientChange = true; /// args.Cancel = false; /// this.ContextChanging.Invoke(this, args); /// /// return args.Cancel ? "Cancel" : ""; /// } /// } /// catch /// { /// return ""; /// } ///} /// /// protected virtual void UnhandledException(Exception aProblem) /// { /// MessageBox.Show(aProblem.Message + " \n\n\n" + aProblem.StackTrace, "Exception"); /// } /// /// protected void HelpFileAssemblyName(Type aType) /// { /// this.HelpFile = aType.Assembly.GetName().Name + ".chm"; /// } /// /// public void EventCallback(string anEvent, string aStub) /// { /// this.Framework.IncomingEventCallback(anEvent, aStub); /// } /// /// public void RPCCallback(int Handle, string Data) /// { /// } /// /// public void RPCCallbackError(int Handle, int ErrorCode, string ErrorText) /// { /// } /// /// #endregion /// /// } /// /// /// //Copy this interface too /// public interface IEhrComponent : IDisposable /// { /// String HelpFile { get; } /// String HelpContext { get; } /// String HelpString { get; } /// } /// } /// /// /// /// See the BMXNET SDK IndianHealthService.BMXNet.Example.CrossComponent.EHR Project as an example. /// /// public class EhrFramework { /// /// Used to create the single EhrFramework instance used for each EHR/VueCentric-based component /// /// /// Use the provided partial class to construct a UserControl-based component to host in the EHR/VueCentric framework /// /// A COM instance of CSS_Session. The EhrFramework will Release() it /// The event source bridge to pass events from your COM-Visible control to the EhrFramework /// A COM instance of ICSS_SessionEvents. The EhrFramework will Release() it /// public static EhrFramework On(CIA_CSS.CSS_Session aCssSession, IEhrEvents anEventSource, CIA_CSS.ICSS_SessionEvents sessionEvents) { EhrFramework answer = new EhrFramework(); answer.Setup(aCssSession, anEventSource, sessionEvents); return answer; } private CSS_Session _cssSession = null; protected CSS_Session CssSession { get { return _cssSession; } set { _cssSession = value; } } private LocalSession _localSession = null; /// /// Access the LocalSession. /// /// This is used by the partial class to prime your LocalSessionConsumer implementing control /// /// public LocalSession LocalSession { get { return _localSession; } set { _localSession = value; } } private RemoteSession _remoteSession = null; /// /// Access the primary RemoteSession. /// /// This is used by the partial class to prime your RemoteSessionConsumer implementing control /// /// public RemoteSession RemoteSession { get { return _remoteSession; } set { _remoteSession = value; } } private BMXNetBroker _broker = null; internal BMXNetBroker Broker { get { return _broker; } set { _broker = value; } } protected void Setup(CIA_CSS.CSS_Session aCssSession, IEhrEvents anEventSource, CIA_CSS.ICSS_SessionEvents sessionEvents) { this.CssSession = aCssSession; CiaSession ciaSession = new CiaSession(aCssSession, anEventSource); ciaSession.ComComponent = sessionEvents; this.LocalSession = ciaSession; this.Broker = BMXNetEhrBroker.Open(ciaSession.CssSession, ciaSession.CssUser, ciaSession.User); this.RemoteSession = this.Broker.PrimaryRemoteSession; ciaSession.RemoteSession = this.Broker.PrimaryRemoteSession; } /// /// Close the EhrFramework /// /// Releases all COM objects /// /// public void Close() { if (this.LocalSession != null) { ((CiaSession)this.LocalSession).Teardown(); this.LocalSession = null; } } /// /// Forward an incoming event from the COM object to the EhrFramework /// /// This string corresponds to well-known/shared EventTypes used to identify /// different events published and subscribed within a local desktop application (WinFramework) /// or in the EHR. /// This is an optional peice of data with some event-specific details. public void IncomingEventCallback(string anEventType, string someDetails) { ((CiaSession)this.LocalSession).IncomingEventCallback(anEventType, someDetails); } /// /// Attach the services to the aConsumer. This is basically a push of services versus a service lookup. /// aConsumer will be offered to cosume: /// /// LocalSession via LocalConsumer /// RemoteSession via RemoteSessionConsumer /// RemoteSessionPool via RemoteSessionPoolConsumer /// /// /// An object optionally implementing LocalConsumer, RemoteSessionConsumer, and/or RemoteSessionPoolConsumer public void AttachTo(object aConsumer) { LocalConsumer localConsumer = aConsumer as LocalConsumer; if (localConsumer != null) { localConsumer.LocalSession = this.LocalSession; } RemoteSessionConsumer remoteConsumer = aConsumer as RemoteSessionConsumer; if (remoteConsumer != null) { remoteConsumer.RemoteSession = this.RemoteSession; } RemoteSessionPoolConsumer remotePoolConsumer = aConsumer as RemoteSessionPoolConsumer; if (remotePoolConsumer != null) { remotePoolConsumer.RemoteSessionPool = this.Broker.RemoteSessionPool; } if (this.LocalSession == null) throw new Exception("BMX: Unable to establish application model"); if (this.LocalSession.Context == null) throw new Exception("BMX: Unable to establish context"); } } }