24小时热门版块排行榜    

查看: 2172  |  回复: 8
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

yalefield

金虫 (文坛精英)

老汉一枚

[交流] 【转帖】MFC与Qt混合编程---“官方文档”的缩写 已有3人参与

作者:程序开发之家
http://www.cngeng.info/qt%B1%E0%B3%CC/2044.html

现在,Windows下的大多数程序都是使用mfc开发的,由于众多产品想移植到非windows的操作系统上继续使用,qt由于自身“一次编写,到处编译 ”的特性恰恰满足了这种需求。所以,怎么从mfc程序迁移到qt上来是很多公司需要考虑的问题。至于从qt迁移到mfc这种需求应该是不会出现的 ,mfc1.0 1992年就发布,qt94年才开始动工呢。怎么说都是mfc历史悠久,地大物博...

选择了qt作为mfc的替代品,那就得考虑是新建一个qt工程重新写一遍还是能在原来的mfc工程里直接使用qt 组件逐步替换掉mfc的部分。本文讨论的是后一种需求。所幸的是,细心的qt官方也考虑到了这一点。官方提供了 Qt/MFC Migration Framework 来实现在mfc工程里混用qt的组件。可以从这个页面找到相关的下载:http://doc.trolltech.com/solutions/qtwinmigrate/winmigrate-walkthrough.html
这个framework比较简单就包括几个类QWinWidget,QMfcApp等。 关于具体怎么做,该页面上也能找到很多实例。翻译成中文大致有这么几点:

首先,要想使用一个QtGui部件,比如QPushButton, QWidget之类的,必须有一个QApplication 对象存在。在创建一个QPushButton时,代码会检测是否有这么一个QApplication对象存在,否则程序会crash掉。所以需要创建一个 QApplication对象:
CODE:
BOOL WindowsApp::InitInstance()
{  // Standard initialization

#if _MFC_VER < 0x0700
#ifdef _AFXDLL
Enable3dControls();                     // Call this when using MFC in a shared DLL
#else  Enable3dControlsStatic();       // Call this when linking to MFC statically
#endif  #endif

         // Change the registry key under which our settings are stored.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));

         // Qt initialization
MfcApp::instance(this); //这一句就是创建QApplication对象

         MainFrame* pFrame = new MainFrame;
return true;
}

创建了QMfcApp对象,那些QWidget们就有指望了,因为它们的事件需要QApplication 来管理分配。所以,接着就要用QMfcApp对象来接管CWinApp的程序运行机制
重载CWinApp的Run函数,调用QMfcApp::run(this);
这里用到了上面创建的QMfcApp对象来同时接管QWidget的 event和MFC的message loop. 代码如下:
CODE:
BOOL WindowsApp::Run()
{  int result = QMfcApp::run(this);
delete qApp;
return result;
}

现在QApplication对象已经有了,new 一个 QPushButton上去,程序也不会报错了。但是,如何让这个QPushButton 能显示在 MFC的窗口类里面呢?
因为构造QPushButton的时候,父类只能接受一个QWidget,而不能不接受一个父类窗口的windows handle。  
QWinWidget登场了!
来看一下QWinWidget的构造函数:
QWinWidget ( HWND hParentWnd, QObject * parent = 0, Qt::WFlags f = 0 );
啥也不用说了,代码如下:
CODE:
int ChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{  if (CWnd::OnCreate( lpCreateStruct ) == -1 )
return -1;

     widget = new QWinWidget( this );
QHBoxLayout *hbox = new QHBoxLayout( widget );

     QLabel *label = new QLabel( "Enter text:", widget );
QLineEdit *edit = new QLineEdit( widget );
hbox->addWidget( label );
hbox->addWidget( edit );

     widget->move( 0, 0 );
widget->show();

     return 0;
}  

懒得翻译了,直接贴一段吧
Now we can create the QWinWidget instance with this CWnd instance as a parent window, and use that instance as a parent to the QWidgets we want to use to create the user interface. Since QWinWidget is a proper QWidget it can be laid out, and we move the Qt GUI to the upper left corner of the MFC child and show() the user interface immediately.
最后别忘了,这个widget还是要干掉的。widget一干掉,下面那些子子孙孙widget全部干掉,qt就这么霸道!
CODE:
void ChildView::OnDestroy()
{  delete widget;
widget = 0;

     CWnd::OnDestroy();
}

就简单讲到这里。我们已经知道如何让mfc代码和qt代码放在一起编译通过了,剩下的工作就是把mfc部分一点点替换掉了。
任重而道远!

[ Last edited by yalefield on 2011-1-31 at 00:02 ]
回复此楼

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

yalefield

金虫 (文坛精英)

老汉一枚

引用回帖:
Originally posted by dedream at 2011-01-31 14:33:54:
多谢前辈指点,我只想让自己别那么累,任何一个使用windows操作系统的人,运行我负责的产品,都没有什么障碍,您的帖子,让我开始有点信心了。

如果是这样的,俺作为考古爱好者建议:
选用Visual C++ 6.0(即MFC 4.2)作为主力程序的开发环境,最为稳妥、可靠。
您查查俺的帖子,VC++ 6.0是微软的开发工具中,推出后作为主力开发环境最长的(应该是6年时间,1997-2003)。
虽然开发出来的程序,界面比较骨灰,但足够工业级应用。实在需要花哨,完全可以在界面上采用其他“皮肤”。
7楼2011-01-31 15:53:05
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 9 个回答

yalefield

金虫 (文坛精英)

老汉一枚

引用回帖:
Originally posted by dedream at 2011-01-31 09:35:53:
前辈看好qt?

当Java出现以后,程序员大约分为C++和Java两大派。
别跟俺提Perl, PHP,那只是凉菜,下酒的。
当.Net出现以后,C++分裂了,有的加入了C#和Visual Basic,有的则保持本色。
可是,随着Visual Studio 2010以及.Net Framework 4.0的出现,尤其是.Net Framework 4.0与3.5版不兼容,使得C#阵营开始动摇了。

Qt则晚生于MFC,但开源、面向对象、界面出色,还有跨平台,使得它后来居上。

随着移动设备的市场增长,MFC在WinCE方面,显得有些笨拙了,连MDI界面都不支持咯。

那么,选择Qt,还有什么犹豫的呢?
3楼2011-01-31 10:10:11
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

dedream

木虫 (正式写手)


小木虫(金币+0.5):给个红包,谢谢回帖交流
我不编程,但工作关系,要和编程的人员打交到,曾经很看好java的跨平台,但实践证明,不入流的软件公司可以把java践踏得一败涂地,于是开始倾向于支持.net。。。
但是如果.Net Framework 4.0与3.5版不兼容,是否意味着在win家族中xp、vista、win7下开发的程序,没法保证有良好的通用性?
从数据到结论
4楼2011-01-31 12:49:52
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

yalefield

金虫 (文坛精英)

老汉一枚

引用回帖:
Originally posted by dedream at 2011-01-31 12:49:52:
我不编程,但工作关系,要和编程的人员打交到,曾经很看好java的跨平台,但实践证明,不入流的软件公司可以把java践踏得一败涂地,于是开始倾向于支持.net。。。
但是如果.Net Framework 4.0与3.5版不兼容,是否 ...

先说.Net Framework。
用VC++ 2008,只能选择.Net Framework 3.5和它之前的版本。
而用VC++ 2010,则只能用.Net Framework 4.0。
更为可怕的,是.Net Framework 4.0与.Net Framework 3.5完全不兼容。也就是说,无法把.Net Framework 3.5的程序代码“自动升级”到.Net Framework 4.0上。

换个角度。
如果您确定了用.Net Framework 3.5,那么您的程序可以运行在Win XP, Vista, 7系统,这个没有问题。
如果您确定了用.Net Framework 4.0,那么您的程序也可以运行在Win XP, Vista, 7系统下。
只是,你用.Net Framework 3.5开发的程序,“永远”都要背着.Net Framework 3.5,如影随形,尾大不掉,直到永远OR微软倒闭OR改写代码。

但是,C#和Java这类语言,都属于“托管”性质,也就是说,程序代码其实并不是运行在操作系统上,而是运行在一个托管环境中,如Java,运行在JVM提供的环境下,C#则运行在.Net Framework提供的环境下。

JVM的宣传,是跨平台,可是多年来的实践证明,“一次编写、到处运行”的梦想,与“一次编写、到处出错、随时调试”的现实,差距的确有。
.Net Framework的梦想,其实也是跨平台,不过,它只是个幌子,实际起作用的,是MSIL这个中间语言。
关于这方面的比较与介绍,请参考任哲等编写的《Windows程序设计基础----MFC与.NET》,机械工业出版社。这本书有些“另类”,前半部分,是对MFC的分析和评价,后半部分,则是关于C#和.Net的。如果没有多年的实践经验,读起来比较困难(俺读起来很舒服,这是必须的)。不过,第10章,是对跨平台的一些介绍和讨论,值得浏览浏览。

[ Last edited by yalefield on 2011-1-31 at 14:13 ]
5楼2011-01-31 14:02:09
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见