Archive for the ‘MFC’ Category

LoadLibrary() can’t load a DLL, and have no clue why?

How do you link or load a DLL file?
My approach is to link a stub *.lib file to a host project. This approach supports best of dynamic load and static load. In other words, each DLL files can be maintained independently, while it is very easy to figure out what functions are not found properly and what functions are in conflict, etc.

However, if you really want to write a host program which can support plug-ins such that each plug-ins can be dropped in a given folder and the host program recognize the plug-in on the fly and starts to provide functionality defined in the plug-ins, you will want more dynamic approach.

Yes. MFC/Win32 provides such approach. With LoadLibrary(), anywhere in your source codes, DLL files can be loaded. Then you can define some common interface/parent class for pluggable architecture.
Neat, isn’t it?
However, there is one problem with LoadLibrary(). It can be difficult to troubleshoot. For example, if your DLL file can’t be loaded, you will check if the search path is correct, if the DLL file is really there, and so on. However, what if all those which affect visibility of the DLL are satisfied but the LoadLibrary() still fails?

Let’s take a look at such codes here.

// JongAm
// Let's try loading "Mediabase.dll". Why the hell WBMediabase started failing in finding the dll?

// Enable the line below to see what is wrong with LoadLibrary()
//SetErrorMode( 0 );

HMODULE dynamicLibrary_Handle = LoadLibrary( _T("MediaBase.dll") );

if( dynamicLibrary_Handle )
{
	AfxMessageBox( _T("Successful in finding Mediabase.dll") );
	TRACE( "Successful\n" );
}
else
{
	int lastError = GetLastError();

	CString message;
	message.Format( _T("Failed in finding Mediabase.dll (%d)"), lastError );
	AfxMessageBox( message );

	TRACE( "Can't find the mediabase.dll\n" );
}

Nothing special, right? However, it failed on me. Why? Later I found out that MediaBase.dll also required other DLL files, and those DLL files also require other DLLs. They are all loaded using LoadLibrary() functions. So, they were not detected with Dependency Walker. Hmmmm….
So, whenever you write LoadLibrary(), it is better to provide some feedback message when it fails loading DLL files like “Failed in loading Blah Blah.dll”.

However, what if you already have a few 3rd parth DLL files which you can’t control?
In such case, there is a really handy diagnosis function. It is the SetErrorMode(). If 0 is passed as its parameter, it will display a message box which tells what is wrong, like “X.dll is missing”.
So, for example, when you load a A.dll using LoadLibrary() but the A.dll also load A-1.dll and the A-1.dll loads A-2.dll and the A-2.dll is missing, the SetErrorMode(0) will make a message box which says “A-2.dll is missing” displayed.

Here are a few screenshots.

When a DLL file required by the designated Mediabase.dll is missing

When the designated DLL file, Mediabase.dll, itself can't be found.

When all DLL file dependency are resolved

Wow.. quite helpful, isn’t it?

About BOOL, BOOLEAN and bool on Windows

Well, this was what I wondered when I used MFC/Win32 a lot when I was a sophormore. Why are there so many boolean type on Windows? And why did people at MS made such many boolean type? Well, actually they are not new. They are just alias of int and char, or BYTE.

In C, there was no native BOOL type. C++ added boolean for this. During the days of C, people tened to define an alias for boolean type using typedef and mapped it to int or char.

However, for MFC and Win32, why are there BOOL and BOOLEAN? I found explanation for them long time ago. However, now I forgot it. So, I searched it again.
Here is a good explanation from MS’s blog.

BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. bool

Well.. for C#, they made another one, bool. ( glad that it is same to C++ bool. )

Ah.. Microsoft….

MFC problems

There are a few subjects I would like to write about MFC and would like to compare Cocoa and MFC. I know that it is not fair to compare Cocoa and MFC, because MFC was designed at the time of ToolBox of System x. However, Cocoa was also designed at almost similar time at NeXT.
However, ToolBox and MFC was based on programming model of the past, while the NeXT API was designed with newer ideas at that time. Currently Cocoa is more comparable to .NET framework. As I compared ( unexpectedly ) at my previous blog “What Apple Inc. didn’t tell you”, there are similarities between Cocoa and .NET.
I also suggest .NET framework to Windows programmers who want to taste Cocoa to figure out how it will be like.

Anyway, in this post, I would like to talk about a problem with MFC among many problems.

Let’s take a look at LVCOLUMN structure, which is used for representing columns for CListCtrl.

