html5-img
1 / 27

DEV331 Visual C++: Using The .NET Framework In Win32/MFC Applications

DEV331 Visual C++: Using The .NET Framework In Win32/MFC Applications. Kate Gregory Gregory Consulting Limited. Timeline. First release: Visual C++ .NET 2002 New reserved keywords: __gc etc Interop Limited designer support Current release: Visual C++ .NET 2003 Still great interop

baylee
Download Presentation

DEV331 Visual C++: Using The .NET Framework In Win32/MFC Applications

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DEV331 Visual C++: Using The .NET Framework In Win32/MFC Applications Kate Gregory Gregory Consulting Limited

  2. Timeline • First release: Visual C++ .NET 2002 • New reserved keywords: __gc etc • Interop • Limited designer support • Current release: Visual C++ .NET 2003 • Still great interop • WinForms designer • Amazing conformance to standard C++ • Goodies for unmanaged C++ devs • Next release: Visual C++ 2005 • codename Whidbey • Language changes • More to follow • Longhorn, Avalon, WinFX, Indigo...

  3. The problem • Existing code is too valuable to throw away • No-one wants to be left behind as functionality advances • So many things are different between MFC and WinForms • Popular data types • Event handling • Lifetime management • Global and static scope

  4. Why Stay In C++? • I like it • Templates • Destructors • Syntax • I want the highest-performing interop • I want to combine managed and unmanaged code • I’m a control freak • Switching languages is confusing

  5. Options • Call your old library from a new WinForm app • Usually requires refactoring • Call new .NET code from your MFC business layer • From unmanaged: interop • Or compile parts as managed • Add a WinForm to your MFC UI • Host the CLR • All about placing the boundary

  6. Refactoring • Easiest MFC apps to move to the new world have separate presentation and logic • Business layer, data layer • Pass business objects (Employee) between layers rather than CRecordset or other library-specific types • Converting your application to a more modular one is often the first step in porting

  7. Refactoring Old monolithic app New Data Layer New Business Layer New MFC UI New Web Services New WinForm UI . . .

  8. Calling The Business Layer • The business layer is an ordinary “classic” C++ class library • Unmanaged • Preferably not using MFC • Call it: #include the header file and linking to the .lib • Just the same from managed C++ or unmanaged C++ • Much easier from C++ than other managed languages

  9. Calling .NET Code From MFC Code • If your MFC code is compiled with /CLR, it can access any .NET objects trivially • This is the big C++ advantage

  10. Calling .NET Code From MFC Code • Create COM-Callable Wrapper around the .NET Objects • Strong name • Regasm • Gacutil • tlbexp • Unmanaged code calls them as though they were COM Components • #import the tlb

  11. Options • Call your old library from a new WinForm app • Usually requires refactoring • Call new .NET code from your MFC business layer • From unmanaged: interop • Or compile parts as managed • Add a WinForm to your MFC UI • Host the CLR • All about placing the boundary

  12. WinForm In An MFC View

  13. WinForm In An MFC View • MFC App is compiled with /clr • Not the only choice, but a simple option • WinForm is accessed as a managed object but also wrapped in a COleControlSite • MFC View creates instance of WinForm, gets an IUnknown from it, and gets it onto the view • Use gcroot<>, CCOMPtr<>, and other managed-unmanaged helpers • Calling methods of the managed object is easy

  14. TestMFCFormView.h • The managed object: gcroot<Controls::ControlsControl*> pWrappedControl; • Helper class from ManagedControlHelpers CWinFormsControlWnd m_usercontrol; • Ordinary click handler: afx_msg void OnBnClickedButton1();

  15. OnInitialUpdate CFormView::OnInitialUpdate(); ResizeParentToFit(); Controls::ControlsControl* pControl = new Controls::ControlsControl(); pWrappedControl = pControl; CComPtr<IUnknown> spunkControl; spunkControl.Attach((IUnknown*)System::Runtime:: InteropServices::Marshal::GetIUnknownForObject( pControl).ToPointer()); CWnd* pwnd = this->GetDlgItem(IDC_PLACEHOLDER); CRect rectPlaceHolder; pwnd->GetWindowRect(&rectPlaceHolder); this->ScreenToClient(rectPlaceHolder); pwnd->ShowWindow(SW_HIDE); m_usercontrol.Create(spunkControl, WS_VISIBLE | WS_TABSTOP, rectPlaceHolder, this, 0);

  16. Click HandlerMFC calls WinForm • Very simple, use the original managed object that was wrapped: void CTestMFCFormView::OnBnClickedButton1() { UpdateData(true); pWrappedControl->LabelText = SendText; }

  17. Click HandlerWinForm calls MFC • This is significantly harder • Define a managed interface for WinForm to call • Define an unmanaged interface with the same methods • Have the MFC View implement the unmanaged interface • Write a managed bridge class

  18. Managed Interface public __gc __interface IViewLabel { __property String* get_Text(); __property void set_Text(String*); };

  19. Equivalent Unmanaged Interface class IUnmanViewLabel { public: virtual char* get_Text()=0; virtual void set_Text(char* t)=0; };

  20. Bridge Class public __gc class ViewLabelImpl: public IViewLabel { public: ViewLabelImpl(IUnmanViewLabel* v); ~ViewLabelImpl(void); __property String* get_Text(); __property void set_Text(String*); private: IUnmanViewLabel* view; };

  21. Bridge Class String* ViewLabelImpl::get_Text() { return new String(view->get_Text()); } void ViewLabelImpl::set_Text(String* t) { //incredibly ugly marshaling code //producing s, a char* view->set_Text(s); }

  22. Working Together

  23. Options • Call your old library from a new WinForm app • Usually requires refactoring • Call new .NET code from your MFC business layer • From unmanaged: interop • Or compile parts as managed • Add a WinForm to your MFC UI • Host the CLR • All about placing the boundary

  24. Hosting The CLR • This is usually a last resort • Unless your app is IIS, Office, SQL Server • Your unmanaged code thinks it is calling COM APIs • The CLR is loaded and managed code runs • Take complete control of your app: when the load cost happens, how the AppDomains are managed, and so on • Not for the faint of heart

  25. Boundary Placement • Transition cost for switching from managed to unmanaged • Managed wrapper around unmanaged code will cross boundary many times • For chatty calls consider adding an unmanaged wrapper with a chunky interface • All the chat happens entirely in unmanaged world • Similar logic when unmanaged code is calling BCL or new managed code

  26. What's Next? • Whidbey • Longhorn • Be ready

  27. Please fill out a session evaluation on CommNet Q1: Overall satisfaction with the session Q2: Usefulness of the information Q3: Presenter’s knowledge of the subject Q4: Presenter’s presentation skills Q5: Effectiveness of the presentation

More Related