Solved

Character messages to windows

Posted on 1998-02-07
12
371 Views
Last Modified: 2013-12-03
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.
0
Comment
Question by:tofff
  • 6
  • 4
  • 2
12 Comments
 
LVL 32

Expert Comment

by:jhance
ID: 1410993
More information would really be helpful here.  What kind of app is it, dialog, SDI, MDI?  How about posting some code?
0
 

Author Comment

by:tofff
ID: 1410994
Edited text of question
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410995
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
 
LVL 32

Expert Comment

by:jhance
ID: 1410996
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
 
LVL 22

Expert Comment

by:nietod
ID: 1410997
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
 
LVL 32

Expert Comment

by:jhance
ID: 1410998
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 32

Expert Comment

by:jhance
ID: 1410999
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
 
LVL 22

Expert Comment

by:nietod
ID: 1411000
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
 

Author Comment

by:tofff
ID: 1411001
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
 
LVL 32

Accepted Solution

by:
jhance earned 50 total points
ID: 1411002
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
 
LVL 32

Expert Comment

by:jhance
ID: 1411003
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
 
LVL 22

Expert Comment

by:nietod
ID: 1411004
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

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now