problem in keyboard focus

vjayaprasen used Ask the Experts™
hi guys,
 In my application,i created a dll and inside that i call an Modeless dialog box..when i call it in the client application the dialog box poped up and i can able to do,what ever functionality i want..but the only problem is that dialog box has an several button controls and if i want to move the focus from one button to other, nothing the dialog box didnt respond the keyboard input...i can only able to click the button by using mouse only...what is the problem?can i handle keyboard messages?can any one suggest me for this..
thx in advance
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Freelance programmer / Consultant
Modeless dialogs in dll's are tricky because of the message handling not being linked into them automatically.

Extract from help system
It's been a while since Dr. GUI looked at these issues. The last time the phrase "tab order in a dialog" came up, it had something to do with talking about who owed what at a restaurant.

To understand the problem you're having, let's throw some light on how the keyboard navigation takes place in a dialog. In both modal and modeless dialogs, keyboard navigation is provided by a function called IsDialogMessage. This function provides an enormous amount of keyboard navigation within the dialogs for free. (It also makes dialog behavior consistent across Windows apps.)

When the user presses a TAB key, IsDialogMessage makes a call to the GetNextDlgTabItem API to get the next tabable item and sets focus to it. The item will not be part of the tab order if it is a static, hidden, or disabled control, or if it does not have the WS_TABSTOP style set. But you're using WS_TABSTOP, so that's not the issue for you.

Another reason the controls might not get focus is if the dynamically created controls are present in a parent window inside the dialog that does not have the WS_EX_CONTROLPARENT style set. Finally, note that the modal dialogs (DialogBox() and DialogBoxIndirect()) have the IsDialogMessage inside their message loop, but modeless dialogs (CreateDialog() and CreateDialogIndirect()) must call IsDialogMessage explicitly inside the main message loop. Except for these cases, the dynamically created controls should be part of the tab order.

To change the tab order at run time you would need to call the SetWindowPos API. Microsoft Windows maintains all the windows in the system in a list. It uses this list for purposes like painting the windows, maintaining the z order, and so on. The order in which the child controls (in a dialog) are created determines their position in the list and, hence, the tabbing order. By changing the position of the windows in this list, we can change the tabbing order. Change the window list order by calling SetWindowPos and passing the relevant windows handles in the first parameter (handle of the window to insert in order) and the second parameter (handle of the window to insert after). The window handle specified in the first parameter would come after the second in the tab order.

AndyAinscowFreelance programmer / Consultant

This is also something else to read

Regular DLLs Dynamically Linked to MFC
Home |  Overview |  How Do I |  FAQ |  Details |  Sample

A regular DLL, dynamically linked to MFC is a DLL that uses MFC internally, and the exported functions in the DLL can be called by either MFC or non-MFC executables.

A regular DLL, dynamically linked to MFC has the following features:

This is a new type of DLL introduced by Visual C++ 4.0.

The client executable can be written in any language that supports the use of DLLs (C, C++, Pascal, Visual Basic, etc.); it does not have to be an MFC application.

Unlike the statically-linked regular DLL, this type of DLL is dynamically linked to the MFC DLL (also known as the shared MFC DLL).

The MFC import library linked to this type of DLL is the same one used for extension DLLs or applications using the MFC DLL: MFCxx(D).LIB.
A regular DLL, dynamically linked to MFC has the following requirements:

These DLLs are compiled with _AFXDLL defined, just like an executable which is dynamically linked to the MFC DLL. But _USRDLL is also defined, just like a regular DLL which is statically linked to MFC.

This type of DLL must instantiate a CWinApp-derived class.

This type of DLL uses the DllMain provided by MFC. Place all DLL-specific initialization code in the InitInstance member function and termination code in ExitInstance as in a normal MFC application.
Because this kind of DLL uses the dynamic link library version of MFC, you must explicitly set the current module state to the one for the DLL. To do this, use theAFX_MANAGE_STATE macro at the beginning of every function exported from the DLL.

Regular DLLs must have a CWinApp-derived class and a single object of that application class, as does an MFC application. However, the CWinApp object of the DLL does not have a main message pump, as does the CWinApp object of an application.

The following MFC capabilities are not applicable in DLLs, either because of technical limitations or because those services are usually provided by the application.


CWinApp::SetDialogBkColor (color is ignored for message boxes)
Note that the CWinApp::Run mechanism does not apply to a DLL, since the application owns the main message pump. If your DLL brings up modeless dialogs or has a main frame window of its own, your application's main message pump must call a DLL-exported routine that calls CWinApp::PreTranslateMessage.

Place all DLL-specific initialization in the CWinApp::InitInstance member function as in a normal MFC application. The CWinApp::ExitInstance member function of your CWinApp derived class will be called from the MFC provided DllMain function before the DLL is unloaded.

You must distribute the shared DLLs MFCx0.DLL and MSVCRT.DLL (or similar files) with your application. See the topic Redistributable Files for a complete list of the MFC redistributable files.

A DLL that is dynamically linked to MFC cannot also statically link to MFC. Applications link to regular DLLs dynamically linked to MFC it just like any other DLL.

Symbols are usually exported from a regular DLL using the standard C interface. The declaration of a function exported from a regular DLL looks something like this:

extern "C" __declspec(dllexport) MyExportedFunction( );

All memory allocations within a regular DLL should stay within the DLL; the DLL should not pass to or receive from the calling executable any of the following:

pointers to MFC objects

pointers to memory allocated by MFC
If you need to do any of the above, or if you need to pass MFC-derived objects between the calling executable and the DLL, then you must build an extension DLL.

It is safe to pass pointers to memory that were allocated by the C run-time libraries between an application and a DLL only if you make a copy of the data. You must not delete or resize these pointers or use them without making a copy of the memory.

When building a regular DLL that dynamically links to MFC, you need to use the macroAFX_MANAGE_STATE to switch the MFC module state correctly. This is done by adding the following line of code to the beginning of functions exported from the DLL:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

The AFX_MANAGE_STATE macro should not be used in regular DLLs that statically link to MFC or in extension DLLs. For more information, see Managing the State Data of MFC Modules.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial