我创建了一个小型C#库,它公开了一个用于显示CrystalReport查看器的COM对象。
我的C#测试应用程序中有这样的代码,可以根据需要运行并显示报告
public partial class ReportHolder : UserControl
{
private string _reportFilename;
private string _datasourcePath;
public ReportHolder(string reportFilename, string datasourcePath)
{
InitializeComponent();
_reportFilename = reportFilename;
_datasourcePath = datasourcePath;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (string.IsNullOrEmpty(_reportFilename))
return;
ReportDocument doc = new ReportDocument();
doc.Load(_reportFilename);
ConnectionInfo connectionInfo = new ConnectionInfo();
string serverName = string.Format("Driver={{Driver do Microsoft dBase (*.dbf)}};DBQ={0};DefaultDir={0};DriverId=533;FIL=dBase 5.0;UserCommitSync=Yes", _datasourcePath);
connectionInfo.ServerName = serverName;
connectionInfo.Type = ConnectionInfoType.DBFile;
Tables tables = doc.Database.Tables;
foreach (CrystalDecisions.CrystalReports.Engine.Table table in tables)
{
TableLogOnInfo logonInfo = table.LogOnInfo;
logonInfo.ConnectionInfo = connectionInfo;
table.ApplyLogOnInfo(logonInfo);
}
//doc.VerifyDatabase();
crViewer.UseWaitCursor = true;
crViewer.ReportSource = doc;
crViewer.RefreshReport();
crViewer.UseWaitCursor = false;
}
}
现在我的C#Com对象中有相同的UserControl
[ComVisible(true)]
[Guid("F8FB6B66-5A15-4396-8A81-D7B8655E2869")]
[ClassInterface(ClassInterfaceType.None)]
public class Se32ComBridge : ISe32ComBridge
{
public Se32ComBridge()
{
}
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public IntPtr ShowReport(IntPtr hWndParent, string reportFileName, string datasourcePath)
{
ReportHolder reportHolder = new ReportHolder(reportFileName, datasourcePath);
SetParent(reportHolder.Handle, hWndParent);
reportHolder.LoadReport(reportFileName, datasourcePath);
return reportHolder.Handle;
}
}
其中hwndChild
是WinAPI C ++应用程序中窗口的实际HWND。
我从本机C ++应用程序实例化,就像这样
sam32_net_bridge::ISe32ComBridgePtr pIBridge(__uuidof(sam32_net_bridge::Se32ComBridge));
_bstr_t reportFilename(_reportFilename.c_ptr());
_bstr_t datasourcePath(_datasourcePath.c_ptr());
pIBridge->ShowReport((long)hWnd, reportFilename, datasourcePath, &_controlHandle);
在这里我得到了这样的例外
System.OutOfMemoryException:类型异常 抛出'System.OutOfMemoryException'。在 System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark&安培; stackMark)at System.Threading.Thread.Start(StackCrawlMark& stackMark)at System.Threading.Thread.Start()at System.Drawing.ImageAnimator.Animate(图像,EventHandler onFrameChangedHandler)at System.Windows.Forms.ButtonBase.Animate(布尔动画)at System.Windows.Forms.ButtonBase.Animate()at System.Windows.Forms.ButtonBase.OnVisibleChanged(EventArgs e)at at System.Windows.Forms.Control.SetVisibleCore(布尔值)at System.Windows.Forms.Control.Show()at CrystalDecisions.Windows.Forms.CrystalReportViewer.ShowProgressAnimation(布尔 启用) CrystalDecisions.Windows.Forms.CrystalReportViewer.set_ReportSource(对象 价值)在sam32.net.bridge.ReportHolder.OnLoad(EventArgs e)中 \程序\ sam32.net.bridge \ ReportHolder.cs:行 52在System.Windows.Forms.UserControl.OnCreateControl()at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
在System.Windows.Forms.Control.CreateControl()at System.Windows.Forms.Control.WmShowWindow(Message& m)at System.Windows.Forms.Control.WndProc(Message& m)at System.Windows.Forms.ScrollableControl.WndProc(Message& m)at System.Windows.Forms.UserControl.WndProc(Message& m)at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)在System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32) msg,IntPtr wparam,IntPtr lparam)
在我看来,Threading在没有在完整的.NET环境中运行时会做一些有趣的事情。所以,我想知道,我还应该在这个COM对象中正确设置它还可以根据需要运行。
THX