Archive for the ‘MFC’ Category

Some issues when working with ComboBox

August 11, 2009 2 comments

The main reason for posting this issue is to help MFC/Win32 beginners. But anyway it’s a good read ;), so once upon a time…

If you’re a beginner with window’s ComboBox controls then you might end up with a bald head thinking and thinking about a weird behavior of combo’s after it’s creation. The combo as such is a great control but there are certain important things to keep in mind while creating a combo.

So what are the problems? Well make it singular, “Problem”. One and the only problem with this control is shown in this screenshot…

Drop down not visible

Drop down not visible

I’ve clicked the drop down arrow but cannot see the dropdown. This one is created via resource editor. The problem here is, just adding a combo is not enough but we’ve also got to set the size of the drop down via resource editor. So follow these steps, as shown in the screen shot to fix this issue…

Resizing a combo drop down

Resizing a combo drop down

So that’s it. The white drag rectangle denotes combo drop down size. Press Ctrl + T to test this. Please note that this is not a bug but a feature of resource editor since there isn’t an another way to set drop down size for a combo via resource editor. But I agree that they should’ve set a better default drop down size instead of a zero height drop down.

Now this was via resource editor. It’s bit different when creating dynamically via code using CComboBox::Create function. Note that you have to give a valid height value. This height value will be the dropdown size for this combo.

See this e.g.

                CRect( 10, 10, 200, 300 ),
                IDC_COMBO1 + 1 );
m_Combo.SetFont( GetFont(), TRUE );

Hope you’ve noticed the last big value given to Combo via CRect, 300. That’s the drop down height. Normally beginners set it to 30 or 40 which results in this issue.

See the resultant screenshot…

Result of properly creating a combo

Result of properly creating a combo

Not a big deal for experts but for beginners, well I’ve been a beginner too, it’s one painful issue. 🙂

Add horizontal scrollbar to a combo box

May 28, 2009 4 comments

CComboBox has a function called SetHorizontalExtent which doesn’t work. SDK equivalent is CB_SETHORIZONTALEXTENT which also doesn’t work. The reason for this bug is pretty lame, because WS_HSCROLL style for combo box is not set, which in turn the VS dialog editor does not provide :(. So a workaround is to open .rc file in a text editor and add WS_HSCROLL style manually for this combo.

This is how a combo box will look with a horizontal scrollbar…

Horizontal scrollbar in a combo box

Horizontal scrollbar in a combo box

Here is a sample code from MSDN which is adapted a bit for this purpose…

void CDialoTestDlg::AddHScroll( CComboBox& Cmb )
  // Find the longest string in the combo box.
  CString str;
  CSize sz;
  int dx = 0;

  TEXTMETRIC tm = { 0 };
  CDC* pDC = Cmb.GetDC();
  CFont* pFont = Cmb.GetFont();

  // Select the listbox font, save the old font
  CFont* pOldFont = pDC->SelectObject(pFont);

  // Get the text metrics for avg char width

  for (int i = 0; i < Cmb.GetCount(); i++)
    Cmb.GetLBText(i, str);
    sz = pDC->GetTextExtent(str);

    // Add the avg width to prevent clipping += tm.tmAveCharWidth;

    if ( > dx)
      dx =;

  // Select the old font back into the DC

  // Set the horizontal extent so every character of all strings can
  // be scrolled to.
}// End AddHScroll

Setting horizontal extent is useful to prevent the combo’s drop down width from extending beyond screen limits. Note that there is another function called SetDroppedWidth which sets the drop down’s width but with no scrolling.

Where can I find MFC feature pack samples?

May 5, 2009 3 comments

People are having trouble finding feature pack samples installed in the samples directory. I too had a similar problem. So what you need to do is to uninstall the previous sample exe that you’ve installed. Then install the samples from here. Good thing about this is that you’ll have an updated samples package.

If you’re still having problems, I’ve uploaded them for you to my blog, please rename this file to zip after downloading or save as zip.

MFC Feature Pack – CMFCEditBrowseCtrl

April 15, 2009 3 comments


It’s a specialized edit control (MFC Feature Pack VS2008) with a browse button attached to it’s right side, when we click on this button we get an open file dialog or an open folder dialog. See this sample screenshot.

Browse edit control sample

Browse edit control sample

Also this control allows us to implement our own event handling by overriding OnBrowse function of this class. This a cool control which I like a bit too much since I know how painful it is to get one going.

