Over the years I've gathered quite some MFC experience and I'm still reluctant to say that I've mastered it. I am much more comfortable creating a GUI application in .Net or QT. I have only worked in each of those two environments for less then two years, whereas I have booked at least 5 years in MFC. How come?
The answer is in all the complexity MFC offers, without offering anything back. It doesn't provide you more power or more control over GUI, but nonetheless you need to learn gazillion different structs, flags definitions to "or" (unary |) them into structures objects, not forgetting all those you don't care about, but must not be empty nor the wrong value, handle all the HANDLEs, ... And then you run it. And then if nothing happens, what was wrong? Wrong flag? Wrong struct, combination of flags, HANDLE cast, a setting left out empty, what?
To demonstrate, following is an example of a popup menu created on left click on some dialog item, with a bitmap and a submenu:
// first, catch left click event // second, calculate the point where the click has been made // then: MENUITEMINFO* newMenuItem = (MENUITEMINFO*)malloc(sizeof(MENUITEMINFO)); ZeroMemory(newMenuItem, sizeof(MENUITEMINFO)); newMenuItem->cbSize = sizeof(MENUITEMINFO); newMenuItem->fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; newMenuItem->hSubMenu = (HMENU)submenu; newMenuItem->fMask |= MIIM_SUBMENU; newMenuItem->hbmpChecked = (HBITMAP)bitmap; newMenuItem->hbmpUnchecked = (HBITMAP)bitmap; newMenuItem->fMask |= MIIM_CHECKMARKS; newMenuItem->fType |= MFT_STRING; newMenuItem->dwTypeData = menuText->GetBuffer(); newMenuItem->cch = menuText->GetLength(); newMenuItem->wID = id; newMenuItem->fState |= MFS_ENABLED; InsertMenuItem(m_menu, m_index, TRUE, ()newMenuItem); //create other items // create popup menu object // then: selection = popupMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, point.x , point.y , this );
Compare that to this, this is WPF way to do the same:
<TextBox.ContextMenu> <ContextMenu Name="cm"> <MenuItem Header="option1" Click="MenuItemOption1_Click"> <MenuItem.Icon> <Image Source="option1.png"/> </MenuItem.Icon> </MenuItem> ... other options ... </ContextMenu> </TextBox.ContextMenu>
And not to stay in Microsoft domain, here is Qt version to do the same:
QAction* option1 = new QAction(tr("option1"), this); QAction* submenu = new QAction(tr("submenu"), this); option1->addAction(submenu); option1->setIcon(icon); menu->addAction(option1); QAction* selected = menu->exec(point);
Menus could be just unlucky case, but they're not. Implementing tab control and pages, automatic adjustment of controls when resizing the dialog, dynamic widths of table columns, a tree control with checkboxes or other additional controls as it's items, implementing input controls to allow only certain patterns of input - masks (i.e. IP, date, phone numbers), validation of user input, animations, all this requires much more work than in other environments.
Why should anybody use MFC in a new project? It offers the same limitations as .Net, with the latter being much easier to use. It's still heavily supported by Microsoft. They regularly update security issues and introduce new features and integrations into the library. This is probably a way for Microsoft to say it's safe to use it's technologies and to show us an example of their 20 years old technology, still supported and with no fear of being canceled any time soon. MFC is not there for us to use, if we don't have to support old legacy project, it is there so we can feel safe diving into WPF and expecting Microsoft to support it 20 years down the line.