分享
 
 
 

银弹制造:开发最灵活的软件(一)

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

银弹制造:开发最灵活的软件(一)

在非托管代码中使用托管资源是如何实现的

BrianLiang (原创)

mynewbigame@tom.com

我一直在寻找这样一个类库:他对Windows的窗口提供面向对象的封装,有灵活的消息响应机制和比较完备的界面框架解决方案,对标准控件提供简练实用的封装,支持操作系统的新特性,支持功能扩充和二次开发,有代码自动生成向导机制,生成的程序使用较少的系统资源,最后是有完全的代码支持和文档支持;对!用MFC;我希望他能对纷繁芜杂的世界有所感应,能让我充分利用到各种开发语言的优点而不为一种环境所困扰;没错!用.NET;我想我可以恰当的使用它们,让他们在我的项目中各尽所能,我纵横于各种开发语言和对象模型之间,而不用太过需要去顾及到他们的差异;很幸运,这样的工具也被我发现了;我使用MFC Application Project with .NET Support 1.0,我不费吹灰之力把CrystalReportView等成熟的.NET组件插入到我的MFC项目中,我用VB.NET和C#完成一些琐碎的工作(我的朋友正在开始学习ADO.NET,他很乐意帮助我完成数据管理部分),而关键部分仍然交给C++来完成。我有点好奇,我不知道作者是怎么做到的!我冒昧的与作者联系,希望能够了解地更多;然后我获得了全部的源代码,同时作者希望我能够把这项技术介绍给大家,他希望能够帮助广大的开发人员自由地整合各种资源,他相信整个技术行业应该是开放性的、具有合作意识的而且是自由自在不受约束的,他认为开发工具能够提供给我们的应该更多,有些必要因素必须是天生的比如资源整合能力、无限的可扩展性、表现层和业务逻辑层的独立以及更重要的是用户对界面和功能的自主与自由的选择等等;开发工具必须能够尽量保证这一切都是可行的、自动的、快速的、简单的。他给我展示了他所完成的开发工具是如何达到以上要求的,在今后的一两个月内他们就会与广大的开发人员见面,这一切都令我震惊。这一系列的工具为我们的开发人员提供更完美的解决方案。这些产品作为构架工具和组件容器,会带来超乎想象的组件重用率和开发者生产率的提高进而带来的软件质量的提高(构架师专注于功能定义和任务调度,生活在地球上各个角落里的组件开发人员维护自己的组件和文档甚至后续的技术支持)。整个软件产业发展的必然之路就在眼前!

构件软件最可能的彻底解决方案是:不开发任何软件!

------------弗雷德里克·布鲁克斯

一、我们需要整合,我们需要互操作!

通过允许MFC项目属性的“Use Managed Extensions(使用托管扩展)”,我们就可以在项目中增加诸如.NET Framework Windows 窗体控件或UserControl等等托管项;

从 Visual C++ .NET 开始,MFC 对消息处理函数的返回类型和参数类型进行更严格的类型检查。这些新增行为通过使用错误信息标记潜在不安全的消息处理函数,来通知开发人员可能会遇到的问题。大家会注意到在这里所有返回类型用 LRESULT 保证类型安全。

源程序中一个重要的类是WFControlSite,他继承自COleControlSite (COleControlSite 提供客户端的控制接口,更多请参考看MSDN);第一步,使用CreateManagedControl方法创建托管控件(窗体、UserControl)把它作为客户端对象激活(客户端激活的对象由基于租约的生存期管理器管理,该管理器确保在对象的租约过期时对该对象进行垃圾回收);以下代码演示了如何获得托管资源:

HRESULT hr = E_FAIL;

ASSERT(m_pObject == NULL);

CWinFormsView::CWFControlWrapper * pWndCtrlLocal = dynamic_cast<CWinFormsView::CWFControlWrapper *>(m_pWndCtrl);

IUnknown * pUnk = pWndCtrlLocal->GetManagedControl();

if (FAILED(hr = pUnk->QueryInterface(IID_IOleObject, (void**)&m_pObject))) {

return hr;

}

GetEventIID(&m_iidEvents);

//激活客户端对象部分略

上述代码中的CWFControlWrapper是另外一个重要的类CWinFormsView(从使用MFC Application Project with .NET Support 1.0 为我们的Visual Studio.NET 2003的VC++项目模板中添加的”MFC Project with .NET Support”向导生成任何一个应用程序的”UserControlView.cpp”里的映射可以看到他们的对应关系)包含的一个子类,类定义如下:

class CWFControlWrapper : public CWnd

{

public:

CWFControlWrapper();

virtual ~CWFControlWrapper(void);

IUnknown * pUnkControl ;

IUnknown * GetManagedControl() { return pUnkControl; }

void SetControlSite(COleControlSite * pSite) { m_pCtrlSite = pSite; }

};

CWinFormsView::CWFControlWrapper::CWFControlWrapper():pUnkControl(NULL){}

//析构函数略

我们必须重写 CreateControl方法以调用CreateManagedControl方法;在这段方法实现中,如果hr = CreateManagedControl(clsid, pPersist, bStorage, bstrLicKey)成功完成,创建托管资源窗口/UserControl,然后,作为OLE就地激活对象,它需要被激活;

插曲:

COLEControlSite对象是一个OLE容器文档对象,在这个容器文档中可以任意创建托管项。开发人员在容器文档中创建托管项后会频繁激活这个对象,以便对其进行编辑。

借助在CWFControlWrapper中的方法SetControlSite使得CWnd的保护成员m_pCtrlSite得以获得新的托管资源:

部分代码如下:

CWinFormsView::CWFControlWrapper * pWndCtrlLocal = dynamic_cast<CWinFormsView::CWFControlWrapper *>(pWndCtrl);

m_pWndCtrl = pWndCtrlLocal;

pWndCtrlLocal->SetControlSite(this);

接下来的问题是,如何将 Windows 窗体控件用作 MFC 视图类。 首先自然要在CWinFormView类中创建CWFControlSite对象,如果创建成功,就把它画在客户区,代码实现如下:

UserControl* pUserControl = __try_cast< UserControl* >( control );

m_Control.pUnkControl = reinterpret_cast<IUnknown*>

(System::Runtime::InteropServices::Marshal::GetIUnknownForObject(control).ToPointer());

OnInitialUserControl();

CRectclientRect;

GetClientRect( &clientRect );

使用过MFC Application Project with .NET Support 1.0的程序员都会发现在UserControlView中可以使用OnInitialUserControl来初始化非托管资源,以下代码取自官方网站提供的例子example003.zip里的TestAppView.cpp(不要被这个类名所迷惑,他其实就是UserControlView,这个例子的作者并没有用向导生成UserContrlView,而是自己增加了一个):

m_pCtrl->Button2->set_Text(S"VB.NET usercontrol-button changed by c++ code.");

m_pCtrl->Button2->add_Click(new system::EventHandler((CTest*)m_pTestObj,CTest::ClickButton2));

m_pCtrl->TabPage1->set_Text(S"VB.NET usercontrol-TabPage title changed by c++ code.");

m_pCtrl->Button1->add_Click(new System::EventHandler((CTest*)m_pTestObj,CTest::Click));

m_pCtrl->add_Click(new System::EventHandler((CTest*)m_pTestObj,CTest::Click));

//Handle events of .NET usercontrol

m_pCtrl->add_xxx(new testcls::UserControl1::xxxEventHandler((CTest*)m_pTestObj, CTest::Fire));

可以看到不管是托管的控件的属性,还是方法甚至是事件,都可以使用非托管代码控制、作出响应。如何保证这一点,本文作者由于对MFC及.NET对象模型掌握程度有限,无法给出更详细的描述,请大家见谅。

MFC Application Project with .NET Support 1.0官方网站:

http://www.apptemplate.com/

下载地址:

http://www.apptemplate.com/GB/downloads/

Brian Liang 2004-04

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有