Jay and others, Unlike JAWS and Window-Eyes, System Access currently requires that a DLL be distributed with the application that uses its API. Matt, the developer of SA, emailed me an archive with the DLL and documentation. He said I could redistribute it, so I have just posted it at http://www.EmpowermentZone.com/sa.zip Basically, the DLL is a Win32 standard one, rather than COM server, with functions to test whether SA is running and to make it speak either ANSI or Unicode strings. The EdSharp source code contains C# wrappers, but I am also posting two relevant classes below that I developed for speech and COM routines generally. Note that the code has some dependencies on other custom routines and that intermittent lines are commented out as I debugged issues. I assume someone else would adapt the code to their own program and coding style. If you have questions, however, let me know. Jamal class Voice { public static string GetJfwDir() { RegistryKey key = Registry.LocalMachine; string sSubKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\"; string sName = "Path"; string sPath = Sys.GetRegString(key, (sSubKey + "jfw.exe"), sName); if (sPath == "") { string[] sVersions = {"91", "90", "81", "80", "8", "71", "70", "7", "62", "61", "60", "6"}; sName = ""; foreach (string sVersion in sVersions) { sPath = Sys.GetRegString(key, (sSubKey + "jaws" + sVersion + ".exe"), sName); if (sPath != "") { sPath = Path.GetDirectoryName(sPath); break; } } } //if (sPath !="" && !sPath.EndsWith(@"\")) sPath = String.Concat(sPath, @"\"); sPath = sPath.TrimEnd('\\'); return sPath; } // GetJfwDir method public static string GetWEDir() { RegistryKey key = Registry.LocalMachine; string sSubKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinEyes.exe"; string sName = "Path"; string sPath = Sys.GetRegString(key, sSubKey, sName); if (sPath !="" && !sPath.EndsWith(@"\")) sPath = String.Concat(sPath, @"\"); return sPath; } // GetWEDir method [DllImport("user32.dll")] static extern bool SystemParametersInfo(int iAction, int iParam, out bool bActive, int iUpdate); public static bool IsScreenReaderActive() { int iAction = 70; // SPI_GETSCREENREADER constant; int iParam = 0; bool bActive; int iUpdate = 0; bool bReturn = SystemParametersInfo(iAction, iParam, out bActive, iUpdate); return bReturn && bActive; } // IsScreenReaderActive method public static bool IsJAWSActive(){ string sClass = "JFWUI2"; string sTitle = "JAWS"; return (int) Sys.FindWindow(sClass, sTitle) != 0; } // IsJAWSActive method public static bool IsWinEyesActive(){ //string sClass = "AfxFrameOrView42"; string sTitle = "Window-Eyes"; //return (int) FindWindow(sClass, sTitle) != 0; int iClass = 0; return (int) Sys.FindWindow(iClass, sTitle) != 0; } // IsWinEyesActive method [DllImport("jfwapi.dll")] public static extern int JFWSayString(string sText, int iInterrupt); public static bool JFWSay(string sText) { try { return JFWSayString(sText, 0) == 1; } catch { return false; } } // JFWSay method [DllImport("saapi32.dll")] public static extern int SA_IsRunning(); public static bool IsSAActive() { try { return SA_IsRunning() == 1; } catch { return false; } } // IsSAActive method [DllImport("saapi32.dll")] public static extern int SA_SayU(string sText); public static bool SASay(string sText) { try { return SA_SayU(sText) == 1; } catch { return false; } } // SASay method public static bool Say(object oText) { string sText = oText.ToString(); if (sText.Trim().Length == 0) sText = "Blank"; if (!App.ExtraSpeech) { Sys.StringAppend2FileU(sText + "\r\n", App.SpeechLog); return false; } if (Voice.JFWSay(sText)) return true; else if (Voice.SASay(sText)) return true; else if (Voice.WESay(sText)) return true; //else if (Voice.SAPISay(sText)) return true; else return false; } // Say method public static bool WESay(string sText) { //object oWE = null; //return WESay(sText, ref oWE); return WESay(sText, ref App.Wineyes); } // WESay method public static bool WESay(string sText, ref object oWE) { //if ((int) Sys.FindWindow(0, "Window-Eyes") == 0) return false; //don't even check since last resort //if (!Sys.IsWinEyesActive()) return false; try { if (oWE == null) oWE = Com.CreateObject("GwSpeak.Speak"); Com.CallMethod(oWE, "SpeakString", sText); return true; } catch { return false; } } // WESay method public static bool SAPISay(string sText) { object oSAPI = null; return SAPISay(sText, oSAPI); } // SAPISay method public static bool SAPISay(string sText, object oSAPI) { try { if (oSAPI == null) oSAPI = Com.CreateObject("SAPI.SPVoice"); Com.CallMethod(oSAPI, "Speak", sText); return true; } catch { return false; } } // SAPISay method } // Voice class public class Com { public static object CreateObject(string sProgID) { Type t = Type.GetTypeFromProgID(sProgID); object oResult = Activator.CreateInstance(t); return oResult; } // CreateObject method public static object GetObject(string sProgID) { object oResult = Interaction.GetObject(null, sProgID); return oResult; } // GetObject method public static object GetOrCreateObject(string sProgID, out bool bCreate, string sMessage) { object oResult; try { oResult = GetObject(sProgID); bCreate = false; } catch { Voice.Say(sMessage); oResult = CreateObject(sProgID); bCreate = true; } return oResult; } // GetOrCreateObject method public static object CallMethod(object o, string sMethod) { object[] args = {}; return CallMethod(o, sMethod, args); } // CallMethod method public static object CallMethod(object o, string sMethod, string sValue) { object[] args = {sValue}; return CallMethod(o, sMethod, args); } // CallMethod method public static object CallMethod(object o, string sMethod, int iValue) { object[] args = {iValue}; return CallMethod(o, sMethod, args); } // CallMethod method public static object CallMethod(object o, string sMethod, object[] args) { Type t = o.GetType(); object oResult = t.InvokeMember(sMethod, BindingFlags.InvokeMethod, null, o, args); return oResult; } // CallMethod method public static object SetProperty(object o, string sProperty, string sValue) { object[] args = {sValue}; return SetProperty(o, sProperty, args); } // SetProperty method public static object SetProperty(object o, string sProperty, int iValue) { object[] args = {iValue}; return SetProperty(o, sProperty, args); } // SetProperty method public static object SetProperty(object o, string sProperty, bool bValue) { object[] args = {bValue}; return SetProperty(o, sProperty, args); } // SetProperty method public static object SetProperty(object o, string sProperty, object[] args) { Type t = o.GetType(); object oResult = t.InvokeMember(sProperty, BindingFlags.SetProperty, null, o, args); return oResult; } // SetProperty method public static object GetProperty(object o, string sProperty) { object[] args = new object[] {}; return GetProperty(o, sProperty, args); } // GetProperty method public static object GetProperty(object o, string sProperty, object[] args) { Type t = o.GetType(); object oResult = t.InvokeMember(sProperty, BindingFlags.GetProperty, null, o, args); return oResult; } // GetProperty method public static void Release(ref object o) { Marshal.ReleaseComObject(o); o = null; } // Release method } // Com class __________ View the list's information and change your settings at //www.freelists.org/list/programmingblind