2

我们管理和开发的程序是用 C++/MFC 编写的。我们希望将其现代化为 .NET,但不想立即重写整个应用程序。因此,我们正在考虑用 .NET 编写程序的新部分,同时用 C++/MFC 维护程序的其余部分。

当我们在 Internet 上读到这一点时,它说了很多关于从托管代码调用非托管代码的内容。但我们想以另一种方式来做。我们查到了一些资料表明是可以的,但是看起来非常繁琐和繁琐。

那可能吗?这是一个很好的解决方案吗?有没有更好的方法来逐步使程序现代化?

4

2 回答 2

4

这是使用 C++/CLI 来使用 C++/MFC 代码中的 .NET 部分的常用方法。当你了解它时,它并不难。.NET UI 控件应该有一个方法来设置父窗口的 HWND 和控件的大小(虽然不是所有的都有)。许多 .NET 组件遇到的另一件事是 .NET 程序集的混淆,这会阻止使用来自 C++/CLI 的控件。

我们是一家 .net 图表制造商,客户已使用我们的产品对其应用程序进行现代化改造。我们有关于如何从 C++/CLI 使用 .NET 图表的文档和示例应用程序。

#using "Arction.LightningChartUltimate.dll"
using namespace Arction::LightningChartUltimate;

//"Global managed variables"  
ref class GlobalObjects {
public:
   static Arction::LightningChartUltimate::LightningChartUltimate^ chart; 
}; 

void CMainFrame::CreateChart(HWND hwndParent)
{

    GlobalObjects^ go = gcnew GlobalObjects();

    //Embeddable trial key is used here. 
    go->chart = gcnew LightningChartUltimate("licensekey"); 

    LightningChartUltimate^ chart = go->chart;

    //Disable repaints for every property change
    chart->BeginUpdate(); 

    //Set parent window by window handle
    chart->SetParentWindow((System::IntPtr) hwndParent); 

    //Remove existing series 
    chart->ViewXY->PointLineSeries->Clear(); 

    //Create new series 
    PointLineSeries^ series = gcnew PointLineSeries(chart->ViewXY, chart->ViewXY->XAxes[0], chart->ViewXY->YAxes[0]);
    const int PointCount = 10; 

    //Create SeriesPoint array
    array<SeriesPoint> ^ data =
        gcnew array<SeriesPoint>(PointCount);

    //Fill the array
    double yValues[PointCount] = {0.0, 5.0, 4.0, 3.0, 8.0, 10.0, 9.0, 8.0, 3.0, 2.0};
    for(int i=0; i<PointCount; i++)
    {
        data[i].X = i+1; 
        data[i].Y = yValues[i]; 
    }

    //Add the points to series
    series->AddPoints(data,false);

    //Add the series itself into chart's PointLineSeries collection
    chart->ViewXY->PointLineSeries->Add(series); 

    //Fit the axis ranges to data assigned
    chart->ViewXY->FitView();

    //Allow repaints, update chart
    chart->EndUpdate();  

} 

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
    __super::OnSize(nType, cx, cy);

    RECT rectStatusBar;
    if (m_wndStatusBar.m_hWnd)
        m_wndStatusBar.GetClientRect(&rectStatusBar);

    //Set the new size to LightningChart object, with SetBounds method call
    GlobalObjects^ go = gcnew GlobalObjects();
    if (go)
    {
        LightningChartUltimate^ chart = go->chart;
        if (chart)
            chart->SetBounds(2, 2, cx - 4, cy - rectStatusBar.bottom - 2);
    }
}

并不比这更难,所需的代码量几乎与 C# 相同。

另一种方法是使用 C#(WinForms 或 WPF)创建新的 DLL,并为 C++ 应用程序导出一个简单的 API,从而最大限度地减少非托管端的 C++/CLI 使用。

(我是 LightningChart 组件的 CTO。)

于 2013-04-02T10:54:00.787 回答
1

最简单的存档方法是使用 COM+ 托管 C#,然后从 C++ 添加这些 COM+ 作为引用。这是一个简单的过程,还增加了一些好处,例如代码封装。

http://my.execpc.com/~gopalan/dotnet/complus/complus.net_accountmanager.html

于 2013-04-02T09:21:47.963 回答