Archive for the KB Category

Optimizing Storage for Constant Data

Posted in KB on May 5, 2008 by naveenraj
In programs we usually declare constant string data. Like..

const char* g_pchar = “this is a string”;

You might be knowing that if we run multiple copies of a exe or dll, the code portion is not duplicated per process. So do the constant data. This is because the constant datas are stored in a special section of exe called “.rdata”( The code protion is stored in the “.text” section ). But guess what will happen if we have declaration like..

const CString g_str(“this is the worst thing I can do”);

Now you’ve got the CString object (which is quite small) in the .bss section( .bss section stores nonconstant uninitialized data ), and you’ve also got a character array in the .data section( Nonconstant initialized data ), neither of which can be backed by the EXE file. To make matters worse, when the program starts, the CString class must allocate heap memory for a copy of the characters. You would be much better off using a const character array instead of a CString object. So never ever declare like that ( Reference “Programming Microsoft vc++” by David Kruglinski ).

OK that was the theory. Now the reason why I stated the above theory is that, last week, I installed the latest VS 2008 feature pack. This feature pack had some new classes for MFC. So I decided to check out the new classes. The CWinAppEx is on among them. On the very first function I stepped in( constructor of the CWinAppEx ), I found the following piece of code..

const CString strRegEntryNameWorkspace = _T(“Workspace”);
m_strRegSection = strRegEntryNameWorkspace;

ops . And when I scrolled up, there was another bunch of similar codes

static const CString strRegEntryNameControlBars = _T(“\\ControlBars”);
static const CString strWindowPlacementRegSection = _T(“WindowPlacement”);
static const CString strRectMainKey = _T(“MainWindowRect”);
static const CString strFlagsKey = _T(“Flags”);
static const CString strShowCmdKey = _T(“ShowCmd”);
static const CString strRegEntryNameSizingBars = _T(“\\SizingBars”);
static const CString strRegEntryVersion = _T(“ControlBarVersion”);
static const CString strVersionMajorKey = _T(“Major”);
static const CString strVersionMinorKey = _T(“Minor”);

I dont think any one has seen such a badly written, poor quality code in the old MFC 4 code. Never did I. If MFC starts like this, where will the developers using MFC ends?

When I discussed about this in code project and MSDN forum, I got some interesting response. That’s how I came to here about Wirth’s law[^] , which states

Software gets slower, faster than hardware gets faster.
or
Software is decelerating faster than hardware is accelerating.

Very true and you just saw one example.

When a MessageBox in InitInstance didn’t show..

Posted in KB on April 8, 2008 by naveenraj

Once I created one utility in which had the below piece of code.

BOOL CMyApp::InitInstance()
{

AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
HANDLE hMutex = CreateMutex( 0, 0, _T(“Some_Mutex”));
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
AfxMessageBox( _T(“Only one instance of the application can be run”));
CloseHandle( hMutex );
return FALSE;
}
CMyDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
CloseHandle( hMutex );
return FALSE;
}

My purpose was to run only one instance of the application. If more than one instance is run, the second instance will show a message box and exits. Before release of the utility, I some touch ups in the application. Fortunately just before the release I noticed that, if two instance of the application is run, the second instance simply exits without showing that message box.
Then I started to roll back the touch ups one by one. After removing one of them, the message box again showed. And that touch up was the manifest file I added for giving XP look and feel. I searched and searched and finally found out that the problem is because of not calling the InitCommonControls() function. It was right there in the documentation Using Windows XP Visual Styles[^] , but I never followed it.
The actual purpose of the InitCommonControls() is described in The Old New Thing [^]. It says if we didn’t call the InitCommonControls() funtion, our application will not be having any reference to the COMCTL32.DLL and therefore will not be loaded while my application start. So when I tries to create a window, the class will not be registered and so the CreateWindow() function will fail.
How ever my doubt was, even with out the InitCommonControls() function, my application dialog was showing correctly. Only the Message box had the problem. InitCommonControls() isn’t necessary for the dialog? How ever when I stepped into the source code of the MFC, things became clear. Inside the DoModal() function, it is calling the InitCommonControls(). The AfxDeferRegisterClass MACRO was doing this job.
Now I got another doubt, Since MFC calls the InitCommonControls() function, the COMCTL32.DLL will be statically linked to MFC42.dll and my application is statically linked to the MFC42.dll. So COMCTL32.DLL should definitly load in the beginning itself. But for some reasons even though MFC42.dll was loaded, COMCTL32.DLL didn’t get loaded.
The only possibility for such a scenario will be a delay load of COMCTL32.DLL in the MFC42.dll dll. To confirm, I opened the MFC42.dll in PEView. As expected the COMCTL32.DLL was added in the “DELAY IMPORT Address Table”.

Let look back to the original problem. “Message box got displayed in normal case even if I didn’t call the InitCommonControls()” . So COMCTL32.DLL not need if didn’t use manifest?? The answer is no. In windows Some window classes are register by User32.dll( Like button, edit etc ) and some other control( Windows common controls ) are registered by COMCTL32.DLL. But if we add manifest files, user32.dll will not be registering any of the window classes instead COMCTL32.DLL will do all the registrations. If you check the manifest file of the COMCTL32.DLL version 6, you can see the list of window classes versioned in it.
( The file is located in “C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.0.0_x-ww_1382d70a.Manifest” )

So to conclude, what I learned because of message box problem are.

1. Whether or not you are using Manifest file, you should call InitCommonControls() or InitCommonControlsEx().

2. MFC42.dll have set COMCTL32.DLL to delay load. ( But when I checked in MFC8.dll, the delayed loading of COMCTL32 is removed )

3. If we use manifest file, COMCTL32.DLL will doing the registration of all System Classes instead of user32.dll. So it is necessary to ensure that COMCTL32.DLL have loaded before you create a window belonging to system class.