Environment: VC5, NT4 SP5
Don't you hate assigning accelerator keys to dialog box controls? If there's only a few controls, it's no big deal, but when there's more than about 10, it gets tedious. After about 15, it gets very, very tedious. I recently had to figure out the accelerators for a property page with 23 controls, and after a half-hour of unsuccessfully trying, I created a class to automate the task. (I did it as a C++/MFC class, instead of as a separate application, because that was easiest.)
Here's how you use it:
1). Put the file DuplicateMnemonicKiller.cpp in your project's directory. (There's no need to actually add it to your MSVC project, though.)
2). Add this line to the CPP source code file of the dialog box class or property page class that you want to work on. This needs to go after the #ifdef _DEBUG stuff that ClassWizard inserts at the top of the file.
3). Add this line to either (a) OnInitDialog(), or (b) OnInitialUpdate(), depending on whether you're working on a dialog box, property page, CFormView, etc., after any call to the base class method. The "sReserved" parameter is for letters you don't want to be assigned a accelerator key; top-level menu items, for example. Setting "bUsePunctuation" allows the class to use characters like periods and parenthesis as accelerators.
The "nUseAnyUnique" parameter causes the class to take a "shortcut"; the values start at zero, and the larger the value, the faster the class can find a solution. What's the catch? Well, the larger the value of "nUseAnyUnique", the more likely it is that the accelertor keys will be at the end of the controls' text, and most people don't like that. Generally, you should start with the parameter at zero, and increment it by one if the class can't find a solution quickly.
DuplicateMnemonicKiller dmk(this, /*sReserved*/ "FEVH", /*bUsePunctuation*/ false, /*nUseAnyUnique*/ 0);
4). Make sure that all the controls you want accelerators for in your dialog box (or whatever) already have an "&" in them. This is how DuplicateMnemonicKiller knows which controls to try to assign accelerators for, and which not to.
5). Build and run your program.
That's it! Progress reports are written to your application's title bar every few iterations. The final results are both TRACE'd and AfxMessageBox()'d. It is important to recognize that above about 17 controls, it can take a long, long time for DuplicateMnemonicKiller to find a solution. For most normal dialogs, however, it's quick enough; if it gets too slow on a particular dialog box, try building in Release Mode. Personally, if it takes more that a minute or two to find a solution, I increase "nUseAnyUnique" by one and try it again.
I created this class using MSVC 5, but it should work in MSVC 6. Please let me know of any bugs or enhancement ideas.