Why MFC is bad

Well, MFC has lots of weird aspects. Basically MFC is a framework. What is a framework? Framework is a wrapper of API to make the API easier to use.
However, when MFC is compared to ToolBox which was most popular during similar period of time, MFC is not as easy to use as ToolBox. ToolBox is, however, API not framework.

Here I would like to show one example why MFC is bad and why its design is bad. Let’s think about CListCtrl. It is a list control or table control if you think of it in the context of Mac OS X. What do you want to do with it?
Let’s summarize some of them.

  • Populate ClistCtrl
  • Retrieve row item or column data
  • Change properties like text color, background color, font and so on for row items.
  • Customizing the UI
  • and so on

First, to manipulate the data or to populate the CListCtrl, this class itself doesn’t provide consistency. Why am I talking about consistency? Let’s take a look at CStatic or CEdit. On Windows, you can set a control variable for them or data variable for them. A control variable is like :

CEdit *editBox

, while data variable is like :

CString editBoxString

To manipulate the value itself, data variable is easier. However to control the widget itself, you should use the control value.
With Cocoa, you don’t need to have this separate mechanism. In Windows point of view, it is like to declare CEdit variable and the CEdit class provides all the methods to manipulate the data value. Or with Cocoa binding, things can be done much more easily.

It does not mean that it is impossible to manipulate data with the control variable. With some widget, or control, it is not easy or is not possible at all.

Here, with CListCtrl, there is no “data” variable unlike that of CEdit or CStatic. So, you should manipulate the data with the CListCtrl itself. So, there is no consistency.

Second, it is very difficult to retrieve row item or data.
GetItem() is for that, but if you look up MSDN document for it, it is not clear how to retrieve an item you want.
Here is explanation on what it does.

Retrieves some or all of a list view item’s attributes.

The LVITEM structure specifies or receives the attributes of a list view item.

However, it doesn’t say about how to do so.

There is something which is even worse.
Let’s take a look at the LVITEM parameter.
What is lParam? What does it supposed to contain? There is no explanation about it in MSDN document.

Let’s assume that you want to customize the CListCtrl. You want to set a bold font for a specific row item or column. Does CListCtrl provide such method? No. Also, there is no each way to retrieve ith item on a CListCtrl. Among them, one easy thing is to set a text color or a background color of a item. Well.. how to to so? There is no explanation about it.
Well.. you can implement a message handler for WM_CUSTOMDRAW message. However the MFC document for CListCtrl doesn’t even contain link for the message. You should look up Win32 document. Isn’t it strange? Framework is a wrapper for API to make API easy to use. However, For MFC, if you want to do some common thing like this, the API, or Win32, should be revealed.

Third. Let’s think about a situation in which you want to set a bold font for some items. There seems to be no way to do so.
Creating a CListCtrl Class with Item Style Features (CListCtrlStyled Class) from CodeGuru introduces a customized CListCtrl clas to do that.

Let’s take a look at some source codes from the class.

void CListCtrlStyled::SetItemStyle(int nItem,int nSubItem,DWORD Style,bool redraw)
{
	// We must retrieve the Style info structure of this item
	//
	LVITEM pItem;
	InitLVITEM(nItem,0,&pItem);

	LS_item * lpLS_item = NULL;
	lpLS_item = (LS_item*) pItem.lParam;

	if(nSubItem > 0)
		lpLS_item = lpLS_item->subitems[ nSubItem - 1];

	// no we can update the style
	//
	lpLS_item->StyleFlag = Style;

	DWORD mask = LIS_BOLD | LIS_ITALIC | LIS_UNDERLINE| LIS_STROKE ;
	lpLS_item->in_use = (Style & mask) > 0;

	// if any font exist for this item then delete it
	//
	this->Free_LS_font(lpLS_item);

	// Redraw it
	if(redraw)	CListCtrl::Update(nItem);
}

void CListCtrlStyled::InitLVITEM(int nItem,int nSubItem,LVITEM * pItem)
{ /*
  typedef struct _LV_ITEM {
    UINT   mask;         // see below
    int    iItem;        // see below
    int    iSubItem;     // see below
    UINT   state;        // see below
    UINT   stateMask;    // see below
    LPSTR  pszText;      // see below
    int    cchTextMax;   // see below
    int    iImage;       // see below
    LPARAM lParam;       // 32-bit value to associate with item
   } LV_ITEM;
  */
	pItem->mask = LVIF_PARAM;
	pItem->iItem = nItem;
	pItem->iSubItem = nSubItem;
	pItem->state = NULL;
	pItem->stateMask = NULL;
	pItem->pszText = NULL;
	pItem->cchTextMax = NULL;
	pItem->iImage = NULL;
	pItem->lParam = NULL;
	CListCtrl::GetItem(pItem);
}

In InitLVITEM() method, it calls GetItem(). What it does is to retrieve lParam value in LVITEM. Then in SetItemStyle(), it calls :

	LS_item * lpLS_item = NULL;
	lpLS_item = (LS_item*) pItem.lParam;

	if(nSubItem > 0)
		lpLS_item = lpLS_item->subitems[ nSubItem - 1];

Hmm.. lpLS_item is once set to lParam. And it is set to lParam’s subitems[].
Then based on the value, it tries modify the variable to set a font face.
To do this, you should know that what the lParam means and the data structure lParam contains. Also, you need to know howdata structure its subitems[] looks like.

But where is explanation on them is? I can’t find anything on MSDN.

There are a lot of things in MFC like this.
Classes are not prepared to handle things easily, and its MFC documentation doesn’t have any link or explanation.

I don’t understand why MS doesn’t provide good documentation about its classes. The bad design of MFC can be understood if we consider when it was designed. However, if MFC designer at MS still want to keep the MFC for native environment, they should do something about it.

2 responses to this post.

  1. Posted by Alex Gagarin on October 2, 2009 at 3:31 PM

    If you can’t find answer how do to somthing in MFC on MSDN visit http://www.codeguru.com/

    Reply

    • Posted by jongampark on October 2, 2009 at 8:50 PM

      Hi, Gagarin.

      You forgot CodeProject!
      By the way what I wanted to say in this post was not whether I knew or didn’t know how to do something with MFC.

      Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: