Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 590
  • Last Modified:

Accessing windows key press msgs in dialog

I need to be able to processes the WM_KEYDOWN message in a dialog based app. I am aware that you cannot simply use WindowProc to pic up the message, and was wondering, what is the best/easiest way to to it?

I have heard that you can use PreTranslateMessage, but that this is frowned upon (although I have heard no reasons why). Here is an example of how you are supposed to be able to do it using that method:

BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
    if (pMsg->message==WM_KEYDOWN)
    {
        if (pMsg->wParam==VK_RETURN)
            pMsg->wParam=VK_TAB;
    }      
    return CDialog::PreTranslateMessage(pMsg);
}

How should I do it?

Thank you,

Tim
0
chadz001
Asked:
chadz001
  • 7
  • 5
  • 4
2 Solutions
 
AndyAinscowFreelance programmer / ConsultantCommented:
I am quite happy using PreTranslateMessage in code but I also believe a good app is one that works.

Are you saying the code snippet doesn't do what you want it to do?
0
 
chadz001Author Commented:
Sorry, I haven't tried this code yet, I will have to try it later, I just wanted to see if anyone had any reasons for not using this method, and any better ways, or if anyone could see if this example would not work - a general response I suppose.

But if you think this is a reasonable way to do it - thanks, I shall probably do it that way then.

If you use this to translate a certain keypress - eg the up arrow, will the dialog still be passed this windows message? (i.e. PreTranslateMessage is just a way of using a message before it is used as it normally would?) Does that make sense? :)
0
 
SteHCommented:
A reason not to overuse PreTranslateMessage is that it is called for every message that is send or posted to that window. If you put some lines of code into it which are time consuming or not efficient you will make the whole app crawl. Using a dedicated message handler where possible releases this problem to handling of messages directly related and not the complete application.

So in general it is a good idea to avoid PreTranslateMessage but in some cases it can be the best solution. The lines of code you posted don't seem to be a problem to me. But be carefull with expanding this part of the code. It is executed very often and should therefore remain highly optimized.
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
SteHCommented:
In which control do you want to use it? Overriding the dialog if it is needed only for one control would be a bad approach. In that case derive your own class from that control and override PreTranslateMessage for this class only. If you want to change message handling for the dialog (changing the user interface) this can be a the correct place. See if you can override a handler to one of the following messages:
WM_COMMAND,         all keystrokes except some system keys, and some others.
WM_SYSCOMMAND    system keys.
WM_KEYDOWN,          key is pressed.
WM_KEYUP                 key is released.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
SteH: as he is testing for a return and wanting to change to a tab it sounds like this is wanting to move to the next control when the return key is pressed.  That implies the dialog is the correct place for this handler.

chadz001:  If my assumption is correct then the following could be of use

    if(pMsg->message == WM_KEYDOWN)
      {
            if(pMsg->wParam == VK_RETURN)
            {
                  long nID = ::GetDlgCtrlID(pMsg->hwnd);
                  switch (nID)
                  {
                  case IDC_LIST_MAIN:
                        MutateDoc();
                        return true;

                  default:
                        NextDlgCtrl();
                        return true;
                  }

            }
      }
There I have a different behaviour for a control to respond to the return key.  The return true tells PreTranslateMessage that it has been handled and not to pass the message further.
0
 
SteHCommented:
I didn't took too much care about the actual code chadz001 supplied. My intention was more to make him aware what could be reasoning to use or not to use PreTranslateMessage.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
SteH.  You made a good point re performance/efficiency.  It was the line 'The lines of code you posted don't seem to be a problem to me' that made me think you had looked in more detail hence my comment to you.
0
 
chadz001Author Commented:
Sorry if that example was a bit missleading - I posted it simply as en example of using that kind of method - I don't actually wish to override the return key.

What I am basically doing is thus:

I have an MFC dialog app, in which I have a DirectX simulation window running (a vehicle on terrain if you must know). The main part of this app is the control of the simaultion over controller area network using real vehicle controls (which works fine). But for simple testing, I want to be able to control the sim via key preses - the arrow keys mainly. It doesn't need to be super responsive or anything.

The simulation runs in it's own thread anyway, so what I would do is ismply update variables with the keypresses (user presses forward - speed variable is increased - simple actions like that really).

Thank you for your answres - I think PreTranslateMessage will suffice then - if updating variables is simple enough.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
That should be OK.
0
 
SteHCommented:
Where do the keystrokes come from? It sounds that you could better use accelerators. Have a look at
http://www.voidnish.com/articles/ShowArticle.aspx?code=pretransdialog01
for how to use accelerators in dialog based app. And use the message handlers of the (menu?) commands to change the variables. This way the app is much more flexible. You can post those messages from anywhere and the reaction is the same.
0
 
SteHCommented:
Or use a overriden handler of WM_KEYDOWN  / OnKeyDown. This seems IMHO the more appropriate place than overriding PreTranslateMessage. Sideeffects of using PreTranslateMessage can be potentially harmful at a later stage of your application.
0
 
chadz001Author Commented:
I have tried overriding the OnKeyDown function, but it seems to be in the same situation as the windowProc function - unless i am doing it wrong. I will have a closer look at accelerators in a bit.

I have a question though - if I use PreTranslateMessage, will it slow down the app if it isn't doing anything - just intercepting a message, and doing nothing?

E.g. if I have a boolean value:

bool usingKeyboardInput;

And when the user selects to use keyboard input instead, i set this to true, then in my PreTranslateMessage function , have
if (usingKeyboardInput == TRUE)
{
    blah blah
}

so it doesn't handle the windows messages if the user hasn't selected keyboard input - will this slow it down?

Thanks.
0
 
SteHCommented:
A tiny bit yes. One comparison is definitely OK. Using PreTranslateMessage is only problematic if you have more code added. The reason  to look better places comes from the experience that if you add more functionality you would not redesign the existing code but just add to the places where necessary. If this is the only reliable place use it. You can be right that when other input controls have the focus you won't see the arrow key presses in the KEY_DOWN handler. And in this case PreTranslateMessage is the correct place but keep in mind to have efficient and small code only.

Using accelerators the way shown on voidnish.com works as well, though accelerators are not natively supported in dialog based applications. Which way to go now depends mainly on the complexity of the project. The more complex it is (or will get) the more suited seem the accelerator approach.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
Slow it down - the if statement itself would not slow it down so that the user would notice.  

If this is just for testing be pragmatic and stick with the PreTranslateMessage, it will work and you shouldn't see any performance hit.
0
 
SteHCommented:
I forgot the second half of the first sentence. The tiny bit won't be noticable. Sorry. Go ahead, but keep in mind not to overload this function.
0
 
chadz001Author Commented:
Thank you.
0
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.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 7
  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now