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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. pretranslatemessageoverride

pretranslatemessageoverride

Scheduled Pinned Locked Moved C / C++ / MFC
question
17 Posts 4 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.
  • B Bob Stanneveld

    Nope! Child controls are also windows. So when you click a CButton control, the control will handle the message rather then passing it on to the parent window.

    A student knows little about a lot. A professor knows a lot about little. I know everything about nothing.

    P Offline
    P Offline
    prateekkathuria
    wrote on last edited by
    #3

    thanks for the answer. But this is what i understand about the message handling mechanism of MFC. When a control say a button is clicked it invokes its own wndproc which does what ever is required( say showing it in depressed state). Thiis because every control is actually a window.And then it sends anotification to the parent WM_COMMAND( in this case with msg as BN_CLICKED). Right? If this was the case then i Should be able to handle BN_CLICKED in parent. Please correct me if i am wrong.

    J B 2 Replies Last reply
    0
    • P prateekkathuria

      Hi, i have an application that creates controls on the fly on a dialog. Say a button and a combo box. I wan to handle the events in the pretranslate message of the parent(dialog in my case)so what i do is override the mydialog::PreTranslateMessage(MSG *pMsg) as below: if(pMsg->message==WM_KEYDOWN) { if(pMsg->wParam==VK_RETURN) { pMsg->wParam=VK_TAB; AfxMessageBox(_T("return was pressed")); } else { AfxMessageBox(_T("some key was pressed")); } } else if(pMsg->message==WM_COMMAND) { if(HIWORD(pMsg->wParam) == BN_CLICKED) { CString Tmp = _T("Button Clicked was :"); Tmp.Format(_T("%s%d"),Tmp , LOWORD(wParam) ) ; AfxMessageBox(Tmp); } else if (HIWORD(pMsg->wParam) == CBN_SELCHANGE) { CString Tmp = _T("Button Clicked was :"); Tmp.Format(_T("%s%d"),Tmp , LOWORD(wParam) ) ; AfxMessageBox(Tmp); } } return CDialog::PreTranslateMessage(pMsg); } Now if the child control - a button is clicked which is an object of CButton ( no subclassing done) should nt the dialog recieve a notification and therefore shouldnt the pretranslatemessage be invoked?? Thanks in advance,

      J Offline
      J Offline
      Joaquin M Lopez Munoz
      wrote on last edited by
      #4

      I's say so, a BN_CLICKED notification, to be precise. What's your observed behavior? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

      P 1 Reply Last reply
      0
      • P prateekkathuria

        thanks for the answer. But this is what i understand about the message handling mechanism of MFC. When a control say a button is clicked it invokes its own wndproc which does what ever is required( say showing it in depressed state). Thiis because every control is actually a window.And then it sends anotification to the parent WM_COMMAND( in this case with msg as BN_CLICKED). Right? If this was the case then i Should be able to handle BN_CLICKED in parent. Please correct me if i am wrong.

        J Offline
        J Offline
        Joaquin M Lopez Munoz
        wrote on last edited by
        #5

        I think I got it, BN_CLICKED is a notification, not a command, and will be received into a WM_NOTIFY message. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

        1 Reply Last reply
        0
        • P prateekkathuria

          thanks for the answer. But this is what i understand about the message handling mechanism of MFC. When a control say a button is clicked it invokes its own wndproc which does what ever is required( say showing it in depressed state). Thiis because every control is actually a window.And then it sends anotification to the parent WM_COMMAND( in this case with msg as BN_CLICKED). Right? If this was the case then i Should be able to handle BN_CLICKED in parent. Please correct me if i am wrong.

          B Offline
          B Offline
          Bob Stanneveld
          wrote on last edited by
          #6

          You can process the message in the parent window. The only thing you have to do is map a message handler to the desired action in your windows message map: BEGIN_MESSAGE_MAPE(YourWindow, DerivedFrom) ON_BN_CLICKED(IDD_YOUR_BUTTON_ID, memberfxn) END_MESSAGE_MAP() Hope this helps :)

          A student knows little about a lot. A professor knows a lot about little. I know everything about nothing.

          P 1 Reply Last reply
          0
          • J Joaquin M Lopez Munoz

            I's say so, a BN_CLICKED notification, to be precise. What's your observed behavior? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

            P Offline
            P Offline
            prateekkathuria
            wrote on last edited by
            #7

            it could be a bn_clicked, en_change, cbn_selchanged any message( command or notification ). I donot agree that BN_CLIcKED is a wm_notify type because CButton is a standard control and not a common control.

            J 1 Reply Last reply
            0
            • B Bob Stanneveld

              You can process the message in the parent window. The only thing you have to do is map a message handler to the desired action in your windows message map: BEGIN_MESSAGE_MAPE(YourWindow, DerivedFrom) ON_BN_CLICKED(IDD_YOUR_BUTTON_ID, memberfxn) END_MESSAGE_MAP() Hope this helps :)

              A student knows little about a lot. A professor knows a lot about little. I know everything about nothing.

              P Offline
              P Offline
              prateekkathuria
              wrote on last edited by
              #8

              "You can process the message in the parent window. The only thing you have to do is map a message handler to the desired action in your windows message map: BEGIN_MESSAGE_MAPE(YourWindow, DerivedFrom) ON_BN_CLICKED(IDD_YOUR_BUTTON_ID, memberfxn) END_MESSAGE_MAP() " That is correct but my requirement is slightly different. I dont want to provide a static macro like the one above. Because my application reads what controls are to be rendered from datastructure. It reads from the datastructure that it need to create a button with xyz style , a textbox with some wdth and style etc. Now i cannot use static statemenst as above. So what i wanted to do was intercept the default message handling mechanism. I wanted to override the pretranslate message for this and then from the MSG structure get what was the event fired and who fired it process it in pretranslatemessage and return.

              B 1 Reply Last reply
              0
              • P prateekkathuria

                it could be a bn_clicked, en_change, cbn_selchanged any message( command or notification ). I donot agree that BN_CLIcKED is a wm_notify type because CButton is a standard control and not a common control.

                J Offline
                J Offline
                Joaquin M Lopez Munoz
                wrote on last edited by
                #9

                Maybe you're right, but I'd try anyway, it's a few of lines of code and will make you 100% sure. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                G 1 Reply Last reply
                0
                • B Bob Stanneveld

                  Nope! Child controls are also windows. So when you click a CButton control, the control will handle the message rather then passing it on to the parent window.

                  A student knows little about a lot. A professor knows a lot about little. I know everything about nothing.

                  P Offline
                  P Offline
                  prateekkathuria
                  wrote on last edited by
                  #10

                  i tried notify but no change. I cannot handle it still.

                  1 Reply Last reply
                  0
                  • P prateekkathuria

                    "You can process the message in the parent window. The only thing you have to do is map a message handler to the desired action in your windows message map: BEGIN_MESSAGE_MAPE(YourWindow, DerivedFrom) ON_BN_CLICKED(IDD_YOUR_BUTTON_ID, memberfxn) END_MESSAGE_MAP() " That is correct but my requirement is slightly different. I dont want to provide a static macro like the one above. Because my application reads what controls are to be rendered from datastructure. It reads from the datastructure that it need to create a button with xyz style , a textbox with some wdth and style etc. Now i cannot use static statemenst as above. So what i wanted to do was intercept the default message handling mechanism. I wanted to override the pretranslate message for this and then from the MSG structure get what was the event fired and who fired it process it in pretranslatemessage and return.

                    B Offline
                    B Offline
                    Bob Stanneveld
                    wrote on last edited by
                    #11

                    Hello, One way to go is subclassing the button control. This[^] article will tell you more about subclassing. The other way to go is creating your own button control by deriving your custom button class from CButton. From there you can make the button do what you want it to do. For exemple, you can send a user defined window message to your window that'll handle the button's actions.

                    A student knows little about a lot. A professor knows a lot about little. I know everything about nothing.

                    P 1 Reply Last reply
                    0
                    • B Bob Stanneveld

                      Hello, One way to go is subclassing the button control. This[^] article will tell you more about subclassing. The other way to go is creating your own button control by deriving your custom button class from CButton. From there you can make the button do what you want it to do. For exemple, you can send a user defined window message to your window that'll handle the button's actions.

                      A student knows little about a lot. A professor knows a lot about little. I know everything about nothing.

                      P Offline
                      P Offline
                      prateekkathuria
                      wrote on last edited by
                      #12

                      I dont wanna go subclass way because i dont wanna subclass "n" classes. Since my ui may have n differnt controls.

                      1 Reply Last reply
                      0
                      • J Joaquin M Lopez Munoz

                        Maybe you're right, but I'd try anyway, it's a few of lines of code and will make you 100% sure. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                        G Offline
                        G Offline
                        GKarRacer
                        wrote on last edited by
                        #13

                        Control notifications are handled via WM_COMMAND not WM_NOTIFY. If you wish to override the original message that caused the event like a keystroke, mouse move, etc, then you subclass the control and override the appropriate window message. If you want to override the notification (which sounds like what you want), then in the parent class (dialog) you have three options: 1. Handle the notification message. Add ON_BN_CLICKED function for example. 2. Override the OnCommand message. Inside OnCommand you can do something like:

                        BOOL CYourDialog::OnCommand( WPARAM wParam, LPARAM lParam )
                        {
                        if( LOWORD(wParam) == IDC_CTRL_ID && HIWORD(wParam) == BN_CLICKED )
                        // do something here
                        return( CDialog::OnCommand(wParam, lParam) );
                        }

                        3. Override PreTranslateMessage and process there.

                        BOOL CYourDialog::PreTranslateMessage( MSG *pMsg )
                        {
                        if( pMsg->message == WM_COMMAND )
                        {
                        if( LOWORD(pMsg->wParam) == IDC_CTRL_ID && HIWORD(pMsg->wParam) == BN_CLICKED )
                        // do something here
                        }
                        return( CDialog::PreTranslateMessage(pMsg) );
                        }

                        I'm not sure what you're trying to do, but usually it's better to your command processing using either method 1 or 2. Rarely do I have a need to override PreTranslateMessage.

                        P 1 Reply Last reply
                        0
                        • G GKarRacer

                          Control notifications are handled via WM_COMMAND not WM_NOTIFY. If you wish to override the original message that caused the event like a keystroke, mouse move, etc, then you subclass the control and override the appropriate window message. If you want to override the notification (which sounds like what you want), then in the parent class (dialog) you have three options: 1. Handle the notification message. Add ON_BN_CLICKED function for example. 2. Override the OnCommand message. Inside OnCommand you can do something like:

                          BOOL CYourDialog::OnCommand( WPARAM wParam, LPARAM lParam )
                          {
                          if( LOWORD(wParam) == IDC_CTRL_ID && HIWORD(wParam) == BN_CLICKED )
                          // do something here
                          return( CDialog::OnCommand(wParam, lParam) );
                          }

                          3. Override PreTranslateMessage and process there.

                          BOOL CYourDialog::PreTranslateMessage( MSG *pMsg )
                          {
                          if( pMsg->message == WM_COMMAND )
                          {
                          if( LOWORD(pMsg->wParam) == IDC_CTRL_ID && HIWORD(pMsg->wParam) == BN_CLICKED )
                          // do something here
                          }
                          return( CDialog::PreTranslateMessage(pMsg) );
                          }

                          I'm not sure what you're trying to do, but usually it's better to your command processing using either method 1 or 2. Rarely do I have a need to override PreTranslateMessage.

                          P Offline
                          P Offline
                          prateekkathuria
                          wrote on last edited by
                          #14

                          Correct, but assume that the controls on the dialog are dynamically created such that at time of coding i dont know as to what are the controls on the dialog. So i cannot provide the macro ON_BN_CLIKCED(btnid, handler). The reason i want to over ride the pretranslatemessage is to catch what ever goes thru the message loop filter the messages i am intersted in by using and ifelse construct like you mentioned. But the main question is my handler in pretranslate never gets invoked Why??? Cmydialog::PreTranslateMessage(MSG *msg) { if( pMsg->message == WM_COMMAND ) { if(LOWORD(pMsg->wParam)==IDC_CTRL_ID && HIWORD(pMsg->wParam)==BN_CLICKED) { UINT controlID = LOWORD(pMsg->wParam); if (controlID == someidofinterest) { //do what i want it to do } } } }

                          G 1 Reply Last reply
                          0
                          • P prateekkathuria

                            Correct, but assume that the controls on the dialog are dynamically created such that at time of coding i dont know as to what are the controls on the dialog. So i cannot provide the macro ON_BN_CLIKCED(btnid, handler). The reason i want to over ride the pretranslatemessage is to catch what ever goes thru the message loop filter the messages i am intersted in by using and ifelse construct like you mentioned. But the main question is my handler in pretranslate never gets invoked Why??? Cmydialog::PreTranslateMessage(MSG *msg) { if( pMsg->message == WM_COMMAND ) { if(LOWORD(pMsg->wParam)==IDC_CTRL_ID && HIWORD(pMsg->wParam)==BN_CLICKED) { UINT controlID = LOWORD(pMsg->wParam); if (controlID == someidofinterest) { //do what i want it to do } } } }

                            G Offline
                            G Offline
                            GKarRacer
                            wrote on last edited by
                            #15

                            Overriding OnCommand is the correct place to do this. Why isn't PreTranslateMessage being called? I had to think about this for a bit and reach back into the message loop days. PreTranslateMessage is not called for every type of message sent to a window. It is primarily a pre-cursor beforing calling the API function TranslateMessage. TranslatesMessage's primary function is to convert key strokes into WM_CHAR messages or into command accelerators. MFC's message loop, in a nutshell, looks like this:

                            while( GetMessage(pMsg) )
                            {
                            if( ! AfxPreTranslateMessage(pMsg) )
                            {
                            ::TranslateMessage(pMsg);
                            ::DispatchMessage(pMsg);
                            }
                            }

                            The key thing to note here as the GetMessage does not return for every message received by the application. It only returns for WM_QUIT, posted messages (I think), and keyboard handling. WM_COMMAND messages are sent directly to the window procedure from within GetMessage. The reason for this is that there is no translation necessary. Think of it this way. The purpose of PreTranslateMessage/TranslateMessage is not to perform some action when a message is received. That's what the appropriate message handlers are for (like OnCommand). It's job is to convert message IDs from one to another as needed. For example if you press "Ctrl+N" it converts the WM_KEYUP to WM_COMMAND (ID_FILE_NEW).

                            P 1 Reply Last reply
                            0
                            • G GKarRacer

                              Overriding OnCommand is the correct place to do this. Why isn't PreTranslateMessage being called? I had to think about this for a bit and reach back into the message loop days. PreTranslateMessage is not called for every type of message sent to a window. It is primarily a pre-cursor beforing calling the API function TranslateMessage. TranslatesMessage's primary function is to convert key strokes into WM_CHAR messages or into command accelerators. MFC's message loop, in a nutshell, looks like this:

                              while( GetMessage(pMsg) )
                              {
                              if( ! AfxPreTranslateMessage(pMsg) )
                              {
                              ::TranslateMessage(pMsg);
                              ::DispatchMessage(pMsg);
                              }
                              }

                              The key thing to note here as the GetMessage does not return for every message received by the application. It only returns for WM_QUIT, posted messages (I think), and keyboard handling. WM_COMMAND messages are sent directly to the window procedure from within GetMessage. The reason for this is that there is no translation necessary. Think of it this way. The purpose of PreTranslateMessage/TranslateMessage is not to perform some action when a message is received. That's what the appropriate message handlers are for (like OnCommand). It's job is to convert message IDs from one to another as needed. For example if you press "Ctrl+N" it converts the WM_KEYUP to WM_COMMAND (ID_FILE_NEW).

                              P Offline
                              P Offline
                              prateekkathuria
                              wrote on last edited by
                              #16

                              thanks a lot. Your explanation solved it all. Is this behaviour of getMessage and pretranslate/translate message documented somewhere in msdn so that i could dig more into it.

                              G 1 Reply Last reply
                              0
                              • P prateekkathuria

                                thanks a lot. Your explanation solved it all. Is this behaviour of getMessage and pretranslate/translate message documented somewhere in msdn so that i could dig more into it.

                                G Offline
                                G Offline
                                GKarRacer
                                wrote on last edited by
                                #17

                                It probably is somewhere, but I couldn't say where. I discovered that partly through trial and error and partly gleaned from the many varying documents in MSDN. If you look at the docs for the GetMessage function there's a sentence that says: "During this call, the system delivers pending messages that were sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function". The key phrase being During this call. That's the only one I can think of off the top of my head.

                                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