public void Test_RemoveTransactionFilter()
 {
     using var context = new DdeContext();
     var filter = new TransactionFilter();
     context.AddTransactionFilter(filter);
     context.RemoveTransactionFilter(filter);
 }
예제 #2
0
 public void Test_IsInitialized_Variation_1()
 {
     using (DdeContext context = new DdeContext())
     {
         Assert.IsFalse(context.IsInitialized);
     }
 }
예제 #3
0
 public void Test_Initialize()
 {
     using (DdeContext context = new DdeContext())
     {
         context.Initialize();
     }
 }
예제 #4
0
 public TestServer(string service, DdeContext context)
     : base(service, context)
 {
     _Timer.Elapsed += new ElapsedEventHandler(this.OnTimerElapsed);
     _Timer.Interval = 1000;
     _Timer.SynchronizingObject = base.Context;
 }
예제 #5
0
 public void Test_Ctor_Overload_2()
 {
     using (var context = new DdeContext())
     {
         DdeServer server = new TestServer(ServiceName);
     }
 }
예제 #6
0
 public void Test_Ctor_Overload_2()
 {
     using (DdeContext context = new DdeContext())
     {
         DdeClient client = new DdeClient(ServiceName, TopicName, context);
     }
 }
 public void Test_AddTransactionFilter_After_Dispose()
 {
     using var context = new DdeContext();
     IDdeTransactionFilter filter = new TransactionFilter();
     context.Dispose();
     Assert.Throws<ObjectDisposedException>(() => context.AddTransactionFilter(filter));
 }
예제 #8
0
 public void Test_IsInitialized_Variation_2()
 {
     using (DdeContext context = new DdeContext())
     {
         context.Initialize();
         Assert.IsTrue(context.IsInitialized);
     }
 }
예제 #9
0
 public void Test_Initialize_After_Dispose()
 {
     using (DdeContext context = new DdeContext())
     {
         context.Dispose();
         context.Initialize();
     }
 }
예제 #10
0
 public void Test_AddTransactionFilter()
 {
     using (DdeContext context = new DdeContext())
     {
         IDdeTransactionFilter filter = new TransactionFilter();
         context.AddTransactionFilter(filter);
     }
 }
 public void Test_Initialize_After_Dispose()
 {
     using (var context = new DdeContext())
     {
         context.Dispose();
         Assert.Throws<ObjectDisposedException>(() => context.Initialize());
     }
 }
 public void Test_Initialize_After_Initialize()
 {
     using (var context = new DdeContext())
     {
         context.Initialize();
         Assert.Throws<InvalidOperationException>(() => context.Initialize());
     }
 }
