Combo Box and Edit Control fields

We have developed a libray that bridges our old DOS screen handler and Win95 API.  Our library creates Win95 windows that represent the old DOS versions of the screens.  Because of the way the DOS screen handler is constructed, it is necessary for our library to read the DOS screen layout, create the win95 parent window, and create the appropriate edit controls on the parent window.  In some cases we also use combo controls instead of edit controls.  Things are working except for two nagging problems that we can't seem to pin down:

1) When tabbing between edit fields we always trigger a beep (or the Windows default sound).  We have been unable to determine what the trigger actually is.  It seems to occur outside of our code.  Our programmer has traced through the edit control handler function (ours) and determined that the beep occurs sometime after that handler function finishes and  returns control back to Windows.  Any idea what could cause this?

2) We seem to be unable to trap many of the messages we need to trap in the combo box control.  Our message handler does get some messages for the combo box controls, but never receives the messages we really want to handle (like key down).  THe creation of the combo box seems to be done correctly, yet we are cut off from receiving messages.  Any ideas?

- Rob
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Have you tried setting a windows hook for the keyboard handler.  You can handle just the key strokes that you want to, and let the default processes handle the others.
The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. An application installs a hook procedure to monitor the system for certain types of events. A hook procedure can monitor events associated either with a specific thread or with all threads in the system. This function supersedes the SetWindowsHook function.
HHOOK SetWindowsHookEx(

    int  idHook,      // type of hook to install
    HOOKPROC  lpfn,      // address of hook procedure
    HINSTANCE  hMod,      // handle of application instance
    DWORD  dwThreadId       // identity of thread to install hook for
Specifies the type of hook procedure to be installed. This parameter can be one of the following values:
Value      Description

WH_CALLWNDPROC      Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more information,  the CallWndProc hook procedure.
WH_CALLWNDPROCRET      Windows 95 only: Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more information, see  the CallWndRetProc hook procedure.
WH_CBT      Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the CBTProc hook procedure.
WH_DEBUG      Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
WH_GETMESSAGE      Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
WH_JOURNALPLAYBACK      Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the JournalPlaybackProc hook procedure.
WH_JOURNALRECORD      Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the JournalRecordProc hook procedure.
WH_KEYBOARD      Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
WH_MOUSE      Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
WH_MSGFILTER      Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. For more information, see  the MessageProc hook procedure.
WH_SHELL      Installs a hook procedure that receives notifications useful to shell applications. For more information, see  the ShellProc hook procedure.
WH_SYSMSGFILTER      Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see  the SysMsgProc hook procedure.
Points to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
Identifies the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads.
Return Value
If the function succeeds, the return value is the handle of the hook procedure.
If the function fails, the return value is NULL.
An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process.
Chaining to the next hook procedure (that is, calling the CallNextHookEx function) is optional. An application or library can call the next hook procedure either before or after any processing in its own hook procedure.
Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.
The scope of a hook depends on the hook type. Some hooks can be set only with system scope; others can also be set for only a specific thread, as shown in the following list:
Hook      Scope

WH_CALLWNDPROC      Thread or system
WH_CBT      Thread or system
WH_DEBUG      Thread or system
WH_GETMESSAGE      Thread or system
WH_JOURNALRECORD      System only
WH_KEYBOARD      Thread or system
WH_MOUSE      Thread or system
WH_MSGFILTER      Thread or system
WH_SHELL      Thread or system
WH_SYSMSGFILTER      System only
For a specified hook type, thread hooks are called first, then system hooks.
The system hooks are a shared resource, and installing one affects all applications. All system hook functions must be in libraries. System hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove the hook procedure.
See Also
CallNextHookEx, CallWndProc, CBTProc, DebugProc, GetMsgProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, MouseProc, MessageProc, ShellProc, SysMsgProc, UnhookWindowsHookEx


Here's an example

 *                                                                                            *
 *           Source File:      filter.c                                                              *
 *           Description:  WinMoops Main Module                                                        *
 *               Date:      3/17/98                                                               *
 *                                                                                                  *

#include "windows.h"
#include "winmoops.h"
#include <string.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>

DWORD CALLBACK FilterFunc( int nCode, WORD wParam, DWORD lParam )

      LPMSG      lpmsg;
      lpmsg = ( LPMSG )lParam;
      if( lpmsg->message == WM_KEYDOWN )
            if( lpmsg->wParam == VK_F1 )
                  PostMessage( ghWnd, WM_COMMAND, IDM_ABOUT_WINMOOPS, 0L );
                  return( TRUE );
            if( lpmsg->wParam == VK_F3 )
                  if( DLL_Talk.ghDlg != NULL )
                        PostMessage( DLL_Talk.ghDlg, WM_COMMAND, IDD_FIND_NEXT, 0L );
                  return( TRUE );
            if( lpmsg->wParam == VK_RETURN )
                  if( DLL_Talk.ghDlg != NULL )
                        PostMessage( DLL_Talk.ghDlg, WM_COMMAND, IDD_CREATE, 0L );
                  return( TRUE );
            if( ( lpmsg->message == WM_KEYUP && lpmsg->wParam == VK_F1 )
             || ( lpmsg->message == WM_KEYUP && lpmsg->wParam == VK_F3 )
             || ( lpmsg->message == WM_KEYUP && lpmsg->wParam == VK_RETURN && DLL_Talk.ghDlg != NULL ) )
                  return( TRUE );
      return( CallNextHookEx( gWinHook, nCode, wParam, lParam ) );


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

I may be telling you something you already know, but...

It appears as though your program which basically does "screen scraping" was written just for you application. However, wrap what your translation layer does and you have "HLLAPI for DOS". You might want to think about marketing such a beast if you've already done the work and it was done in a generic enough manner.

Just an idea,

robworleyAuthor Commented:
Thanks for your help.  I think we've hit upon a simpler solution from another resource.

We found out that by putting a !IsDialog condition around my translate/dispatch loop like so:

  if (!IsDialog(...))

causes the dialog handler to pick up some of the functionality, like handling TABS.  This eliminated the beeping problem (1) and actually smoothed out the tabbing between edit controls.  Our only concern with this now is that we may be missing some of the edit messages we need.

We also found out that handling messages for the Combo control really isn't what we want to do.  We really want to handle messages for the edit child window of the combo control.  We are now using ChildWindowFromPoint(...) to get the handle of the edit child of the combo box and handling messages to it, not to the combo itself.  This gives us the control we are looking for.

Tom - Good suggestion.  Right now the routines are not generic enough, but it may be worth looking at going that extra step.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.