public TopicInfo(ExcelRtdServer.Topic topic, string alias, string tab, string sym, string col, string hist) { Topic = topic; Alias = alias; Table = tab; Symbol = sym; Column = col; History = hist; }
// Forwarded from XlCall // Loads the RTD server with temporary ProgId. // CAUTION: Might fail when called from array formula (the first call in every array-group fails). // When it fails, the xlfRtd call returns xlReturnUncalced. // In that case, this function returns null, and does not keep a reference to the created server object. // The next call should then succeed (though a new server object will be created). public static bool TryRTD(out object result, string progId, string server, params string[] topics) { Debug.Print("### RtdRegistration.RTD " + progId); // Check if this is any of our business. Type rtdServerType; if (!string.IsNullOrEmpty(server) || !registeredRtdServerTypes.TryGetValue(progId, out rtdServerType)) { // Just pass on to Excel. return(TryCallRTD(out result, progId, null, topics)); } // TODO: Check that ExcelRtdServer with stable ProgId case also works right here - // might need to add to loadedRtdServers somehow // Check if already loaded. string loadedProgId; if (loadedRtdServers.TryGetValue(progId, out loadedProgId)) { if (ExcelRtd2010BugHelper.ExcelVersionHasRtdBug && rtdServerType.IsSubclassOf(typeof(ExcelRtdServer))) { ExcelRtd2010BugHelper.RecordRtdCall(progId, topics); } // Call Excel using the synthetic RtdSrv_xxx (or actual from attribute) ProgId return(TryCallRTD(out result, loadedProgId, null, topics)); } // Not loaded already - need to get the Rtd server loaded // TODO: Need to reconsider registration here..... // Sometimes need stable ProgIds. object rtdServer; if (ExcelRtd2010BugHelper.ExcelVersionHasRtdBug && rtdServerType.IsSubclassOf(typeof(ExcelRtdServer))) { Debug.Print("### Creating Wrapper " + progId); rtdServer = new ExcelRtd2010BugHelper(progId, rtdServerType); } else { using (XlCall.Suspend()) { rtdServer = Activator.CreateInstance(rtdServerType); } ExcelRtdServer excelRtdServer = rtdServer as ExcelRtdServer; if (excelRtdServer != null) { // Set ProgId so that it can be 'unregistered' (removed from loadedRtdServers) when the RTD server terminates. excelRtdServer.RegisteredProgId = progId; } else { // Make a wrapper if we are not an ExcelRtdServer // (ExcelRtdServer implements exception-handling and XLCall supension itself) rtdServer = new RtdServerWrapper(rtdServer, progId); } } // We pick a new Guid as ClassId for this add-in... CLSID clsId = Guid.NewGuid(); // ... (bad idea - this will cause Excel to try to load this RTD server while it is not registered.) // Guid typeGuid = GuidUtilit.CreateGuid(..., DnaLibrary.XllPath + ":" + rtdServerType.FullName); // or something based on ExcelDnaUtil.XllGuid // string progIdRegistered = "RtdSrv_" + typeGuid.ToString("N"); // by making a fresh progId, we are sure Excel will try to load when we are ready. // Change from RtdSrv.xxx to RtdSrv_xxx to avoid McAfee bug that blocks registry writes with a "." anywhere string progIdRegistered = "RtdSrv_" + clsId.ToString("N"); Debug.Print("RTD - Using ProgId: {0} for type: {1}", progIdRegistered, rtdServerType.FullName); try { using (new SingletonClassFactoryRegistration(rtdServer, clsId)) using (new ProgIdRegistration(progIdRegistered, clsId)) using (new ClsIdRegistration(clsId, progIdRegistered)) { Debug.Print("### About to call TryCallRTD " + progId); if (TryCallRTD(out result, progIdRegistered, null, topics)) { // Mark as loaded - ServerTerminate in the wrapper will remove. loadedRtdServers[progId] = progIdRegistered; Debug.Print("### Added to loadedRtdServers " + progId); return(true); } return(false); } } catch (UnauthorizedAccessException secex) { Logger.RtdServer.Error("The RTD server of type {0} required by add-in {1} could not be registered.\r\nThis may be due to restricted permissions on the user's HKCU\\Software\\Classes key.\r\nError message: {2}", rtdServerType.FullName, DnaLibrary.CurrentLibrary.Name, secex.Message); result = ExcelErrorUtil.ToComError(ExcelError.ExcelErrorValue); // Return true to have the #VALUE stick, just as it was before the array-call refactoring return(true); } catch (Exception ex) { Logger.RtdServer.Error("The RTD server of type {0} required by add-in {1} could not be registered.\r\nThis is an unexpected error.\r\nError message: {2}", rtdServerType.FullName, DnaLibrary.CurrentLibrary.Name, ex.Message); Debug.Print("RtdRegistration.RTD exception: " + ex.ToString()); result = ExcelErrorUtil.ToComError(ExcelError.ExcelErrorValue); // Return true to have the #VALUE stick, just as it was before the array-call refactoring return(true); } }
protected internal Topic(ExcelRtdServer server, int topicId, object initialValue) { _server = server; _topicId = topicId; _value = initialValue; }
protected internal Topic(ExcelRtdServer server, int topicId) { _server = server; _topicId = topicId; _value = ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA); }
internal Topic(ExcelRtdServer server, int topicId) { _server = server; TopicId = topicId; }
protected internal Topic(ExcelRtdServer server, int topicId) { _server = server; TopicId = topicId; _value = ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA); }
// Forwarded from XlCall // Loads the RTD server with temporary ProgId. public static object RTD(string progId, string server, params string[] topics) { // Check if this is any of our business. if (!string.IsNullOrEmpty(server) || !registeredRtdServerTypes.ContainsKey(progId)) { // Just pass on to Excel. return(CallRTD(progId, null, topics)); } // Check if already loaded. if (loadedRtdServers.ContainsKey(progId)) { // Call Excel using the synthetic RtdSrv.xxx (or actual from attribute) ProgId return(CallRTD(loadedRtdServers[progId], null, topics)); } // Not loaded already - need to get the Rtd server loaded // TODO: Need to reconsider registration here..... // Sometimes need stable ProgIds. Type rtdServerType = registeredRtdServerTypes[progId]; object rtdServer = Activator.CreateInstance(rtdServerType); ExcelRtdServer excelRtdServer = rtdServer as ExcelRtdServer; if (excelRtdServer != null) { // Set ProgId so that it can be 'unregistered' (removed from loadedRtdServers) when the RTD sever terminates. excelRtdServer.RegisteredProgId = progId; } else { // Make a wrapper if we are not an ExcelRtdServer // (ExcelRtdServer implements exception-handling and XLCall supension itself) rtdServer = new RtdServerWrapper(rtdServer, progId); } // We pick a new Guid as ClassId for this add-in... CLSID clsId = Guid.NewGuid(); // ... (bad idea - this will cause Excel to try to load this RTD server while it is not registered.) // Guid typeGuid = GuidUtilit.CreateGuid(..., DnaLibrary.XllPath + ":" + rtdServerType.FullName); // string progIdRegistered = "RtdSrv." + typeGuid.ToString("N"); // by making a fresh progId, we are sure Excel will try to load when we are ready. string progIdRegistered = "RtdSrv." + clsId.ToString("N"); Debug.Print("RTD - Using ProgId: {0} for type: {1}", progIdRegistered, rtdServerType.FullName); try { using (new SingletonClassFactoryRegistration(rtdServer, clsId)) using (new ProgIdRegistration(progIdRegistered, clsId)) using (new ClsIdRegistration(clsId, progIdRegistered)) { object result; if (TryCallRTD(out result, progIdRegistered, null, topics)) { // Mark as loaded - ServerTerminate in the wrapper will remove. // TODO: Consider multithread race condition... loadedRtdServers[progId] = progIdRegistered; } return(result); } } catch (UnauthorizedAccessException secex) { Logging.LogDisplay.WriteLine("The RTD server of type {0} required by add-in {1} could not be registered.\r\nThis may be due to restricted permissions on the user's HKCU\\Software\\Classes key.\r\nError message: {2}", rtdServerType.FullName, DnaLibrary.CurrentLibrary.Name, secex.Message); return(ExcelErrorUtil.ToComError(ExcelError.ExcelErrorValue)); } }
//-------------------------------------------------------------------// /// <summary> /// Removes given topic from internal mpapings /// </summary> /// <param name="topic">topic id to be removed</param> public void RemoveTopic(ExcelRtdServer.Topic topic) { if (!_revMap.ContainsKey(topic)) return; var t = _revMap[topic]; //get table,sym,col var list = _topicMap[t.Item1][t.Item2][t.Item3]; foreach (var ti in list.Where(ti => ti.Topic == topic)) { list.Remove(ti); break; } _revMap.Remove(topic); }
//-------------------------------------------------------------------// /// <summary> /// Provides mapping between given topic id from Excel RTD and table,symbol,column /// from kdb+ /// </summary> /// <param name="topic">RTD formula topic id</param> /// <returns>Triplet: table,symbol,column or null in case topic is not mapped</returns> public Tuple<string, string, string> GetMapKeys(ExcelRtdServer.Topic topic) { return _revMap.ContainsKey(topic) ? _revMap[topic] : null; }
//-------------------------------------------------------------------// /// <summary> /// Verifies whether given topic exists in internal mappings /// </summary> /// <param name="topic">topic id</param> /// <returns>ture in case topic is present, false otherwise</returns> public bool ContainsTopic(ExcelRtdServer.Topic topic) { return _revMap.ContainsKey(topic); }
public Topic(ExcelRtdServer server, int topicId) { _server = server; TopicId = topicId; }
protected internal Topic(ExcelRtdServer server, int topicId, object initialValue) { _server = server; _topicId = topicId; _value = initialValue; }
internal ExcelRtdObserver(ExcelRtdServer.Topic topic) { _topic = topic; Value = ExcelError.ExcelErrorNA; }
public Topic(ExcelRtdServer server, int topicId) { _server = server; TopicId = topicId; }
public TestArrayTopic(ExcelRtdServer server, int topicId) : base(server, topicId) { }