예제 #13
0
 ///<summary>Sends data for pat to the Dexis Integrator program using a DDE Execute command.  Shows a message box if pat is null instructing user
 ///to first select a pat.  Sends SET command with the following format: SET 17 LN="LName" FN="FName" MI="MiddleI" BD=19760205.  The first
 ///parameter of the command is the patient ID defined by the program property as either PatNum or ChartNumber.  The BD portion will only be added
 ///if the pat has a valid bday and adding it to the commmand won't increase the length of the command to >255 characters.</summary>
 public static void SendData(Program progCur, Patient pat)
 {
     if (pat == null)
     {
         MsgBox.Show("DexisIntegrator", "Please select a patient first.");
         return;
     }
     try {
         if (_client == null || _client.Context == null)
         {
             DdeContext context = new DdeContext(Application.OpenForms.OfType <FormOpenDental>().FirstOrDefault() ?? Application.OpenForms[0]);
             _client = new DdeClient("Dexis", "Patient", context);
         }
         if (!_client.IsConnected)
         {
             _client.Connect();
         }
         string patId = pat.PatNum.ToString();
         if (ProgramProperties.GetPropVal(progCur.ProgramNum, "Enter 0 to use PatientNum, or 1 to use ChartNum") == "1")
         {
             patId = pat.ChartNumber;
         }
         string ddeCommand = "SET " + patId + " LN=\"" + pat.LName + "\" FN=\"" + pat.FName + "\" MI=\"" + pat.MiddleI + "\"";
         if (pat.Birthdate.Year > 1880 && ddeCommand.Length < 244)             //add optional bday only if valid and it won't increase the length to >255 characters
         {
             ddeCommand += " BD=" + pat.Birthdate.ToString("yyyyMMdd");
         }
         _client.Execute(ddeCommand, 30000);               //timeout 30 seconds
         //if execute was successfully sent, subscribe the PatientChangedEvent_Fired handler to the PatientChangedEvent.Fired event
         PatientChangedEvent.Fired -= PatientChangedEvent_Fired;
         PatientChangedEvent.Fired += PatientChangedEvent_Fired;
         UserodChangedEvent.Fired  -= UserodChangedEvent_Fired;
         UserodChangedEvent.Fired  += UserodChangedEvent_Fired;
     }
     catch (ObjectDisposedException ode) {
         if (_isRetry)
         {
             FriendlyException.Show(Lans.g("DexisIntegrator", "There was an error trying to launch Dexis with the selected patient."), ode);
             return;
         }
         _isRetry = true;
         if (_client != null && _client.IsConnected)
         {
             ODException.SwallowAnyException(new Action(() => _client.Disconnect()));                    //disconnect if necessary
         }
         ODException.SwallowAnyException(new Action(() => _client.Dispose()));
         _client = null;              //will cause a new _client to be made with a new context
         SendData(progCur, pat);
     }
     catch (Exception ex) {
         FriendlyException.Show(Lans.g("DexisIntegrator", "There was an error trying to launch Dexis with the selected patient."), ex);
         return;
     }
     finally {
         _isRetry = false;
     }
 }
예제 #14
0
 public void Test_RemoveTransactionFilter_After_Dispose()
 {
     using (DdeContext context = new DdeContext())
     {
         TransactionFilter filter = new TransactionFilter();
         context.AddTransactionFilter(filter);
         context.Dispose();
         context.RemoveTransactionFilter(filter);
     }
 }
        public void Test_TransactionFilter()
        {
            using var context = new DdeContext();
            var filter = new TransactionFilter();
            context.AddTransactionFilter(filter);
            context.Initialize();
            using (DdeServer server = new TestServer(ServiceName))
            {
                server.Register();
            }

            Assert.IsTrue(filter.Received.WaitOne(Timeout, false));
        }
        public void Test_Register()
        {
            using var context = new DdeContext();
            var listener = new EventListener();
            context.Register += listener.OnEvent;
            context.Initialize();
            using (DdeServer server = new TestServer(ServiceName))
            {
                server.Register();
            }

            Assert.IsTrue(listener.Received.WaitOne(Timeout, false));
        }
예제 #17
0
파일: DentX.cs 프로젝트: mnisl/OD
		///<summary>Launches the program using the patient.Cur data.</summary>
		public static void SendData(Program ProgramCur, Patient pat){
			ArrayList ForProgram=ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;
			if(pat==null){
				MessageBox.Show("Please select a patient first");
				return;
			}
			//Get the program path from the ini file
			string windir=Environment.GetEnvironmentVariable("windir");// C:\WINDOWS
			string iniFile=windir+"\\dentx.ini";
			if(!File.Exists(iniFile)){
				MessageBox.Show("Could not find "+iniFile);
				return;
			}
			//Make sure the program is running
			string proimagePath=ReadValue(iniFile,"imagemgt","MainFile");
			Process[] proImageInstances=Process.GetProcessesByName("ProImage");
			if(proImageInstances.Length==0){
				Process.Start(proimagePath);
				Thread.Sleep(TimeSpan.FromSeconds(10));
			}
			//command="Xray,PatientNo,FirstName,LastName,Birth Date,Sex,Address,City,State,Code"(zip)
			string command="Xray,";
			//PatientNo can be any string format up to 9 char
			ProgramProperty PPCur=ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
			if(PPCur.PropertyValue=="0"){
				command+=pat.PatNum.ToString()+",";
			}
			else{
				if(pat.ChartNumber==""){
					MessageBox.Show("ChartNumber for this patient is blank.");
					return;
				}
				command+=pat.ChartNumber.Replace(",","")+",";
			}
			command+=pat.FName.Replace(",","")+","
				+pat.LName.Replace(",","")+","
				+pat.Birthdate.ToShortDateString()+",";
			if(pat.Gender==PatientGender.Female)
				command+="F,";
			else
				command+="M,";
			command+=pat.Address.Replace(",","")+","
				+pat.City.Replace(",","")+","
				+pat.State.Replace(",","")+","
				+pat.Zip.Replace(",","");
			//MessageBox.Show(command);
			try {
				//Create a context that uses a dedicated thread for DDE message pumping.
				using(DdeContext context=new DdeContext()){
					//Create a client.
					using(DdeClient client=new DdeClient("ProImage","Image",context)){
						//Establish the conversation.
						client.Connect();
						//Start ProImage and open to the Xray Chart screen
						client.Execute(command,2000);//timeout 2 secs
					}
				}
			}
			catch{
				//MessageBox.Show(e.Message);
			}
		}
예제 #18
0
        ///<summary>Launches the program using the patient.Cur data.</summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            List <ProgramProperty> ForProgram = ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;

            if (pat == null)
            {
                MessageBox.Show("Please select a patient first");
                return;
            }
            //Get the program path from the ini file
            string windir  = Environment.GetEnvironmentVariable("windir");         // C:\WINDOWS
            string iniFile = windir + "\\dentx.ini";

            if (!File.Exists(iniFile))
            {
                MessageBox.Show("Could not find " + iniFile);
                return;
            }
            //Make sure the program is running
            string proimagePath = ReadValue(iniFile, "imagemgt", "MainFile");

            Process[] proImageInstances = Process.GetProcessesByName("ProImage");
            if (proImageInstances.Length == 0)
            {
                ODFileUtils.ProcessStart(proimagePath);
                Thread.Sleep(TimeSpan.FromSeconds(10));
            }
            //command="Xray,PatientNo,FirstName,LastName,Birth Date,Sex,Address,City,State,Code"(zip)
            string command = "Xray,";
            //PatientNo can be any string format up to 9 char
            ProgramProperty PPCur = ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;

            if (PPCur.PropertyValue == "0")
            {
                command += pat.PatNum.ToString() + ",";
            }
            else
            {
                if (pat.ChartNumber == "")
                {
                    MessageBox.Show("ChartNumber for this patient is blank.");
                    return;
                }
                command += pat.ChartNumber.Replace(",", "") + ",";
            }
            command += pat.FName.Replace(",", "") + ","
                       + pat.LName.Replace(",", "") + ","
                       + pat.Birthdate.ToShortDateString() + ",";
            if (pat.Gender == PatientGender.Female)
            {
                command += "F,";
            }
            else
            {
                command += "M,";
            }
            command += pat.Address.Replace(",", "") + ","
                       + pat.City.Replace(",", "") + ","
                       + pat.State.Replace(",", "") + ","
                       + pat.Zip.Replace(",", "");
            //MessageBox.Show(command);
            try {
                //Create a context that uses a dedicated thread for DDE message pumping.
                using (DdeContext context = new DdeContext()){
                    //Create a client.
                    using (DdeClient client = new DdeClient("ProImage", "Image", context)){
                        //Establish the conversation.
                        client.Connect();
                        //Start ProImage and open to the Xray Chart screen
                        client.Execute(command, 2000);                       //timeout 2 secs
                    }
                }
            }
            catch {
                //MessageBox.Show(e.Message);
            }
        }
예제 #19
0
        private string _Service      = "";    // This is a cached DdemlServer property.


        /// <overloads>
        /// <summary>
        /// </summary>
        /// </overloads>
        /// <summary>
        /// This initializes a new instance of the <c>DdeServer</c> class that can register the specified service name.
        /// </summary>
        /// <param name="service">
        /// The service name that this instance can register.
        /// </param>
        /// <exception cref="ArgumentException">
        /// This is thown when service exceeds 255 characters..
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// This is thrown when service is a null reference.
        /// </exception>
        public DdeServer(string service)
            : this(service, DdeContext.GetDefault())
        {
        }
예제 #20
0
 /// <summary>
 /// This initializes a new instance of the <c>DdeServer</c> class that can register the specified service name and uses the specified
 /// context.
 /// </summary>
 /// <param name="service">
 /// The service name that this instance can register.
 /// </param>
 /// <param name="context">
 /// The context to use for execution.
 /// </param>
 /// <exception cref="ArgumentException">
 /// This is thown when service exceeds 255 characters..
 /// </exception>
 /// <exception cref="ArgumentNullException">
 /// This is thrown when service is a null reference.
 /// </exception>
 public DdeServer(string service, DdeContext context)
 {
     Service = service;
     Context = context;
 }
예제 #21
0
 /// <summary>
 /// This initializes a new instance of the <c>DdeServer</c> class that can register the specified service name and using the specified
 /// synchronizing object.
 /// </summary>
 /// <param name="service">
 /// The service name that this instance can register.
 /// </param>
 /// <param name="synchronizingObject">
 /// The synchronizing object to use for this instance.
 /// </param>
 /// <exception cref="ArgumentException">
 /// This is thown when service exceeds 255 characters..
 /// </exception>
 /// <exception cref="ArgumentNullException">
 /// This is thrown when service is a null reference.
 /// </exception>
 public DdeServer(string service, ISynchronizeInvoke synchronizingObject)
     : this(service, DdeContext.GetDefault(synchronizingObject))
 {
 }
예제 #22
0
 ///// <summary>
 ///// 
 ///// </summary>
 //public event EventHandler<DdeStringActivityEventArgs> StringActivity
 //{
 //    add
 //    {
 //        lock (_LockObject)
 //        {
 //            _StringActivityEvent += value;
 //        }
 //    }
 //    remove
 //    {
 //        lock (_LockObject)
 //        {
 //            _StringActivityEvent -= value;
 //        }
 //    }
 //}
 /// <summary>
 /// This initializes a new instance of the <c>DdeMonitor</c> class.
 /// </summary>
 public DdeMonitor()
 {
     Context = new DdeContext();
 }
예제 #23
0
        ///// <summary>
        ///// 
        ///// </summary>
        //public event EventHandler<DdeStringActivityEventArgs> StringActivity
        //{
        //    add
        //    {
        //        lock (_LockObject)
        //        {
        //            _StringActivityEvent += value;
        //        }
        //    }
        //    remove
        //    {
        //        lock (_LockObject)
        //        {
        //            _StringActivityEvent -= value;
        //        }
        //    }
        //}

        /// <summary>
        /// This initializes a new instance of the <c>DdeMonitor</c> class.
        /// </summary>
        public DdeMonitor()
        {
            Context = new DdeContext();
        }
예제 #24
0
		///<summary>Launches the program if necessary.  Then passes patient.Cur data using DDE.</summary>
		public static void SendData(Program ProgramCur, Patient pat){
			string path=Programs.GetProgramPath(ProgramCur);
			ArrayList ForProgram=ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;
			if(pat==null){
				MessageBox.Show("Please select a patient first");
				return;
			}
			//The path is available in the registry, but we'll just make the user enter it.
			if(!File.Exists(path)){
				MessageBox.Show("Could not find "+path);
				return;
			}
			//Make sure the program is running
			if(Process.GetProcessesByName("DentalEye").Length==0){
				Process.Start(path);
				Thread.Sleep(TimeSpan.FromSeconds(4));
			}
			//command="[Add][PatNum][Fname][Lname][Address|Address2|City, ST Zip][phone1][phone2][mobile phone][email][sex(M/F)][birthdate (YYYY-MM-DD)]"
			ProgramProperty PPCur=ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
			string patID;
			if(PPCur.PropertyValue=="0"){
				patID=pat.PatNum.ToString();
			}
			else{
				if(pat.ChartNumber==""){
					MessageBox.Show("ChartNumber for this patient is blank.");
					return;
				}
				patID=pat.ChartNumber;
			}
			string command="[Add]["+patID+"]"
				+"["+pat.FName+"]"
				+"["+pat.LName+"]"
				+"["+pat.Address+"|";
			if(pat.Address2!=""){
				command+=pat.Address2+"|";
			}
			command+=pat.City+", "+pat.State+" "+pat.Zip+"]"
				+"["+pat.HmPhone+"]"
				+"["+pat.WkPhone+"]"
				+"["+pat.WirelessPhone+"]"
				+"["+pat.Email+"]";
			if(pat.Gender==PatientGender.Female)
				command+="[F]";
			else
				command+="[M]";
			command+="["+pat.Birthdate.ToString("yyyy-MM-dd")+"]";
			//MessageBox.Show(command);
			try {
				//Create a context that uses a dedicated thread for DDE message pumping.
				using(DdeContext context=new DdeContext()){
					//Create a client.
					using(DdeClient client=new DdeClient("DENTEYE","Patient",context)){
						//Establish the conversation.
						client.Connect();
						//Add patient or modify if already exists
						client.Execute(command,2000);//timeout 2 secs
						//Then, select patient
						command="[Search]["+patID+"]";
						client.Execute(command,2000);
					}
				}
			}
			catch{
				//MessageBox.Show(e.Message);
			}
		}
 public void Test_Ctor_Overload_2()
 {
     var context = new DdeContext(new DdeContext());
 }
예제 #26
0
 public void Test_Ctor_Overload_1()
 {
     DdeContext context = new DdeContext();
 }
 public void Test_Dispose()
 {
     using (var context = new DdeContext())
     {
     }
 }
 public void Test_Initialize()
 {
     using var context = new DdeContext();
     context.Initialize();
 }
예제 #29
0
파일: Vipersoft.cs 프로젝트: nampn/ODental
 ///<summary>Launches the program if necessary.  Then passes patient.Cur data using DDE.</summary>
 public static void SendData(Program ProgramCur, Patient pat)
 {
     ArrayList ForProgram=ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;
     if(pat==null){
         MessageBox.Show("Please select a patient first");
         return;
     }
     if(!File.Exists(ProgramCur.Path)){
         MessageBox.Show("Could not find "+ProgramCur.Path);
         return;
     }
     //Make sure the program is running
     //Documentation says to include the -nostartup command line switch (to avoid optional program preference startup command).
     if(Process.GetProcessesByName("Vipersoft").Length==0){
         Process.Start(ProgramCur.Path,"-nostartup");
         Thread.Sleep(TimeSpan.FromSeconds(4));
     }
     //Data is sent to the Vipersoft DDE Server by use of the XTYP_EXECUTE DDE message only.
     //The format ot the XTYP_EXECUTE DDE message is"
     //command="\004hwnd|name|ID|Lastname|Firstname|MI|Comments|Provider|Provider Phone|Addrs1|Addrs2|City|State|Zip|Patient Phone|Practice Name|Patient SSN|restore server|"
     //\004 is one byte code for version 4. 0x04 or Char(4)
     //hwnd is calling software's windows handle.
     //name is for name of calling software (Open Dental)
     //ID is patient ID.  Required and must be unique.
     //Provider field is for provider name.
     //hwnd, ID, Lastname, Firstname, and Provider fields are required.  All other fields are optional.
     //All vertical bars (|) are required, including the ending bar.
     //The restore server flag is for a future release's support of the specialized capture/view commands (default is '1')
     //Visual Basic pseudo code:
     //Chan = DDEInitiate("Vipersoft", "Advanced IntraOral")
     //DDE_String$ = "" //etc
     //DDEExecute Chan, DDE_String$ //send XTYP_EXECUTE DDE command:
     //DDETerminate Chan
     Char char4=Convert.ToChar(4);
     string command=char4.ToString();//tested to make sure this is just one non-printable byte.
     IntPtr hwnd=Application.OpenForms[0].Handle;
     command+=hwnd.ToString()+"|"//hwnd
         +"OpenDental|";//name
     ProgramProperty PPCur=ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
     string patID;
     if(PPCur.PropertyValue=="0"){
         patID=pat.PatNum.ToString();
     }
     else{
         if(pat.ChartNumber==""){
             MessageBox.Show("ChartNumber for this patient is blank.");
             return;
         }
         patID=pat.ChartNumber;
     }
     command+=patID+"|";//ID
     command+=pat.LName+"|";//Lastname
     command+=pat.FName+"|";//Firstname
     command+=pat.MiddleI+"|";//
     command+="|";//Comments: blank
     Provider prov=Providers.GetProv(Patients.GetProvNum(pat));
     command+=prov.LName+", "+prov.FName+"|";//Provider
     command+="|";//Provider phone
     command+="|";//Addr
     command+="|";//Addr2
     command+="|";//City
     command+="|";//State
     command+="|";//Zip
     command+="|";//Phone
     command+="|";//Practice
     command+=pat.SSN+"|";//SSN
     command+="1|";//Restore Server
     //MessageBox.Show(command);
     try {
         //Create a context that uses a dedicated thread for DDE message pumping.
         using(DdeContext context=new DdeContext()){
             //Create a client.
             using(DdeClient client=new DdeClient("Vipersoft","Advanced IntraOral",context)){
                 //Establish the conversation.
                 client.Connect();
                 //Select patient
                 client.Execute(command,2000);//timeout 2 secs
                 client.Disconnect();
             }
         }
     }
     catch{
         //MessageBox.Show(e.Message);
     }
 }
예제 #30
0
        ///<summary>Launches the program if necessary.  Then passes patient.Cur data using DDE.</summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            ArrayList ForProgram = ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;

            if (pat == null)
            {
                MessageBox.Show("Please select a patient first");
                return;
            }
            //The path is available in the registry, but we'll just make the user enter it.
            if (!File.Exists(ProgramCur.Path))
            {
                MessageBox.Show("Could not find " + ProgramCur.Path);
                return;
            }
            //Make sure the program is running
            if (Process.GetProcessesByName("DentalEye").Length == 0)
            {
                Process.Start(ProgramCur.Path);
                Thread.Sleep(TimeSpan.FromSeconds(4));
            }
            //command="[Add][PatNum][Fname][Lname][Address|Address2|City, ST Zip][phone1][phone2][mobile phone][email][sex(M/F)][birthdate (YYYY-MM-DD)]"
            ProgramProperty PPCur = ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
            string          patID;

            if (PPCur.PropertyValue == "0")
            {
                patID = pat.PatNum.ToString();
            }
            else
            {
                if (pat.ChartNumber == "")
                {
                    MessageBox.Show("ChartNumber for this patient is blank.");
                    return;
                }
                patID = pat.ChartNumber;
            }
            string command = "[Add][" + patID + "]"
                             + "[" + pat.FName + "]"
                             + "[" + pat.LName + "]"
                             + "[" + pat.Address + "|";

            if (pat.Address2 != "")
            {
                command += pat.Address2 + "|";
            }
            command += pat.City + ", " + pat.State + " " + pat.Zip + "]"
                       + "[" + pat.HmPhone + "]"
                       + "[" + pat.WkPhone + "]"
                       + "[" + pat.WirelessPhone + "]"
                       + "[" + pat.Email + "]";
            if (pat.Gender == PatientGender.Female)
            {
                command += "[F]";
            }
            else
            {
                command += "[M]";
            }
            command += "[" + pat.Birthdate.ToString("yyyy-MM-dd") + "]";
            //MessageBox.Show(command);
            try {
                //Create a context that uses a dedicated thread for DDE message pumping.
                using (DdeContext context = new DdeContext()){
                    //Create a client.
                    using (DdeClient client = new DdeClient("DENTEYE", "Patient", context)){
                        //Establish the conversation.
                        client.Connect();
                        //Add patient or modify if already exists
                        client.Execute(command, 2000);                       //timeout 2 secs
                        //Then, select patient
                        command = "[Search][" + patID + "]";
                        client.Execute(command, 2000);
                    }
                }
            }
            catch {
                //MessageBox.Show(e.Message);
            }
        }
예제 #31
0
        ///<summary>Launches the program if necessary.  Then passes patient.Cur data using DDE.</summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            ArrayList ForProgram = ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;

            if (pat == null)
            {
                MessageBox.Show("Please select a patient first");
                return;
            }
            if (!File.Exists(ProgramCur.Path))
            {
                MessageBox.Show("Could not find " + ProgramCur.Path);
                return;
            }
            //Make sure the program is running
            //Documentation says to include the -nostartup command line switch (to avoid optional program preference startup command).
            if (Process.GetProcessesByName("Vipersoft").Length == 0)
            {
                Process.Start(ProgramCur.Path, "-nostartup");
                Thread.Sleep(TimeSpan.FromSeconds(4));
            }
            //Data is sent to the Vipersoft DDE Server by use of the XTYP_EXECUTE DDE message only.
            //The format ot the XTYP_EXECUTE DDE message is"
            //command="\004hwnd|name|ID|Lastname|Firstname|MI|Comments|Provider|Provider Phone|Addrs1|Addrs2|City|State|Zip|Patient Phone|Practice Name|Patient SSN|restore server|"
            //\004 is one byte code for version 4. 0x04 or Char(4)
            //hwnd is calling software's windows handle.
            //name is for name of calling software (Open Dental)
            //ID is patient ID.  Required and must be unique.
            //Provider field is for provider name.
            //hwnd, ID, Lastname, Firstname, and Provider fields are required.  All other fields are optional.
            //All vertical bars (|) are required, including the ending bar.
            //The restore server flag is for a future release's support of the specialized capture/view commands (default is '1')
            //Visual Basic pseudo code:
            //Chan = DDEInitiate("Vipersoft", "Advanced IntraOral")
            //DDE_String$ = "" //etc
            //DDEExecute Chan, DDE_String$ //send XTYP_EXECUTE DDE command:
            //DDETerminate Chan
            Char   char4   = Convert.ToChar(4);
            string command = char4.ToString();          //tested to make sure this is just one non-printable byte.
            IntPtr hwnd    = Application.OpenForms[0].Handle;

            command += hwnd.ToString() + "|"   //hwnd
                       + "OpenDental|";        //name
            ProgramProperty PPCur = ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
            string          patID;

            if (PPCur.PropertyValue == "0")
            {
                patID = pat.PatNum.ToString();
            }
            else
            {
                if (pat.ChartNumber == "")
                {
                    MessageBox.Show("ChartNumber for this patient is blank.");
                    return;
                }
                patID = pat.ChartNumber;
            }
            command += patID + "|";                            //ID
            command += pat.LName + "|";                        //Lastname
            command += pat.FName + "|";                        //Firstname
            command += pat.MiddleI + "|";                      //
            command += "|";                                    //Comments: blank
            command += Providers.GetNameLF(pat.PriProv) + "|"; //Provider
            command += "|";                                    //Provider phone
            command += "|";                                    //Addr
            command += "|";                                    //Addr2
            command += "|";                                    //City
            command += "|";                                    //State
            command += "|";                                    //Zip
            command += "|";                                    //Phone
            command += "|";                                    //Practice
            command += pat.SSN + "|";                          //SSN
            command += "1|";                                   //Restore Server
            //MessageBox.Show(command);
            try {
                //Create a context that uses a dedicated thread for DDE message pumping.
                using (DdeContext context = new DdeContext()){
                    //Create a client.
                    using (DdeClient client = new DdeClient("Vipersoft", "Advanced IntraOral", context)){
                        //Establish the conversation.
                        client.Connect();
                        //Select patient
                        client.Execute(command, 2000);                       //timeout 2 secs
                        client.Disconnect();
                    }
                }
            }
            catch {
                //MessageBox.Show(e.Message);
            }
        }
 public TracingServer(string service, DdeContext context)
     : base(service, context)
 {
 }