Hi All,
As part of my evaluation, I need to add some kind of COM server, or COM Callable Wrapper (CCW) around a Nevron 3D Bar Chart implementation such that select interface entries can be called from existing unmanaged MFC C++. I'm new to COM, in general, but I have to think someone has walked this path before. I'm using Visual Studio 2010, and everything is built (and registered) for x86. The System and Nevron assemblies (except for Nevron.Diagram.WinForm) seem to be resident in the GAC.
I'm attempting to interface the .NET assemblies through the IChartInterface from MFC, but can never get a pointer to the interface. The problem is CoCreateInstance in the C++ client returns an HRESULT of 0x80040154 "Class not registered" unless the interface is simplified to the extent it can't do anything I need.
These are the Registry entries found for IChartInterface:
HKEY_CLASSES_ROOT\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}
HKEY_CLASSES_ROOT\Wow6432Node\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}
HKEY_CLASSES_ROOT\Wow6432Node\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}\ProxyStubClsid32
(Default) {00020424-0000-0000-C000-000000000046}
HKEY_CLASSES_ROOT\Wow6432Node\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}\TypeLib
(Default) {1E6F43BC-F79C-4E66-B9E6-3B60B220D1BE}
Value 1.0
The NevronChartTest TypeLib Guid is 1E6F43BC-F79C-4E66-B9E6-3B60B220D1BE in the AssemblyInfo.cs file in my project. All part of COM are marked as visible
During startup, a ProcMon.exe trace of Registry activity shows no access (whatsoever) involving the IChartInterface entries.
Here's an abbreviation of what I'm trying to do in Visual Studio 2010:
// C++ Client
#import "NevronChartTest.tlb" named_guids
using namespace NevronChartTest;
CMyDialog:
nInitDialog()
{
NevronChartTest::IChartInterface *pIChartInterface = NULL;
hResult = CoInitialize(NULL);
hResult = CoCreateInstance (
CLSID_NevronChart, // in NevronChartTest.tli
NULL,
CLSCTX_INPROC_SERVER
IID_PPV_ARGS(&pIChartInterface)
);
CoUninitialize();
return (hResult ? FALSE : TRUE); // hResult: 0x80040154 "Class not registered"
}
// C# COM Server DLL
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Nevron.Dom;
using Nevron.GraphicsCore;
using Nevron.Chart;
using Nevron.Chart.WinForm;
namespace NevronChartTest
{
[ToolboxItem(false)]
[Guid("415100CE-8BCD-45F2-AF10-ADBF84F9ECE1")]
public interface IChartInterface
{
void ChartInstance(bool bOrthogonal);
void AddTitle(string Name);
void AddBarData(NBarSeries bar, double x, double y);
void AddDataPoint(NRangeSeries series, double x1, double x2, double y1, double y2, double z1, double z2);
void ClearData();
}
[ComVisible(true)]
[Guid("112CA7D7-F682-4F22-BAD5-971B855887AF")]
public partial class NevronChart : Form, IChartInterface
{
NBarSeries barSeries;
NLabel title;
bool bDisplayOrthogonal;
public NevronChart()
{
bDisplayOrthogonal = true;
InitializeComponent();
}
// COM Entry Points...
public void ChartInstance(bool bOrthogonal)
{
bDisplayOrthogonal = bOrthogonal;
InitializeComponent();
}
public void AddTitle(string Name)
{
title = new NLabel(Name);
title.Dock = DockStyle.Top;
title.TextStyle.FontStyle = new NFontStyle("Times New Roman", 18, FontStyle.Italic);
title.TextStyle.FillStyle = new NColorFillStyle(Color.Blue);
}
public void AddBarData(NBarSeries bar, double x, double y)
{
bar.AddDataPoint(new NDataPoint(x - 0.5, y)); // 1..10
nChartControl1.Refresh();
}
public void AddDataPoint(NRangeSeries series, double x1, double x2, double y1, double y2, double z1, double z2)
{
series.XValues.Add(x1);
series.X2Values.Add(x2);
series.Values.Add(y1);
series.Y2Values.Add(y2);
series.ZValues.Add(z1);
series.Z2Values.Add(z2);
}
public void ClearData()
{
// clear data
barSeries.ClearDataPoints();
}
private void NevronChart_Load(object sender, System.EventArgs e)
{
Initialize();
}
private void Initialize()
{
// ...the usual stuff...
}
/// Required designer variable.
private System.ComponentModel.IContainer components = null;
/// Clean up any resources being used.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private Nevron.Chart.WinForm.NChartControl nChartControl1;
// Windows Form Designer generated code
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
private void Initialize_Component()
{
/// ...the usual setup... (e.g a System EventHandler to call
/// NevronChart_Load(), etc.)
}
}
Steve C.