Some tips on how to make such a control…

  1. Handle nc calcsize event, so that you can specify size of the area that the browse button will take which in turn results in edit control resizing it’s client area to adjust the button.
  2. Handle nc paint to draw the button, also you have to force generate an nc calcsize message for once in the beginning.
  3. Handle mouse up and mouse down event.


  1. You should be working in VS2008 SP1 or with Feature pack installation
  2. Add an edit control to a dialog
  3. Open .h file of this dialog’s class and add a member variable – CMFCEditBrowseCtrl m_EditBrowse;
  4. Open .cpp file and add a call to sub class this item in DoDataExchange
    DDX_Control( pDX, IDC_EDIT_FILEBROWSE, m_EditBrowse);
  5. Then in OnInitDialog
    // Note: Only one of these calls will work at a time!
    m_EditBrowse.EnableFileBrowseButton(); // To show file open dialog
    m_EditBrowse.EnableFolderBrowseButton(); // To show folder browse dialog
    m_EditBrowse.EnableBrowseButton(); // To do custom event handling
  6. That’s it, now you’ve got the browse edit working. 🙂
  7. Note that above calls take some parameters (which has default values) look up in MSDN.

Custom event handling for browse button

Here is a small sample on how to handle custom browse button event handling, taken from MSDN samples…

class CMyBrowseEdit : public CMFCEditBrowseCtrl
    virtual void OnBrowse()
        MessageBox(_T("Browse item..."));
        SetWindowText(_T("New value!"));


Use SetBrowseButtonImage to change browse button image, also has an option to maintain such a bitmap or an icon. There are some more virtual functions which could be useful…

  1. OnDrawBrowseButton – Override to for some additional painting from your side
  2. OnChangeLayout – Called when browse button mode changes, i.e. from folder to file mode etc (I guess so). 🙂

Set resource handle in MFC and ATL

March 23, 2009 5 comments

When working in MFC/ATL and then using a resource dll can at times cause bugs because resource handle is not properly set. For e.g. if you have a dialog resource in a dll and you instantiate a CDialog which results in an error because resource cannot be located in this application or dll since it’s in the resource dll. So solution for above problem will be to set correct resource handle.

MFC provides two functions…

  1. AfxGetResourceHandle
  2. AfxSetResourceHandle

pretty obvious names. 🙂

So we should first save our current resource handle and then set new resource handle before loading such a resource. Also don’t forget to set our old handle since its good practice.

Sample code snippet.

extern HINSTANCE hResDll = NULL;
HINSTANCE hDefInstance = AfxGetResourceHandle();
CBitmap Bmp;
Bmp.LoadBitmap( IDB_NIBUS_FACE );


Internally MFC calls FindResource and LoadResource using this handle, so if it’s not properly set this will cause failure in loading resources.

In ATL it’s quite similar except that we’ve got a new function called AddResourceInstance which adds our new resource handle to existing list of handles. So when a look up is done given resource handle is also used. Following functions are provided in ATL to work with resource handles…

  1. AddResourceInstance
  2. GetResourceInstance – Similar to AfxGetResourceHandle
  3. SetResourceInstance – Similar to AfxGetSetResourceHandle

For newbies this is always a painful bug to resolve as they don’t know what went wrong since they expect this to be automagically done.

AfxGetMainWnd in worker threads

March 11, 2009 2 comments

Recently I faced an issue in one of my project code bases. There is a worker thread (created using CreateThread native API) which calls AfxGetMainWnd() MFC function and since worker threads doesn’t have a main window associated with it, CWnd::Create( …WS_CHILD… ) call fails. A window created with WS_CHILD needs a parent window but AfxGetMainWnd() returned NULL hence the crash.

So I searched using Google and found suggestions ranging from sending window handle as the custom parameter to the thread and then passing this on to the function were the Create function call is made! But that call is about 20 functions deep :roll:. The calls go from one class to another, this means I’ve got to carry this darn handle that far, naah I decided, I’m not going to do that. So I set about exploring other possibilities.

Then a pretty cool thought 💡 struck me, AfxGetMainWnd() calls AfxGetThread(), which returns NULL which in turn results in a NULL window handle. So I thought a possible solution will be to create a CWinThread object using AfxBeginThread(WorkerThread). Then another novel thought came that I can set the main window’s handle to m_pMainWnd member variable of this CWinThread object…

CWinThread* pThread = AfxBeginThread( (AFX_THREADPROC)ThreadProc,
                                      NULL );
pThread->m_pMainWnd = AfxGetMainWnd(); // Possibly already set by above call

So this does the trick for me and my project. Now calls to AfxGetMainWnd in this worker thread succeeds, haven’t seen any issue with this so far. If you find any, please post as a comment.

How to handle child window messages in a parent window?

Is there any way to handle child window messages in a parent window? Yes you can use WM_PARENTNOTFIY message or OnParentNotify MFC handler. Note that this message is sent or this function is only called when WS_EX_NOPARENTNOTIFY style is not set. A child controls notifies it’s parent window on…

  • Creation
  • Destruction
  • Mouse button clicks

Please go through following MSDN links for more information…

  2. OnParentNotify
  3. A thread in MSDN forums on this topic