typedef struct _LVCOLUMN { 
    UINT mask; 
    int fmt; 
    int cx; 
    LPTSTR pszText; 
    int cchTextMax; 
    int iSubItem; 
#if (_WIN32_IE >= 0x0300)
    int iImage;
    int iOrder;
#endif
#if (_WIN32_WINNT >= 0x0600)
    int cxMin;
    int cxDefault;
    int cxIdeal;
#endif
} LVCOLUMN, *LPLVCOLUMN; 

As you can see, the first member variable is “mask”. Then let’s take a look at the second one, fmt.

fmt
Alignment of the column header and the subitem text in the column. The alignment of the leftmost column is always left-justified; it cannot be changed. This member can be one of the following values:

LVCFMT_LEFT
Text is left-aligned.
LVCFMT_RIGHT
Text is right-aligned.
LVCFMT_CENTER
Text is centered.
LVCFMT_JUSTIFYMASK
A bitmask used to select those bits of fmt that control field justification. To check the format of a column, use a logical “and” to combine LCFMT_JUSTIFYMASK with fmt. You can then use a switch statement to determine whether the LVCFMT_LEFT, LVCFMT_RIGHT, or LVCFMT_CENTER bits are set.

What is LVCFMT_JUSTIFYFYMASK? It is ANDed with LVCFMT_LEFT/RIGHT/CENTER to set those alignment setting.
Hmmm… Why is there another mask bit set here? Isn’t the 1st member variable is for masks?
Like this, here and there in MFC, there are some confusing part or illogically designed parts.

Also, although this is another aspect of MFC, it doesn’t provide easy way to work with controls. For example, instead of calling CListCtrl’s method to add, delete items and columns, it utilizes messages. You need to send messages to controls to manipulate them. Some controls don’t work like this. What I want to say is that the architecture of MFC is somewhat awkward and not designed for ease of use, which is very different from Cocoa and .NET.

When I was a university student, I found out that may other CSE student had difficulty in using MFC framework. I think it is not coincidence.
Probably MS architects at MS knew about this problem and they decided to make a new framework by hiring Borland people to adopt their Form-based and property programming paradigm.

Visual C++ 2008 resource editing and control variable annoyance

Hmmm.. It was strange that VC++ 2008 add variables wizard didn’t let a “value” variable of a radio button. With VC++ 6, it was possible as far as I remember.

So, I searched to find out what changed since VC++ 6.

What I found are :

However, the most official document is :
Grouping Radio Buttons on a Dialog Box

People are confused by the different way of setting variable for a radio button to they way you do with its previous version, and MS didn’t seem to present “What is changed and How is changed” document.

So, the way it manipulate resources was changed. No, problem. However again MS’s approach shows problems.

  1. In the resource editor, there is no way to group radio boxes visually
  2. Because only one radio buttons is to be turned on exclusively in its group, there should be a visual way to make a series of radio buttons grouped. However, a group is defined by setting the order of radio buttons in series and only the first radio button is flagged as “Group”.

  3. Setting only the first radio button as “Grouped” is not reasonable.
  4. Basically there are multiple radio buttons in a group. Then all should be “grouped”. But MS want you to set only the 1st radio button as “grouped”. Then all the following radio buttons are grouped. It doesn’t feel natural.

  5. Setting the variable to the first radio button
  6. So, a variable for a group should be declared for the group. But a variable for the 1st button is declared and treated like that it is the representative button for the group.

All of them don’t look natural and reasonable.

I think this is why people get confused and couldn’t get a clue on how to make set a variable for radio buttons.

Choice of method name : MFC and Cocoa

MFC and Cocoa have very different philosophy about programming model. The MFC is a wrapper of Win32 API and data types, while the Cocoa is written from the scratch to present new programmng model.

To me, writing with Cocoa has always been eaiser because Cocoa has understandable method names and so on.
Let’s take a look at a screenshot.
windows_terminology

To set a text of an edit box, you should use SetWindowText. With NSTextField of Cocoa, you will use setStringValue. To understand why Set”WindowText”, you should understand that the CEdit is a subclass of a CWnd. So, the content of the CEdit is a kind of window text, although it sounds like a title of a window.

So, the Cocoa’s nomenclature is a lot easier to understand. Also, it is more readable, because of its capitalization. by mixing small and large letters, Cocoa helps you to see what is verb part and what is noun part. So, it is easier to recognize what the method means.

I think this is very good example how Apple and MS are different each other.
I have been seeing this kind of tradition from MS and Apple. It feels like that this is the very one which shows the two different cultures.

%d bloggers like this: