Unsolved Best approach to porting MFC GUI to Qt
-
I have a few moderately large projects that I'd like to port to use Qt instead of MFC - that sounds like a plan :)
So how should I go about this? I've quite a few questions:
-
Can I leave the project being started from WinMain() (for the MFC stuff) and only change to using main() once all the MFC code has been removed?
-
Do I then add a QApplication object inside WinMain?
-
Can I then convert each GUI component one by one?
-
What issues do I have to watch out for - I'm sure there are loads!
-
Are there any useful/essential tools to get this done? I've seen a mention of something called "Windows Migration Framework" - is this still appropriate?
I looked for a White Paper or Red Book or similar on how to approach this but failed - surely this is a pretty common requirement?
Many thanks
David -
-
Hi,
Did you already come around the QtWinMigrate module ?
-
Is that the same as the "Windows Migration Framework" - I updated my post at about the time you replied.
Are there any extended docs on using it apart from the readme, or do I get "get stuck in"?
Is this the same as I would get from : https://github.com/qtproject/qt-solutions
David
-
I went through porting a humongous app from MFC to Qt and while it's not a very pleasant process it's quite doable. Depending on the size and complexity of your app it might range anywhere from easy to not worth the effort. In my case it took about 2 years and cost me pretty much most of my hair. After 5 years there are stil bits and pieces of MFC left but that's just because nobody has energy left to clean it up :P To answer your questions:
Can I leave the project being started from WinMain() (for the MFC stuff) and only change to using main() once all the MFC code has been removed?
Yes. You need to provide the standard argc and argv params to QApplication object though. You can fabricate them using e.g. GetCommandLineA(). The tricky part is that you can't just start Qt's event loop with
exec()
as it would shut off MFC, and you can't leave the MFC event processing as is because it would swallow events targeted for Qt. For the transition period you need to devise an event dispatching solution that will sort through events and send them to the correct framework. The mentioned QtWinMigrate is a good starting point for that.Do I then add a QApplication object inside WinMain?
QApplication object must outlive any other QObejcts in your app. Apart from that there are no restrictions on where you put it.
WinMain
is as good place as any. I had it created inCWinApp::InitInstance
and destroyed inCWinApp::ExitInstance
but I don't see a reason not to place it somewhere else.Can I then convert each GUI component one by one?
That's what I did. In my case it was a large app with dozens of docking windows so I started by creating an empty top level QMainWIndow, embedding entire MFC window as the central widget and then gradually, one by one, porting MFC windows to Qt docks and dialogs. It's tedious but keeps the app in working condition throughout the process.
What issues do I have to watch out for - I'm sure there are loads!
Too many to list. Seriously, it's nerve wrecking. The problem is that you have two large frameworks constantly fighting for system events and Windows messages. The toughest ones for me were focus related - widgets loosing focus, focus switching endlessly in loops etc. The other annoying type were window ordering related - modal dialogs stuck under the main window, MFC windows flickering, Qt overpainting parts of MFC windows, that sort of things. The third is events getting directed to the wrong system and vanishing without trace. Really hard ones to debug.
Are there any useful/essential tools to get this done? I've seen a mention of something called "Windows Migration Framework" - is this still appropriate?
I started with that QtWinMigrate lib from the repo you mentioned but it's old and not maintained. At the time I needed it it didn't even support Qt5 (I think it was later updated a bit) so I had to add that myself. I had to modify it so much that soon I basically knew it by heart and decided to get rid of it entirely and use my own custom helper functions cut for my specific needs.
Are there any extended docs on using it apart from the readme, or do I get "get stuck in"?
Maybe. I don't know any. I'd suggest to just read and learn the code of that library. There's not that much of it but it touches upon a lot of stuff that you'll have to internalize anyway if you plan on having that Frankenstein's monster for some time.