簡體   English   中英

將大型MFC應用程序遷移到WPF / .NET有哪些技巧?

[英]What are some techniques for migrating a large MFC application to WPF/.NET?

我目前正在研究一個非常大的傳統MFC MDI應用程序。 它有大量的UI元素 - 可停靠的工具欄,自定義樹控件,上下文菜單等。它是一個圖像處理應用程序,因此主視圖使用DirectX和OpenGL自我渲染。 該產品大約有10年的歷史,其中一個優先事項是更新它的外觀和感覺。

知道微軟在提供C ++ / MFC和.NET之間的互操作性方面做得很好,我認為以遞增方式遷移代碼庫是有意義的。 我現在正在努力的是從哪里開始。

一種方法是使用WPF刪除MFC框架並盡可能多地重用C ++代碼。 這將讓我們最大限度地發揮WPF架構的優勢,但這將意味着一個漫長的開發周期,直到我們再次完全正常運行。

另一種方法是用它們的WPF對應物一次替換一個MFC控件。 這將允許我們以增量方式工作。 我對這種方法的關注是,這意味着托管和非托管代碼之間會有很多連接點,我不知道從哪里開始替換主菜單和工具欄等。

或者我還有其他選擇嗎?

任何有關此主題的信息的建議或鏈接將不勝感激。

更新: DavidK提出了一些很好的問題,所以我添加了這背后的動機。

1)產品的未來發展

該產品仍在積極開發中,並定期添加新功能。 我認為嘗試慢慢遷移到C#/ WPF會很有意義。 憑借我在C#/ WPF方面的有限經驗,我發現在C ++ / MFC中工作效率會提高。

我們用WPF獲得的另一件大事就是能夠利用多頭系統。 MFC應用程序僅限於單個頂級框架,因此很難利用多個監視器。

2)員工保留和招聘

找到願意使用MFC的開發人員越來越難了。 對於當前開發人員的職業發展而言,接觸新技術也很重要。

重新審視這個,因為我已成功用WPF替換了我們的頂級MFC UI(主框架,窗口和工具欄)。

事實證明,我們的核心繪圖代碼只需要交給HWND進行渲染。 這使得重用大量現有C ++代碼庫變得非常容易。

以下是我采用的方法的關鍵部分的快速概述:

  • 使用.NET HwndHost類來托管要呈現的C ++繪圖代碼的HWND
  • 為需要暴露給WPF / C#UI代碼的任何本機C ++代碼創建C ++ / CLI包裝器
  • 將大多數MFC對話框保留為本機C ++代碼中的原樣。 這最大限度地減少了完成UI所需的工作量。 MFC對話框可以隨着時間的推移遷移到WPF。

作為旁注,我們正在使用Divelements的SandDock和SandRibbon, 到目前為止他們對它們非常滿意。

我不認為有一種更簡單的方法,你沒有涉及,雖然它可能很大程度上取決於底層邏輯與UI層的分離程度。

不希望看起來很消極:你確定這值得努力嗎? 如果我從頭開始編寫一個大型應用程序,我現在不會從C ++和MFC開始,但是看看你在哪里,你會從重寫它中獲得什么? 這會增加一個用戶將支付的新功能嗎? 是否有任何用戶會被切斷誰將無法運行新版本? 我不禁懷疑你會從一些相對簡單的事情中獲得更大的投資回報,以改善應用程序的外觀。 例如,它是否有XP風格的清單,以便常見的控件獲得XP外觀? 幾天花在更新位上(例如使用新的樣式文件對話框)可以讓你獲得閃亮的新外觀嗎? 請記住,即使是最新,最閃亮的Office 2007也是由Microsoft使用普通的Win32控件實現的。

我之前必須在使用WinForms的項目中做同樣的事情。 我們需要將我們的MFC項目遷移到.NET 1.1,我們決定采用MFC應用程序的所有核心功能,並圍繞所有這些功能編寫托管包裝器。 然后我們寫了一個WinForms前端並逐位插入遺留的c ++代碼。 我認為從長遠來看,我們做出了正確的選擇。 我無法想象如果我們試圖同時保留MFC前端,我們將如何做到這一點。

FWIW,在此期間,您可以使用MFC功能包(VS2008 SP1提供)為您的應用程序提供Office 2007外觀和感覺非常快(如果您的用戶願意,您甚至可以添加功能區,盡管這可能是更多參與。)我在一天內使用這些新課程改進了一個舊MFC應用程序的UI,現在,公平地說,它看起來很棒,我的用戶非常高興(你可以支持一大堆外觀和配色方案) 。)MS選擇了BCG工具包,但是如果你想支付少量的錢,還有其他的可用(例如CodeJock)。

我知道這不能回答你的問題,但如果它只是用戶界面的變化,那么你可能值得一看。

我認為你已經掌握了很好的策略。 請注意,遷移到WPF的一個潛在痛點是並非每個控件都有句柄。 遺憾的是,這是最笨拙的互操作性方案。 AFAIK,與MFC和WPF互操作的唯一方法是通過WindowsFormsHost WPF范例也與MFC / WinForms截然不同,因此可能存在一些翻譯問題。

鑒於您的大型但功能強大的遺留代碼庫,我可能會支持您的第二種方法。 一次從一個控件開始並使其成為WPF-y。 在新的托管控件和底層代碼庫之間創建一個定義良好的接口,然后針對該接口進行操作。 如果你一次只做一次,你將會處理一個較低的風險輪廓:WPF的學習曲線(這是非常陡峭的,imho)。

我覺得重要的是要注意,如果你要使用WinForms,我可能會建議使用前一種方法。 更接近的范式和相對平滑的學習曲線將更容易通過一次性工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM