We're having some trouble getting our .NET 2.0 application working with an
ActiveX control. We're using the RTList control
(
http://www.xyris.com/products/rtlist.htm). I've created the interop
assemblies using aximp. It appears that we're communicating with the control
and get back the results, but sometime afterwards our application terminates
with no messages. I did attach WinDbg to our application, and while I'm not
sure we had the proper symbols for the OS, it appeared we terminated because
we jumped to some invalid location (eip was some invalid address). We're
using events exposed by the ActiveX control to communicate with it. Is there
anything special we need to be aware of in this interop scenario? Our
application does have the [STAThread] attribute on the Main() entry point.
Below is a snippet of our code:
// Initialization
internal RTListPricingFeedManager(VWAPMultiplier[] vwapMultipliers,
Country[] volume1xPrice1Countries,
Exchange[] ignoreVolumeAccumulatedExchanges, string reutersSource, string
bloombergSource)
{
_hiddenContainerForm = new HiddenContainerForm();
_axRTList = _hiddenContainerForm._axRTList;
_axRTList.ChangeEx += new
AxRTList._DRTListEvents_ChangeExEventHandler(_axRT List_ChangeEx);
_axRTList.SnapComplete += new EventHandler(_axRTList_SnapComplete);
foreach (VWAPMultiplier vwapMultiplier in vwapMultipliers)
_countryToVWAPMultiplier.Add(vwapMultiplier.Countr y,
vwapMultiplier.Multiplier);
foreach (Country country in volume1xPrice1Countries)
_volume1xPrice1CountriesSet.Add(country.Name, null);
foreach (Exchange exchange in ignoreVolumeAccumulatedExchanges)
_ignoreVolumeAccumulatedExchangesSet.Add(exchange. Name, null);
_reutersSourceName = reutersSource;
_bloombergSourceName = bloombergSource;
}
// Method that kicks off the work.
internal override bool Request(
Pricing.StrikeOption strikeOption,
SecurityCollection securityCollection,
IPricingResults pricingResults,
Pricing.PrimaryOrComposite otcPorC,
Pricing.PrimaryOrComposite listedPorC,
TimeSpan compositeStartTime,
TimeSpan compositeEndTime,
TimeSpan primaryStartTime,
TimeSpan primaryEndTime,
DateTime vwapDate,
int timeout,
bool allowException,
out string errorText)
{
bool retVal = true;
_currentSecurityCollection = securityCollection;
_currentPricingResults = pricingResults;
errorText = "";
try
{
_axRTList.Clear();
if (_log.IsDebugEnabled)
_log.DebugFormat("RTList Source = '{0}'", GetSourceText(strikeOption));
_axRTList.Source = GetSourceText(strikeOption);
_strikeOptionArray = new Pricing.StrikeOption
[_currentSecurityCollection.Count];
int index = 0;
foreach (Security security in _currentSecurityCollection)
{
string requestString = GetRequestString(security, strikeOption, otcPorC,
listedPorC, compositeStartTime, compositeEndTime, primaryStartTime,
primaryEndTime, vwapDate);
if (_log.IsDebugEnabled)
_log.DebugFormat("Adding request item: '{0}'", requestString);
_axRTList.AddItem(requestString, index);
_strikeOptionArray[index] = strikeOption;
index++;
}
_snapComplete = false;
if (_log.IsDebugEnabled)
_log.Debug("Sending request");
_axRTList.Mode = (short)Modes.Manual;
int sleepDuration = 100;
for (int i = 0; i < timeout / 100; i++)
{
Application.DoEvents();
if (_snapComplete)
break;
System.Threading.Thread.Sleep(sleepDuration);
}
if (!_snapComplete)
throw new ApplicationException("Request timed out");
}
catch (Exception e)
{
if (allowException)
throw;
retVal = false;
errorText = e.Message;
}
return retVal;
}
// Event handlers
private void _axRTList_ChangeEx(object sender,
AxRTList._DRTListEvents_ChangeExEvent e)
{
int index = e.itemIndex;
Security security = _currentSecurityCollection[index];
try
{
double resultValue = CalculateResultValue(security,
_strikeOptionArray[index], (object[])_axRTList.ItemValueToArray(index));
_currentPricingResults.SetResult(security, resultValue);
}
catch (Exception exc)
{
_log.Warn("Error in _axRTList_ChangeEx", exc);
}
}
private void _axRTList_SnapComplete(object sender, EventArgs e)
{
_axRTList.Mode = (short)Modes.None;
_snapComplete = true;
if (_log.IsDebugEnabled)
_log.Debug("Snap complete");
}
Also, this class above is a member of another class that is a member of a
WinForm. Each time we price something (use this ActiveX to get a price) we
create a new instance of this WinForm which creates a pricing component which
creates the above component. And as you can see the above component creates
a HiddenContainerForm which contains the ActiveX control. I know that was
probably a confusing explanation.
--
Thanks,
Nick
nicknospamdu (AT) community (DOT) nospam
remove "nospam" change community. to msn.com