Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. DoModal in CWnd::PreTranslateMessage( MSG *pMsg )

DoModal in CWnd::PreTranslateMessage( MSG *pMsg )

Scheduled Pinned Locked Moved C / C++ / MFC
c++question
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Newbie00
    wrote on last edited by
    #1

    Hello, I need to verify content of my edit control before I let it to loose focus. To do so I wrote my PreTranslateMessage like this:

    BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
    {
    BOOL bMessageHandled = FALSE;

    switch( pMsg->message )
    {
    case WM_LBUTTONDOWN:
    {
    if( ::GetFocus == MyEditWnd )
    {
    if( !IsContentOfMyEditWndOK )
    {
    ShowMessageBox( "You cannot change value");
    //ShowMessageBox has got DoModal inside, which pumps messages.
    //Unfortunately it causes my *pMsg parameter to be changed.
    }
    }
    break;
    }
    }
    if( !bMessageHandled )
    {
    bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I get assertion has failed here, because I am sending pMsg->Hwnd changed with 'ShowMessageBox'
    }

    return bMessageHandled; //I want to show messagebox and let WM_LBUTTONDOWN to be processed, because I do not want to trap focus in my Edit. So I am returning FALSE here. But it has no sence since the pMsg has changed. It is no longer WM_LBUTTONDOWN.
    }

    In order to be able to show modal dialog in PreTranslateMessage and after it forward WM_LBUTTONDOWN I would like to do something like this:

    BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
    {
    BOOL bMessageHandled = FALSE;
    MSG oRememberMsg;

    switch( pMsg->message )
    {
    case WM_LBUTTONDOWN:
    {
    if( ::GetFocus == MyEditWnd )
    {
    if( !IsContentOfMyEditWndOK )
    {
    oRememberMsg = *pMsg;
    ShowMessageBox( "You cannot change value");
    *pMsg = oRememberMsg; //now pMsg is WM_LBUTTONDOWN again
    }
    }
    break;
    }
    }
    if( !bMessageHandled )
    {
    bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I am not getting assertion has failed, because pMsg->HWnd is correct now (the same as at the beginning)
    }

    return bMessageHandled; //Now I am forwarding my catch WM_LBUTTONDOWN and my Edit loses focus
    }

    But I am not sure if my code is ok from MFC structural point of view. Can I manipulate with MSG *pMsg parameter as I described above? I tried it and it seems to work, but I don't know... Does it make some side effects? Is something I am missing here? How do you think?

    J L 2 Replies Last reply
    0
    • N Newbie00

      Hello, I need to verify content of my edit control before I let it to loose focus. To do so I wrote my PreTranslateMessage like this:

      BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
      {
      BOOL bMessageHandled = FALSE;

      switch( pMsg->message )
      {
      case WM_LBUTTONDOWN:
      {
      if( ::GetFocus == MyEditWnd )
      {
      if( !IsContentOfMyEditWndOK )
      {
      ShowMessageBox( "You cannot change value");
      //ShowMessageBox has got DoModal inside, which pumps messages.
      //Unfortunately it causes my *pMsg parameter to be changed.
      }
      }
      break;
      }
      }
      if( !bMessageHandled )
      {
      bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I get assertion has failed here, because I am sending pMsg->Hwnd changed with 'ShowMessageBox'
      }

      return bMessageHandled; //I want to show messagebox and let WM_LBUTTONDOWN to be processed, because I do not want to trap focus in my Edit. So I am returning FALSE here. But it has no sence since the pMsg has changed. It is no longer WM_LBUTTONDOWN.
      }

      In order to be able to show modal dialog in PreTranslateMessage and after it forward WM_LBUTTONDOWN I would like to do something like this:

      BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
      {
      BOOL bMessageHandled = FALSE;
      MSG oRememberMsg;

      switch( pMsg->message )
      {
      case WM_LBUTTONDOWN:
      {
      if( ::GetFocus == MyEditWnd )
      {
      if( !IsContentOfMyEditWndOK )
      {
      oRememberMsg = *pMsg;
      ShowMessageBox( "You cannot change value");
      *pMsg = oRememberMsg; //now pMsg is WM_LBUTTONDOWN again
      }
      }
      break;
      }
      }
      if( !bMessageHandled )
      {
      bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I am not getting assertion has failed, because pMsg->HWnd is correct now (the same as at the beginning)
      }

      return bMessageHandled; //Now I am forwarding my catch WM_LBUTTONDOWN and my Edit loses focus
      }

      But I am not sure if my code is ok from MFC structural point of view. Can I manipulate with MSG *pMsg parameter as I described above? I tried it and it seems to work, but I don't know... Does it make some side effects? Is something I am missing here? How do you think?

      J Offline
      J Offline
      jeron1
      wrote on last edited by
      #2

      Couldn't you handle the EN_KILLFOCUS message from the edit control in the parent dialog, check for valid values, and if is isn't OK, call the SetFocus() method for the edit control?

      N 1 Reply Last reply
      0
      • J jeron1

        Couldn't you handle the EN_KILLFOCUS message from the edit control in the parent dialog, check for valid values, and if is isn't OK, call the SetFocus() method for the edit control?

        N Offline
        N Offline
        Newbie00
        wrote on last edited by
        #3

        I cannot let to run OnKillFocus if control has no valid value, because OnKillFocus is too late. It is out of my control. Let me show you some example: I have a toolbar also. If somebody presses toolbar button OnCommand is running. Let say it is saving the document. Before saving I have to recalculate it and then save. Recalculating depends on the values in Edit. If Edit is not valid I have wrong calculations. Unfortunately pressing this toolbar buton doesn't cause KillFocus for my Edit. I have to use SetFocus to the edit's parent in order to make KillFocus for my edit to run, before I make recalculation. I don't like this solution. I have many similar problems with validating data in OnKillFocus, so I need to handle all actions before OnKillFocus and before OnLButtonDown, OnCommand, etc of given buton. I do not want to change all possible handlers in my app so I choose PreTranslateMessage. Sometime I return TRUE in PreTranslateMessage for example in order to not let the app for saving document, if user is in serious trouble with his already typed data.

        1 Reply Last reply
        0
        • N Newbie00

          Hello, I need to verify content of my edit control before I let it to loose focus. To do so I wrote my PreTranslateMessage like this:

          BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
          {
          BOOL bMessageHandled = FALSE;

          switch( pMsg->message )
          {
          case WM_LBUTTONDOWN:
          {
          if( ::GetFocus == MyEditWnd )
          {
          if( !IsContentOfMyEditWndOK )
          {
          ShowMessageBox( "You cannot change value");
          //ShowMessageBox has got DoModal inside, which pumps messages.
          //Unfortunately it causes my *pMsg parameter to be changed.
          }
          }
          break;
          }
          }
          if( !bMessageHandled )
          {
          bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I get assertion has failed here, because I am sending pMsg->Hwnd changed with 'ShowMessageBox'
          }

          return bMessageHandled; //I want to show messagebox and let WM_LBUTTONDOWN to be processed, because I do not want to trap focus in my Edit. So I am returning FALSE here. But it has no sence since the pMsg has changed. It is no longer WM_LBUTTONDOWN.
          }

          In order to be able to show modal dialog in PreTranslateMessage and after it forward WM_LBUTTONDOWN I would like to do something like this:

          BOOL CMyFrameWnd::PreTranslateMessage( MSG *pMsg )
          {
          BOOL bMessageHandled = FALSE;
          MSG oRememberMsg;

          switch( pMsg->message )
          {
          case WM_LBUTTONDOWN:
          {
          if( ::GetFocus == MyEditWnd )
          {
          if( !IsContentOfMyEditWndOK )
          {
          oRememberMsg = *pMsg;
          ShowMessageBox( "You cannot change value");
          *pMsg = oRememberMsg; //now pMsg is WM_LBUTTONDOWN again
          }
          }
          break;
          }
          }
          if( !bMessageHandled )
          {
          bMessageHandled = CFrameWnd::PreTranslateMessage( pMsg ); //I am not getting assertion has failed, because pMsg->HWnd is correct now (the same as at the beginning)
          }

          return bMessageHandled; //Now I am forwarding my catch WM_LBUTTONDOWN and my Edit loses focus
          }

          But I am not sure if my code is ok from MFC structural point of view. Can I manipulate with MSG *pMsg parameter as I described above? I tried it and it seems to work, but I don't know... Does it make some side effects? Is something I am missing here? How do you think?

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Why make life difficult for yourself? The edit control provides notifications that will let you know when the contents are changing. Take a look at EN_CHANGE[^] and EN_UPDATE[^].

          Use the best guess

          N 1 Reply Last reply
          0
          • L Lost User

            Why make life difficult for yourself? The edit control provides notifications that will let you know when the contents are changing. Take a look at EN_CHANGE[^] and EN_UPDATE[^].

            Use the best guess

            N Offline
            N Offline
            Newbie00
            wrote on last edited by
            #5

            Unfortunately I cannot use OnChange. It is to early to disturb user. I have to wait untill user finishes typing. EN_CHANGE is sent after each pressed key and I cannot save data from control to internal buffer during typing. I want to do it, if user decides to leave edit control. I have also investigated this MSG *pMsg deeper and it occured that: If I let pumping messages (f.e with modal messagebox), I always have to return TRUE in PreTranslateMessage. Saving first message and forwarding it at the end has no sence, because the whole messaging process is disturbed any way. Here is example of situation, for which my solution with saving *pMSG won't help: WM_LBUTTONDOWN -> WM_LBUTTONUP pair is very sensitive here. If I put messagebox between WM_LBUTTONDOWN and WM_LBUTTONUP in PreTranslateMessage it causes WM_LBUTTONUP to run for mouse point from the [OK] button on the messagebox and not for the original coordinates. So code from CFirstClickedArea::OnLButtonUp() will not be run. So I think, I have to return always TRUE and I have no choice, if I want to use PreTranslateMessage with DoModal.

            L 1 Reply Last reply
            0
            • N Newbie00

              Unfortunately I cannot use OnChange. It is to early to disturb user. I have to wait untill user finishes typing. EN_CHANGE is sent after each pressed key and I cannot save data from control to internal buffer during typing. I want to do it, if user decides to leave edit control. I have also investigated this MSG *pMsg deeper and it occured that: If I let pumping messages (f.e with modal messagebox), I always have to return TRUE in PreTranslateMessage. Saving first message and forwarding it at the end has no sence, because the whole messaging process is disturbed any way. Here is example of situation, for which my solution with saving *pMSG won't help: WM_LBUTTONDOWN -> WM_LBUTTONUP pair is very sensitive here. If I put messagebox between WM_LBUTTONDOWN and WM_LBUTTONUP in PreTranslateMessage it causes WM_LBUTTONUP to run for mouse point from the [OK] button on the messagebox and not for the original coordinates. So code from CFirstClickedArea::OnLButtonUp() will not be run. So I think, I have to return always TRUE and I have no choice, if I want to use PreTranslateMessage with DoModal.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              I think you are just making your program far more complicated than necessary. Using either EN_CHANGE or EN_UPDATE means that you can trap illegal content at any point. This will not have any effect on the user's typing unless they enter an incorrect character.

              Use the best guess

              N 1 Reply Last reply
              0
              • L Lost User

                I think you are just making your program far more complicated than necessary. Using either EN_CHANGE or EN_UPDATE means that you can trap illegal content at any point. This will not have any effect on the user's typing unless they enter an incorrect character.

                Use the best guess

                N Offline
                N Offline
                Newbie00
                wrote on last edited by
                #7

                This program is already complicated :D Now I am trying to avoid crashes xD I could use EN_CHANGE, if I could prevent just typing. But what about pasting with ctrl + v illegal text? Should I delete it in EN_CHANGE automatically? Other case is, that I have to also read data from editable controls, put it to internal buffer and set "Modified" flag for saving database record later. If data is illegal, I cannot put it to the buffer and set this flag. For simple edits it os ok. But there are also RichEditCtrl controls with OLE and a lot of text. I do not want to copy all text with OLE to the buffer each time EN_CHANGE comes.

                L 1 Reply Last reply
                0
                • N Newbie00

                  This program is already complicated :D Now I am trying to avoid crashes xD I could use EN_CHANGE, if I could prevent just typing. But what about pasting with ctrl + v illegal text? Should I delete it in EN_CHANGE automatically? Other case is, that I have to also read data from editable controls, put it to internal buffer and set "Modified" flag for saving database record later. If data is illegal, I cannot put it to the buffer and set this flag. For simple edits it os ok. But there are also RichEditCtrl controls with OLE and a lot of text. I do not want to copy all text with OLE to the buffer each time EN_CHANGE comes.

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  Newbie00 wrote:

                  Should I delete it in EN_CHANGE automatically?

                  Since I don't know what your program is trying to do and how many of these controls you are using I cannot answer that question.

                  Use the best guess

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups