(图1:打开托管编译支持开关) 对偶.NET对象 在打开托管扩展编译开关以后,您就可以在MFC项目中使用托管对象了,通常的做法是:为每个重要的MFC对象匹配一个托管对象以形成一个对偶对,彼此匹配的对象包含指向对方的指针,这样,其他.NET对象可以通过对偶对中的.NET对象操作MFC对象;而其他MFC对象可以通过对偶对中的MFC对象操作.NET对象(如图2)。
(图2:对偶托管对象) 在Visual Studio .NET 中,没有提供关于添加托管C++类对象的向导,因此,你可以先添加一个基于托管C++的Component对象(如图3)。
(图3. Add Class向导:增加托管C++ Component对象) 添加了该testDocObject托管组件对象之后,将该对象的基类改为Object,并删除一些代码得到一个最小托管类:| 以下是引用片段: namespace test { __gc public class testDocObject : public Object { public: testDocObject(void) { } }; } |
| 以下是引用片段: public: gcroot<test::testDocObject*> m_ptestDocObj; |
| 以下是引用片段: BOOL CtestDoc::InitialDocument() { #PRagma push_macro("new") #undef new m_ptestDocObj = new test::testDocObject(); #pragma pop_macro("new") } |
(图4:MFC框架中ActiveX控件的创建) 我们知道,MFC是通过COleControlSite类创建ActiveX控件的,由于针对用于ActiveX控件的COleControlSite类不适用于.NET控件,因此必须重新派生一个新类CWFControlSite来提供必要的支持,通过一个CWFControlWrapper类将一个.NET控件包装在一个CWnd窗体中,并将包装后的窗体“安置”在CWFControlSite内。CWFControlWrapper类代码如下:| 以下是引用片段: class CWFControlWrapper : public CWnd { public: CWFControlWrapper(); virtual ~CWFControlWrapper(void); IUnknown *pUnkControl; IUnknown *GetManagedControl() { return pUnkControl; } void SetControlSite(COleControlSite *pSite) { m_pCtrlSite = pSite; } }; |
(图5:MFC框架中.NET控件的创建) NET控件的消息处理 一般而言,控件的对话框消息处理是一个极为要害的问题,在网上能找到的MFC中宿主控件的解决方法中,均没有实现.NET控件的对话框消息处理,一个明显的特征是不能处理“Tab”键消息。为此,我们重载了CUserCtrlView的PreTranslateMessage函数:| 以下是引用片段: BOOL CUserCtrlView::PreTranslateMessage(MSG *pMsg) { BOOL bRet = FALSE; if(m_Control.pUnkControl != NULL) { CComQiptr<IOleInPlaceActiveObject> spInPlace(m_Control.pUnkControl); if(spInPlace) bRet =(S_OK == spInPlace-> TranslateAccelerator(pMsg)) ? TRUE : FALSE; } if(CView::PreTranslateMessage(pMsg)) return TRUE; CFrameWnd *pFrameWnd = GetTopLevelFrame(); if(pFrameWnd != NULL && pFrameWnd->m_bHelpMode) return FALSE; // start with first parent frame pFrameWnd = GetParentFrame(); while(pFrameWnd != NULL) { if(pFrameWnd->PreTranslateMessage(pMsg)) return TRUE; pFrameWnd = pFrameWnd->GetParentFrame(); } return bRet; } |
| 以下是引用片段: #pragma once ... namespace test { public __gc class testControl : public System::Windows::Forms::UserControl { public: testControl(void) { InitializeComponent(); } protected: void Dispose(Boolean disposing) { if(disposing && components) components->Dispose(); __super::Dispose(disposing); } private: System::Windows::Forms::Label *label1; System::ComponentModel::Container *components; void InitializeComponent(void) { this->label1 = new System::Windows::Forms::Label(); this->SuspendLayout(); this->label1->Location = System::Drawing::Point(16, 24); this->label1->Name = S"label1"; this->label1->Size = System::Drawing::Size(208, 16); this->label1->TabIndex = 0; this->label1->Text = S"Welcome to TZ MFC.NET!"; this->Controls->Add(this->label1); this->Name = S"testControl"; this->Size = System::Drawing::Size(240, 160); this->ResumeLayout(false); } }; } |
新闻热点
疑难解答