How to retrieve special folder paths, for e.g. my documents?

February 27, 2009 Leave a comment

SHGetFolderPath is the API that we use to retrieve special folder paths.  Some examples of special folders are as follows…

  • My Documents
  • My Pictures
  • Windows directory
  • System directory
  • Program files
  • Internet history directory
  • Cookies directory
  • etc…

So here is a small useful function which retrieves path of any special directory documented for SHGetFolderPath API in MSDN.

CString GetSpecialFolderPath( const DWORD csidl )
   HANDLE ProcToken = NULL;
   VERIFY( OpenProcessToken( GetCurrentProcess(), TOKEN_READ, &ProcToken ));

   TCHAR szBuffer[MAX_PATH*2] = { 0 };
   SHGetFolderPath( NULL, csidl, ProcToken, SHGFP_TYPE_CURRENT, szBuffer );
   CString SpecialFolderPath = szBuffer;

   CloseHandle( ProcToken );

   return SpecialFolderPath;

// Usage
int main()
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } // Get my documents folder path const CString MyDocuments = GetSpecialFolderPath( CSIDL_PERSONAL ); ::MessageBox( NULL, MyDocuments, "MyDocuments Path", MB_OK | MB_ICONINFORMATION ); // Get Program files path const CString ProgramFiles = GetSpecialFolderPath( CSIDL_PROGRAM_FILES ); ::MessageBox( NULL, ProgramFiles, "Program files", MB_OK | MB_ICONINFORMATION ); // Get internet history path const CString HistoryFolder = GetSpecialFolderPath( CSIDL_HISTORY ); ::MessageBox( NULL, HistoryFolder, "History folder", MB_OK | MB_ICONINFORMATION ); return 0; }[/sourcecode] There may be times when a special folder might not be present, so for that case you can combine CSIDL_FLAG_CREATE with other CSIDL flags. For example if you want to create my documents folder if there is no such one present then we'll call "GetSpecialFolderPath" likewise... [sourcecode language='cpp']// You can be sure that my documents will be present this way CString MyDocuments = GetSpecialFolderPath( CSIDL_PERSONAL | CSIDL_FLAG_CREATE ); // Now create a file in this directory MyDocuments += "/Learning.txt"; // CreateFile [/sourcecode] Above function is extremely easy to use but internally it opens and closes a token handle, so if you want to retrieve multiple entries then you can provide a token handle which may increase performance. Return values from ShGetFolderPath is interpreted as follows... S_FALSE -> SHGetFolderPathA only. The CSIDL in nFolder is valid, but the folder does not exist. Note that the failure code is different for the ANSI and Unicode versions of this function. E_FAIL -> SHGetFolderPathW only. The CSIDL in nFolder is valid, but the folder does not exist. Note that the failure code is different for the ANSI and Unicode versions of this function. E_INVALIDARG -> The CSIDL in nFolder is not valid.

Functions for converting strings to upper/lower case

February 17, 2009 3 comments

Use following functions

  1. _strupr
  2. _strlwr
  3. std::transform – does the trick too but hard to understand
/* STRLWR.C: This program uses _strlwr and _strupr to create
 * uppercase and lowercase copies of a mixed-case string.

#include <string .h>
#include <stdio .h>

void main( void )
   char str[100] = "The String to End All Strings!";
   printf( "Mixed: %s\n", str );
   printf( "Lower: %s\n", _strlwr( str ));
   printf( "Upper: %s\n", _strupr( str ));

// Output
// Mixed: The String to End All Strings!
// Lower: the string to end all strings!

How about converting std::string to upper or lower case?

// Convert std::string to upper or lower case
std::string teststr = “Nibu Babu Thomas”;
_strlwr( &teststr[0] );
cout << endl << teststr.c_str() << endl; _strupr( &teststr[0] ); cout << teststr.c_str() << endl;[/sourcecode] How about converting 'CString' to upper or lower case? Fortunately and wisely enough there are member functions called 'MakeLower', 'MakeUpper'. Phew! [sourcecode language='cpp']CString csTest = _T( "Nibu Babu Thomas" ); csTest.MakeUpper();// Now in upper case csTest.MakeLower(); // Now in lower case[/sourcecode]

Dialog does not show up after adding rich edit control!

January 23, 2009 Leave a comment

Many of you must have faced this obscure problem, it’s because you haven’t called AfxInitRichEdit/AfxInitRichEdit2() function.

Wait! Before you jump onto add this call identify your rich edit control’s class name, if you are working in VC6 then rich edit class name will be RICHEDIT and or if VC7 and above then it will be RichEdit20A. So if the class name is RICHEDIT then call AfxInitRichEdit(), else if the class name is RichEdit20A then call AfxInitRichEdit2().

%d bloggers like this: