Character messages to windows

What am I doing wrong? I've got a windows app, but I can't get char messages through to it. I've tried using an accelerator table, but that doesn't work either. I'm using TranslateAccelerator and TranslateMessage, and both appear to be succeeding, but the WM_CHAR messages just don't get through.

This a standard Win32 application, using C, with a number of
dialog boxes as the front end. The app starts off (in WinMain):

accel.fVirt = FCONTROL;
accel.key = (int)'s';
accel.cmd = IDM_SWAP;
hAccel = CreateAcceleratorTable(&accel,
                                1);
if (NULL != hAccel)
{
    if (NULL != CreateDialogParam(StoreDLLInstanceHandle(NULL),
                                  MAKEINTRESOURCE(IDDB_DIAGNOSTIC_CONFIGURATION),
                                  NULL,
                                  DiagnosticConfigurationDlgProc,
                                  (LPARAM)szComputer))
    {                                      
        while (GetMessage(&msg,
                          NULL,
                          0,
                          0))
        {
            if (!TranslateAccelerator(msg.hwnd,
                                      hAccel,
                                      &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }              
    else
    {
        t(TRACE_ERROR,
          "CreateDialogParam failed due to a GetLastError of %d.\n",
          GetLastError());
    }
}    

I have in the dialog proc of every window:

switch (wMessage)
{
    case WM_CHAR:
    case WM_DEADCHAR:
    case WM_SYSCHAR:
    case WM_SYSDEADCHAR:
        t(TRACE_ENTRY,
          "WM_CHAR received by DataCollectionSetupDlgProc, '%c' selected.\n",
          (TCHAR)wparam);            
        break;
           
None of them ever get invoked - the CHAR messages just aren't getting through.

If this isn't enough info, please let me know, I need this pretty desparately.
tofffAsked:
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.

jhanceCommented:
More information would really be helpful here.  What kind of app is it, dialog, SDI, MDI?  How about posting some code?
0
tofffAuthor Commented:
Edited text of question
0
nietodCommented:
the character messages will go to the window that has the focus.  If that is an edit box or other "built-in" control you do not have a window procedure for, you will not "see" the message.  

You could put a test for the messages in you message loop.  The messages will go through there before beig dispatched to the window with the focus.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

jhanceCommented:
To be more specific, your main program won't get any WM_CHAR messages from an EDIT control by default.  These controls are setup to handle all key presses by themselves.  In order to get WM_CHAR messages to go to the main message loop for your window, you must subclass the EDIT control (in Win32 API) using the SetWindowLong() function.  Using the HWND to the EDIT control and GWL_WNDPROC, you can replace the WndProc with a new one which will handle WM_CHAR.
0
nietodCommented:
I don't think that is quite correct.  I beleive that the WM_CHAR messages will go to the main message loop, that is, I believe, they are posted, not sent.  So you should see them in the message loop.  But from there they go to the edit control window or other control window, not to the dialog window.

If I am wrong however, and they are sent, not posted.  Then the edit control must be sub-classed as jhance said.  However, his reasoning is wrong (or more likely, he was a little careless in what he said)  If the messages are sent, then sub-classing the edit control would allow you to intercept the message in the new edit control's window procedure.  (not in the message loop as jhance suggested.)  If the message is sent, you cannot intercept the message in the message loop regardless of sub-clssing.
0
jhanceCommented:
nietod, you are correct that perhaps my language are not 100% precise.  But, to get WM_CHAR messages from an EDIT control (and it's kin) you need to subclass it (at least that is one way to do it).  Since the EDIT control is a window of it's own and has it's own message loop, you don't normally see the WM_CHAR messages.  They are handled internally by the control in Windows so as avoid burdening the programmer with unnecessary messages fro the control.  When you want to get at them, however, you can subclass it and substitute your own WndProc that can intercept the WM_CHAR messages and take the appropriate action.
0
jhanceCommented:
I can give you an example of this in MFC (that is subclassing a CEdit) but I'm a bit rusty in my Win32 API.  You might want to look at the SUBCLASS sample if you have MSDN.  It shows how to do this in the Win32 API.
0
nietodCommented:
Your absolutly right.  I forgot that when a modal dialog is open windows uses a private message loop so you application holds up until the dialog closes.  (I don't use the built-in dialogs and my dialog's don't hold up execution.)  

However, this is a dialog related issue, not an edit control related issue.  If the edit control is in a regular window, the edit control's messages would go through the program's message loop.  That's the kind of case I was thinking of.  

0
tofffAuthor Commented:
I have tried this with the focus both on an edit field, on no control, and with the the focus on pushbuttons, etc. I even created a dialog box with no controls at all and put it into the program. It didn't get the messages, either.
0
jhanceCommented:
Again, the problem is that you are using a DIALOG BOX which does not process WM_CHAR messages by default.  Usually, you have nothing in a dialog itself to send WM_CHARs to.  Any controls in the dialog are able to handle their own WM_CHARs.  If you want to receive WM_CHAR messages in a DIALOG, nietod is right (and I was unclear) you need to subclass it with the SetWindowLong and provide your own WndProc.  Again, I refer you to the SUBCLASS example in MSDN which ives you a live example of doing this.
0

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
jhanceCommented:
OK, you forced me to break out my Programming Windows book (by Charles Petzold).  If you don't have one, go and get one.  No real Windows programmer would be without it!!!  Anyway, there is a nice example in Chapter 10 on making a windows that on one hand acts like a dialog box in that it is created from a resource, but also acts like a normal window in that it's WndProc is supplied by you and not the default dialog WndProc that Windows provides for dialogs.  (By the way, the SetWindowLong method will also do the same thing but this might be clearer).  

The basic idea is to add WS_OVERLAPPED to the STYLE directive in your RC file for the dialog.  Then  you need to call CreateWindow() and also set the WS_OVERLAPPED flag.  I'd suggest looking at the example as my copy is so old that it didn't come with a CD and it a lot to type in here.
0
nietodCommented:
The dialog between jnahce and I may be a little confussing for you, especialy since we both made some mistakes.  let me try to make this clear.

The WM_CHAR message goes to two places.  First it goes to a message loop and then it goes to the window procedure of the window with the focus.  Thus there are two potential places to intercept it.

Now if you have a dialog up, windows uses its own message loop so you can't intercept it in you message loop.  (If a regular window is up, your are fine.)  Thus option one is in this case.

That means that in this case you have to intercept it at the window procedure.  Okay?  Problem.  You don't write the window procedures for the edit control/push button/dialog window/listbox etc.  If items like this have the focus they will get the message, but the window procedure or procedures you've written are not for these windows, so you can't intercept the message.

Workaround.

As jhance suggested.  You must have a window procedure for the window that is receiving the character message, that is, the edit control/push button, list box, etc.  The way to do this is to sub-class the window.  This allows you to provide a short window procedure for these types of windows and then use the window procedure that windows would ordinarily have used.  You can then intercept the WM_CHAR message in the short window procedure.

However, I wonder if this is a good idea.  I suspect that if you tell us what you are trying to do there might be a better way.  Often there is no reason to get character messages for these type of windows (or any type of window really).


0
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.