2

I want to track event of single left-click on edit control. I override PretranslateMessage function as below:

BOOL CMyClass::PreTranslateMessage(Msg* pMsg)
    {
       switch(pMsg->message)

       case WM_LBUTTONDOWN:
       {
          CWnd* pWnd = GetFocus();
          if (pWnd->GetDlgCtrlID == MY_EDIT_CTRL_ID)
             {
                //Do some thing
             }
          break;
       }
    }

The problem is that when I click on the edit control, all other control become disabled (for example buttons don't respond to clicks etc.)

How can I fix this problem? Or how can I track click notificationN on edit box?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
javad
  • 23
  • 4
  • 1
    Where's your return __super::PreTranslateMessage(pMsg); ? See e.g. here: http://binglongx.com/2011/03/20/pretranslatemessage-overrides-in-mfc-and-grab-key-presses/ – Tilman Hausherr Jan 28 '16 at 13:29
  • I return TRUE in if() body after //Do something – javad Jan 28 '16 at 13:34
  • But you don't do it in the default case. – Tilman Hausherr Jan 28 '16 at 13:35
  • if i return TRUE in default case the problem remains unsolved – javad Jan 28 '16 at 13:40
  • 1
    Sorry, what I meant is that in the default case you should call the parent, as explained on several websites. – Tilman Hausherr Jan 28 '16 at 13:41
  • I do below code exactly but still don't work BOOL CMyClass::PreTranslateMessage(Msg* pMsg) { switch(pMsg->message) case WM_LButtonDown: { CWnd* pWnd = GetFocus(); if (pWnd->GetDlgCtrlID == MY_EDIT_CTRL_ID) { //Do some thing return TRUE; } break; } Return CDialogEx::PreTranslateMessage(Msg* pMsg); } – javad Jan 28 '16 at 13:47
  • 1
    No, what I mean is this: BOOL CMyClass::PreTranslateMessage(Msg* pMsg) { switch(pMsg->message) case WM_LButtonDown: { CWnd* pWnd = GetFocus(); if (pWnd->GetDlgCtrlID == MY_EDIT_CTRL_ID) { //Do some thing } break; } default: return __super::PreTranslateMessage(pMsg); } – Tilman Hausherr Jan 28 '16 at 13:51
  • I apply your code but unfortunately other buttons became disabled – javad Jan 28 '16 at 13:55
  • 1
    You need to call PreTranslateMessage(pMsg); for all controls other than your edit control. – drescherjm Jan 28 '16 at 13:57
  • Dear drescherjm Could you please help me how call PreTranslateMessage(pMsg); for other controls? – javad Jan 28 '16 at 14:00
  • Why aren't you deriving your own class for the CEdit control and trapping the message there? – rrirower Jan 28 '16 at 14:47
  • The real question is: **Why** do you need this? Whenever this question comes up, people are trying to work around a problem, that is the result of their proposed solution. What is the ultimate goal you are trying to achieve? – IInspectable Jan 28 '16 at 18:31

1 Answers1

5

You need this:

BOOL CMyClass::PreTranslateMessage(MSG* pMsg)
{
  switch(pMsg->message)
  {
    case WM_LBUTTONDOWN:
    {
      CWnd* pWnd = GetFocus();
      if (pWnd->GetDlgCtrlID() == MY_EDIT_CTRL_ID)  // << typo corrected here
      {
         //Do some thing
      }
      break;
    }
  } 

  return __super::PreTranslateMessage(pMsg);  //<< added
}

BTW its a bit awkword to use a switch statement here. Following code is cleaner IMO, unless you want to add morecases than only WM_LBUTTONDOWN:

BOOL CMyClass::PreTranslateMessage(MSG* pMsg)
{
  if (pMsg->message == WM_LBUTTONDOWN)
  {
    CWnd* pWnd = GetFocus();

    if (pWnd->GetDlgCtrlID() == MY_EDIT_CTRL_ID)
    {
       //Do some thing
    }
  } 

  return __super::PreTranslateMessage(pMsg);  //<< added
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • @javad if it still doesn't work, you'll need to include more of your code. Try creating a minimal but complete application. – Tilman Hausherr Jan 28 '16 at 14:15
  • I believe it should work. I have done this many times in the past (long ago though since I do not write MFC code anymore). Perhaps whatever you are doing in the `//Do some thing` is the problem. – drescherjm Jan 28 '16 at 14:15
  • @javad Actually this doesn't work for following reason: once you've clicked on the MY_EDIT_CTRL_ID control, "Do something" is executed and the focus is set to this control. Now the focus is still in MY_EDIT_CTRL_ID, and the next time you click on some other control, `PreTranslateMessage` is called before the focus change takes place and therefore the focus gets "stuck" in MY_EDIT_CTRL_ID. I've modified the answer, but this is still not entirely satisfying for the reason mentioned. – Jabberwocky Jan 28 '16 at 14:28
  • @javad You probably should replace the condition `pWnd->GetDlgCtrlID() == MY_EDIT_CTRL_ID` by a condition that tests if `pMsg->pt` is inside the MY_EDIT_CTRL_ID edit control. – Jabberwocky Jan 28 '16 at 14:31
  • Dear michael I think your reason about focus is correct but when i check pMsg->pt instead of checking ID other controls do their normal behavior but i can't enter any text in edit control! what's your idea? – javad Jan 28 '16 at 14:50
  • @javad please update your question with your new code so I can have a look. – Jabberwocky Jan 28 '16 at 14:53
  • CRect ocRect; m_ocEditControl.GetWindowRect(&ocRect); if ((pMsg->pt.x >= ocRect.left) && (pMsg->pt.x <= ocRect.right) && (pMsg->pt.y >= ocRect.top) && (pMsg->pt.y <= ocRect.bottom)) { //Do something } – javad Jan 28 '16 at 14:58
  • @javad it works here. Did you remove the `return TRUE` statement ? Maybe "do something" does some evil things ? In my example I do just a `TRACE("Do something\n");`. – Jabberwocky Jan 28 '16 at 15:05
  • @javad: BTW your condition that tests if the point is in the edit's rectangle can be replaced by this which is much simpler: `if (ocRect.PtInRect(pMsg->pt))` – Jabberwocky Jan 28 '16 at 15:07
  • I wonder why there's a *hwnd* member in the [MSG structure](https://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx). If you simply compared that to the handle of the edit control you are interested in, it would actually work. Unlike your hackery with window rectangles and message positions (which produces false positives). – IInspectable Jan 28 '16 at 18:12
  • @javad : this test is even better than the rectangle test: `pMsg->hwnd == m_ocEditControl.GetSafeHwnd())` – Jabberwocky Jan 29 '16 at 08:22
  • @javad the question has been answered so click the check mark to accept the answer and bring this to a close – Barmak Shemirani Jan 29 '16 at 15:12