CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Dec 2003
    Location
    London (UK)
    Posts
    3

    MFC: How do I receive WM_KEYDOWN message in a complicated dialog

    My dialog box has many different controls - buttons, list-boxes, radios etc. (but no edit controls). It is designed to be part of a hand-held device simulator (it looks like a calculator).
    I have added ON_WM_KEYDOWN to my dialog's message map but all key messages are intercepted by the controls long before my dialog can deal with them.
    Other than sub-classing all of these different control classes then adding ON_WM_KEYDOWN to each of their seperate message maps, is there a better way of capturing key messages?
    In other words, how can I make it so that when the '6' key on my PC is pressed, my OnKeyDown method can deal with it, and when it is released, my OnKeyUp method is informed?
    Many thanks for your potential help.
    Andy

  2. #2
    Join Date
    Feb 2002
    Posts
    3,788

    Re: MFC: How do I receive WM_KEYDOWN message in a complicated dialog

    In other words, how can I make it so that when the '6' key on my PC is pressed, my OnKeyDown method can deal with it, and when it is released, my OnKeyUp method is informed?
    Many thanks for your potential help.
    Andy
    You sais that when your "6" key is pressed you want something to happen, right? do you or don't have this "6" on your dialog(iif you have it s it a button or something)?
    or you want that when your app is running and the user presses "6" from the keyboard something should happen?
    please, clarify this first.

  3. #3
    Join Date
    Dec 2003
    Location
    London (UK)
    Posts
    3
    I want it so that when ANY key is pressed, the dialog gets a crack at it.
    In the dialog, I have buttons which represent the keys on my simulated device (which could be a calculator or a mobile phone etc.). There are around 20 buttons together with spinners, list boxes, radios, tick boxes etc. The user can click the buttons and the program will respond accordingly (e.g. "You have pressed X"), but I also want the user to be able to press the corresponding real key on his keyboard so that my program can respond to this as well.
    In particular, I need to respond to KEYUP/KEYDOWN events so that I can determine how long the key was pressed. For example, I might have to simulate a POWER key which does one thing when the key is first pressed down, and does another thing if the key release took more than 2 seconds (ie. power down).
    For the same reason, it would also be nice to be able to determine the amount of time a button has been clicked down.
    I really want to avoid having to subclass CButton and all of the other controls (CListBoxes, CSpinners whatever) that the dialog uses. Is there any way to arrange things so that ALL keyboard activity can bypass the dialog's controls so that they can be processed centrally by the dialog itself?
    Thanks again.
    Andy

  4. #4
    Join Date
    Feb 2002
    Posts
    3,788
    i always built my own CCustomBtn, CCustomListBox classes when i needed the behavior.
    i think it's the most elegant way.
    another way(not recommended) is to use PreTranslateMessage.
    see this for a more detailed view.

  5. #5
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    I forget if my article makes it clear, but I think the best solution, if it is possible, is to simply ensure that the text entry control always has the focus. Then process the keyboard messages in that control only. In a typical calculater application, there is a text box where the text goes to when it is typed or where the text goes that corresponds with the buttons pushed. That control is probably the only one that needs to get keyboard messages (have the focus).

  6. #6
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    The best and most flexible way of doing this, in my opinion, is to not use a dialog but to have an SDI with a form view.

    Then you can set up accelerators for each of the keys you want to use. You can set the accelerator ID to being the same ID as the button you want pressed.

    There are various advantages to using this method :

    (1) It's inherently flexible. Instead of having a huge switch statement trying to trap the events in every case you let the windows API cope with it all.
    (2) Enabling/disabling is automatic through OnUpdate..(CCmdUI *pCmdUI) and UpdateDialogControls.
    (3) All the code for coping with each key is kept in one place : in the handling code.

    Darwen.

  7. #7
    Join Date
    Dec 2003
    Location
    London (UK)
    Posts
    3
    ...ensure that the text entry control always has the focus...
    This seems to be heading along the right track, but I now have a further problem: when do I use the SetFocus() method so that the CEdit control retains the focus.

    I've now got a control called CFocus (which sub-classes CEdit) and tried putting SetFocus() within the OnKillFocus() method. Now, if I click one of the buttons, focus returns immediately to my CFocus control. All is well and good except that the button click doesn't get noticed by the button control (it is ignored).

    My latest attempt involves using the OnKillFocus event to start a timer, then using OnTimer() to SetFocus() back to my control. There are problems with this method.
    (1) Some key presses will be missed (ignored by the CButton controls)
    (2) How many milli-secs to wait (given that some machines running my app will be slower than mine) to ensure that button click processing will complete.

    I should add that the simulator must be modifiable by other developers who will need to add or remove other buttons and controls. It is for this reason that I need a solution which can cope with any controls that are added (other than those which require focus).

  8. #8
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    I admit that I am not sure how to do that.

    Did you look at all the VC sample programs to see if there are any relevant to what you are doing? I think there is. Did you try using Spy++ to look at the Windows Accessory Calculator?

  9. #9
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917
    Couple of things:

    1. Do not SetFocus when edit control looses focus.
    SetFocus to edit control from button handlers.

    2. Build accelerator table for each button setting ID of accelerator same as button ID. For example for button 6 IDC_6 set ID_6 for key 6 e.t.c.

    3. In OnInitDialg LoadAccelerators.

    4. Override PreTranslateMessage adding line:
    Code:
    	if(TranslateAccelerator(m_hWnd, m_hAcc, pMsg))
    		 return TRUE;
    before calling base class.

    m_hAcc is a member variable holding handle to loaded accelerator table.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  10. #10
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    If you look at the resources in the Windows Accessory calc.exe then you will see that the accelerators table has many entries essentially as John describes. You will also see that the only controls that are tab stops are the data entry edit control, radio buttons and checkboxes. The push buttons are not tab stops. However if I click a radio button then the tab key seems to not work and not be necessary, so there seems to be something that makes the tab key unnecessary for returning focus back to the data entry box.

    Also, if you looked at the VC sample programs, then you probably found MFCCALC, which is probably all you need.

  11. #11
    Join Date
    Feb 2007
    Posts
    48

    Re: MFC: How do I receive WM_KEYDOWN message in a complicated dialog

    Hi, sorry if this seems a little weakly related but I thought i would ask anyway. I have subclassed a window, and am intercepting the messages being passed, but what I really want to do it is intercept the messages sent to the controls on that window, how do I do that, how do i subclass them, where are they? What I really want is to be able to intercept the set text messages so that I can verify the output?

    Many thanks, Ron

  12. #12
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266

    Re: MFC: How do I receive WM_KEYDOWN message in a complicated dialog

    Quote Originally Posted by flavour404
    Hi, sorry if this seems a little weakly related but I thought i would ask anyway. I have subclassed a window, and am intercepting the messages being passed, but what I really want to do it is intercept the messages sent to the controls on that window, how do I do that, how do i subclass them, where are they? What I really want is to be able to intercept the set text messages so that I can verify the output?

    Many thanks, Ron
    You should create a new question (thread) for this.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  13. #13
    Join Date
    Feb 2007
    Posts
    48

    Re: MFC: How do I receive WM_KEYDOWN message in a complicated dialog

    Quote Originally Posted by Sam Hobbs
    You should create a new question (thread) for this.
    I did, everybody ignored it which is why I posted under this, even though I know the link is tenuous!

    Ron

  14. #14
    Join Date
    Feb 2007
    Posts
    48

    Re: MFC: How do I receive WM_KEYDOWN message in a complicated dialog

    Quote Originally Posted by Sam Hobbs
    You should create a new question (thread) for this.
    I did, everybody ignored it which is why I posted under this, even though I know the link is tenuous!

    Ron

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured